about summary refs log tree commit diff
path: root/nixpkgs/pkgs/development/compilers/swift/swiftpm
diff options
context:
space:
mode:
Diffstat (limited to 'nixpkgs/pkgs/development/compilers/swift/swiftpm')
-rw-r--r--nixpkgs/pkgs/development/compilers/swift/swiftpm/cmake-glue.nix87
-rw-r--r--nixpkgs/pkgs/development/compilers/swift/swiftpm/default.nix453
-rw-r--r--nixpkgs/pkgs/development/compilers/swift/swiftpm/generated/default.nix14
-rw-r--r--nixpkgs/pkgs/development/compilers/swift/swiftpm/generated/workspace-state.json144
-rw-r--r--nixpkgs/pkgs/development/compilers/swift/swiftpm/patches/cmake-disable-rpath.patch36
-rw-r--r--nixpkgs/pkgs/development/compilers/swift/swiftpm/patches/cmake-fix-quoting.patch12
-rw-r--r--nixpkgs/pkgs/development/compilers/swift/swiftpm/patches/disable-index-store.patch23
-rw-r--r--nixpkgs/pkgs/development/compilers/swift/swiftpm/patches/disable-sandbox.patch21
-rw-r--r--nixpkgs/pkgs/development/compilers/swift/swiftpm/patches/disable-xctest.patch37
-rw-r--r--nixpkgs/pkgs/development/compilers/swift/swiftpm/patches/fix-clang-cxx.patch121
-rw-r--r--nixpkgs/pkgs/development/compilers/swift/swiftpm/patches/fix-stdlib-path.patch25
-rw-r--r--nixpkgs/pkgs/development/compilers/swift/swiftpm/patches/force-unwrap-file-handles.patch33
-rw-r--r--nixpkgs/pkgs/development/compilers/swift/swiftpm/patches/llbuild-cmake-disable-rpath.patch14
-rw-r--r--nixpkgs/pkgs/development/compilers/swift/swiftpm/patches/nix-pkgconfig-vars.patch28
-rw-r--r--nixpkgs/pkgs/development/compilers/swift/swiftpm/setup-hook.sh60
15 files changed, 1108 insertions, 0 deletions
diff --git a/nixpkgs/pkgs/development/compilers/swift/swiftpm/cmake-glue.nix b/nixpkgs/pkgs/development/compilers/swift/swiftpm/cmake-glue.nix
new file mode 100644
index 000000000000..252040dd3ec0
--- /dev/null
+++ b/nixpkgs/pkgs/development/compilers/swift/swiftpm/cmake-glue.nix
@@ -0,0 +1,87 @@
+# SwiftPM dependencies are normally not installed using CMake, and only provide
+# CMake modules to link them together in a build tree. We have separate
+# derivations, so need a real install step. Here we provide our own minimal
+# CMake modules to install along with the build products.
+{ lib, stdenv, swift }:
+let
+
+  inherit (stdenv.hostPlatform) extensions;
+
+  # This file exports shell snippets for use in postInstall.
+  mkInstallScript = module: template: ''
+    mkdir -p $out/lib/cmake/${module}
+    (
+      export staticLibExt="${extensions.staticLibrary}"
+      export sharedLibExt="${extensions.sharedLibrary}"
+      export swiftOs="${swift.swiftOs}"
+      substituteAll \
+        ${builtins.toFile "${module}Config.cmake" template} \
+        $out/lib/cmake/${module}/${module}Config.cmake
+    )
+  '';
+
+in lib.mapAttrs mkInstallScript {
+  SwiftSystem = ''
+    add_library(SwiftSystem::SystemPackage STATIC IMPORTED)
+    set_property(TARGET SwiftSystem::SystemPackage PROPERTY IMPORTED_LOCATION "@out@/lib/swift_static/@swiftOs@/libSystemPackage@staticLibExt@")
+  '';
+
+  SwiftCollections = ''
+    add_library(SwiftCollections::Collections STATIC IMPORTED)
+    set_property(TARGET SwiftCollections::Collections PROPERTY IMPORTED_LOCATION "@out@/lib/swift_static/@swiftOs@/libCollections@staticLibExt@")
+
+    add_library(SwiftCollections::DequeModule STATIC IMPORTED)
+    set_property(TARGET SwiftCollections::DequeModule PROPERTY IMPORTED_LOCATION "@out@/lib/swift_static/@swiftOs@/libDequeModule@staticLibExt@")
+
+    add_library(SwiftCollections::OrderedCollections STATIC IMPORTED)
+    set_property(TARGET SwiftCollections::OrderedCollections PROPERTY IMPORTED_LOCATION "@out@/lib/swift_static/@swiftOs@/libOrderedCollections@staticLibExt@")
+  '';
+
+  TSC = ''
+    add_library(TSCLibc SHARED IMPORTED)
+    set_property(TARGET TSCLibc PROPERTY IMPORTED_LOCATION "@out@/lib/libTSCLibc@sharedLibExt@")
+
+    add_library(TSCBasic SHARED IMPORTED)
+    set_property(TARGET TSCBasic PROPERTY IMPORTED_LOCATION "@out@/lib/libTSCBasic@sharedLibExt@")
+
+    add_library(TSCUtility SHARED IMPORTED)
+    set_property(TARGET TSCUtility PROPERTY IMPORTED_LOCATION "@out@/lib/libTSCUtility@sharedLibExt@")
+  '';
+
+  ArgumentParser = ''
+    add_library(ArgumentParser SHARED IMPORTED)
+    set_property(TARGET ArgumentParser PROPERTY IMPORTED_LOCATION "@out@/lib/swift/@swiftOs@/libArgumentParser@sharedLibExt@")
+
+    add_library(ArgumentParserToolInfo SHARED IMPORTED)
+    set_property(TARGET ArgumentParserToolInfo PROPERTY IMPORTED_LOCATION "@out@/lib/swift/@swiftOs@/libArgumentParserToolInfo@sharedLibExt@")
+  '';
+
+  Yams = ''
+    add_library(Yams SHARED IMPORTED)
+    set_property(TARGET Yams PROPERTY IMPORTED_LOCATION "@out@/lib/swift/@swiftOs@/libYams@sharedLibExt@")
+  '';
+
+  LLBuild = ''
+    add_library(libllbuild SHARED IMPORTED)
+    set_property(TARGET libllbuild PROPERTY IMPORTED_LOCATION "@out@/lib/libllbuild@sharedLibExt@")
+
+    add_library(llbuildSwift SHARED IMPORTED)
+    set_property(TARGET llbuildSwift PROPERTY IMPORTED_LOCATION "@out@/lib/swift/pm/llbuild/libllbuildSwift@sharedLibExt@")
+  '';
+
+  SwiftDriver = ''
+    add_library(SwiftDriver SHARED IMPORTED)
+    set_property(TARGET SwiftDriver PROPERTY IMPORTED_LOCATION "@out@/lib/libSwiftDriver@sharedLibExt@")
+
+    add_library(SwiftDriverExecution SHARED IMPORTED)
+    set_property(TARGET SwiftDriverExecution PROPERTY IMPORTED_LOCATION "@out@/lib/libSwiftDriverExecution@sharedLibExt@")
+
+    add_library(SwiftOptions SHARED IMPORTED)
+    set_property(TARGET SwiftOptions PROPERTY IMPORTED_LOCATION "@out@/lib/libSwiftOptions@sharedLibExt@")
+  '';
+
+  SwiftCrypto = ''
+    add_library(Crypto SHARED IMPORTED)
+    set_property(TARGET Crypto PROPERTY IMPORTED_LOCATION "@out@/lib/swift/@swiftOs@/libCrypto@sharedLibExt@")
+  '';
+}
diff --git a/nixpkgs/pkgs/development/compilers/swift/swiftpm/default.nix b/nixpkgs/pkgs/development/compilers/swift/swiftpm/default.nix
new file mode 100644
index 000000000000..4a7a4ab63cce
--- /dev/null
+++ b/nixpkgs/pkgs/development/compilers/swift/swiftpm/default.nix
@@ -0,0 +1,453 @@
+{ lib
+, stdenv
+, callPackage
+, cmake
+, ninja
+, git
+, swift
+, swiftpm2nix
+, Foundation
+, XCTest
+, pkg-config
+, sqlite
+, ncurses
+, substituteAll
+, runCommandLocal
+, makeWrapper
+, DarwinTools # sw_vers
+, cctools # vtool
+, xcbuild
+, CryptoKit
+, LocalAuthentication
+}:
+
+let
+
+  inherit (swift) swiftOs swiftModuleSubdir swiftStaticModuleSubdir;
+  sharedLibraryExt = stdenv.hostPlatform.extensions.sharedLibrary;
+
+  sources = callPackage ../sources.nix { };
+  generated = swiftpm2nix.helpers ./generated;
+  cmakeGlue = callPackage ./cmake-glue.nix { };
+
+  # Common attributes for the bootstrap swiftpm and the final swiftpm.
+  commonAttrs = {
+    inherit (sources) version;
+    src = sources.swift-package-manager;
+    nativeBuildInputs = [ makeWrapper ];
+    # Required at run-time for the host platform to build package manifests.
+    propagatedBuildInputs = [ Foundation ];
+    patches = [
+      ./patches/cmake-disable-rpath.patch
+      ./patches/cmake-fix-quoting.patch
+      ./patches/disable-index-store.patch
+      ./patches/disable-sandbox.patch
+      ./patches/disable-xctest.patch
+      ./patches/fix-clang-cxx.patch
+      ./patches/nix-pkgconfig-vars.patch
+      (substituteAll {
+        src = ./patches/fix-stdlib-path.patch;
+        inherit (builtins) storeDir;
+        swiftLib = swift.swift.lib;
+      })
+    ];
+    postPatch = ''
+      # The location of xcrun is hardcoded. We need PATH lookup instead.
+      find Sources -name '*.swift' | xargs sed -i -e 's|/usr/bin/xcrun|xcrun|g'
+
+      # Patch the location where swiftpm looks for its API modules.
+      substituteInPlace Sources/PackageModel/UserToolchain.swift \
+        --replace \
+          'librariesPath = applicationPath.parentDirectory' \
+          "librariesPath = AbsolutePath(\"$out\")"
+
+      # Fix case-sensitivity issues.
+      # Upstream PR: https://github.com/apple/swift-package-manager/pull/6500
+      substituteInPlace Sources/CMakeLists.txt \
+        --replace \
+          'packageCollectionsSigning' \
+          'PackageCollectionsSigning'
+      substituteInPlace Sources/PackageCollectionsSigning/CMakeLists.txt \
+        --replace \
+          'SubjectPublickeyInfo' \
+          'SubjectPublicKeyInfo'
+      substituteInPlace Sources/PackageCollections/CMakeLists.txt \
+        --replace \
+          'FilepackageCollectionsSourcesStorage' \
+          'FilePackageCollectionsSourcesStorage'
+    '';
+  };
+
+  # Tools invoked by swiftpm at run-time.
+  runtimeDeps = [ git ]
+    ++ lib.optionals stdenv.isDarwin [
+      xcbuild.xcrun
+      # These tools are part of cctools, but adding that as a build input puts
+      # an unwrapped linker in PATH, and breaks builds. This small derivation
+      # exposes just the tools we need:
+      # - vtool is used to determine a minimum deployment target.
+      # - libtool is used to build static libraries.
+      (runCommandLocal "swiftpm-cctools" { } ''
+        mkdir -p $out/bin
+        ln -s ${cctools}/bin/vtool $out/bin/vtool
+        ln -s ${cctools}/bin/libtool $out/bin/libtool
+      '')
+    ];
+
+  # Common attributes for the bootstrap derivations.
+  mkBootstrapDerivation = attrs: stdenv.mkDerivation (attrs // {
+    nativeBuildInputs = (attrs.nativeBuildInputs or [ ])
+      ++ [ cmake ninja swift ]
+      ++ lib.optionals stdenv.isDarwin [ DarwinTools ];
+
+    buildInputs = (attrs.buildInputs or [ ])
+      ++ [ Foundation ];
+
+    postPatch = (attrs.postPatch or "")
+      + lib.optionalString stdenv.isDarwin ''
+        # On Darwin only, Swift uses arm64 as cpu arch.
+        if [ -e cmake/modules/SwiftSupport.cmake ]; then
+          substituteInPlace cmake/modules/SwiftSupport.cmake \
+            --replace '"aarch64" PARENT_SCOPE' '"arm64" PARENT_SCOPE'
+        fi
+      '';
+
+    preConfigure = (attrs.preConfigure or "")
+      + ''
+        # Builds often don't set a target, and our default minimum macOS deployment
+        # target on x86_64-darwin is too low. Harmless on non-Darwin.
+        export MACOSX_DEPLOYMENT_TARGET=10.15.4
+      '';
+
+    postInstall = (attrs.postInstall or "")
+      + lib.optionalString stdenv.isDarwin ''
+        # The install name of libraries is incorrectly set to lib/ (via our
+        # CMake setup hook) instead of lib/swift/. This'd be easily fixed by
+        # fixDarwinDylibNames, but some builds create libraries that reference
+        # eachother, and we also have to fix those references.
+        dylibs="$(find $out/lib/swift* -name '*.dylib')"
+        changes=""
+        for dylib in $dylibs; do
+          changes+=" -change $(otool -D $dylib | tail -n 1) $dylib"
+        done
+        for dylib in $dylibs; do
+          install_name_tool -id $dylib $changes $dylib
+        done
+      '';
+
+    cmakeFlags = (attrs.cmakeFlags or [ ])
+      ++ [
+        # Some builds link to libraries within the same build. Make sure these
+        # create references to $out. None of our builds run their own products,
+        # so we don't have to account for that scenario.
+        "-DCMAKE_BUILD_WITH_INSTALL_NAME_DIR=ON"
+      ];
+  });
+
+  # On Darwin, we only want ncurses in the linker search path, because headers
+  # are part of libsystem. Adding its headers to the search path causes strange
+  # mixing and errors.
+  # TODO: Find a better way to prevent this conflict.
+  ncursesInput = if stdenv.isDarwin then ncurses.out else ncurses;
+
+  # Derivations for bootstrapping dependencies using CMake.
+  # This is based on the `swiftpm/Utilities/bootstrap` script.
+  #
+  # Some of the installation steps here are a bit hacky, because it seems like
+  # these packages were not really meant to be installed using CMake. The
+  # regular swiftpm bootstrap simply refers to the source and build
+  # directories. The advantage of separate builds is that we can more easily
+  # link libs together using existing Nixpkgs infra.
+  #
+  # In the end, we don't expose these derivations, and they only exist during
+  # the bootstrap phase. The final swiftpm derivation does not depend on them.
+
+  swift-system = mkBootstrapDerivation {
+    name = "swift-system";
+    src = generated.sources.swift-system;
+
+    postInstall = cmakeGlue.SwiftSystem
+      + lib.optionalString (!stdenv.isDarwin) ''
+        # The cmake rules apparently only use the Darwin install convention.
+        # Fix up the installation so the module can be found on non-Darwin.
+        mkdir -p $out/${swiftStaticModuleSubdir}
+        mv $out/lib/swift_static/${swiftOs}/*.swiftmodule $out/${swiftStaticModuleSubdir}/
+      '';
+  };
+
+  swift-collections = mkBootstrapDerivation {
+    name = "swift-collections";
+    src = generated.sources.swift-collections;
+
+    postPatch = ''
+      # Only builds static libs on Linux, but this installation difference is a
+      # hassle. Because this installation is temporary for the bootstrap, may
+      # as well build static libs everywhere.
+      sed -i -e '/BUILD_SHARED_LIBS/d' CMakeLists.txt
+    '';
+
+    postInstall = cmakeGlue.SwiftCollections
+      + lib.optionalString (!stdenv.isDarwin) ''
+        # The cmake rules apparently only use the Darwin install convention.
+        # Fix up the installation so the module can be found on non-Darwin.
+        mkdir -p $out/${swiftStaticModuleSubdir}
+        mv $out/lib/swift_static/${swiftOs}/*.swiftmodule $out/${swiftStaticModuleSubdir}/
+      '';
+  };
+
+  swift-tools-support-core = mkBootstrapDerivation {
+    name = "swift-tools-support-core";
+    src = generated.sources.swift-tools-support-core;
+
+    patches = [
+      ./patches/force-unwrap-file-handles.patch
+    ];
+
+    buildInputs = [
+      swift-system
+      sqlite
+    ];
+
+    postInstall = cmakeGlue.TSC + ''
+      # Swift modules are not installed.
+      mkdir -p $out/${swiftModuleSubdir}
+      cp swift/*.swift{module,doc} $out/${swiftModuleSubdir}/
+
+      # Static libs are not installed.
+      cp lib/*.a $out/lib/
+
+      # Headers are not installed.
+      mkdir -p $out/include
+      cp -r ../Sources/TSCclibc/include $out/include/TSC
+    '';
+  };
+
+  swift-argument-parser = mkBootstrapDerivation {
+    name = "swift-argument-parser";
+    src = generated.sources.swift-argument-parser;
+
+    buildInputs = [ ncursesInput sqlite ];
+
+    cmakeFlags = [
+      "-DBUILD_TESTING=NO"
+      "-DBUILD_EXAMPLES=NO"
+    ];
+
+    postInstall = cmakeGlue.ArgumentParser
+      + lib.optionalString stdenv.isLinux ''
+        # Fix rpath so ArgumentParserToolInfo can be found.
+        patchelf --add-rpath "$out/lib/swift/${swiftOs}" \
+          $out/lib/swift/${swiftOs}/libArgumentParser.so
+      '';
+  };
+
+  Yams = mkBootstrapDerivation {
+    name = "Yams";
+    src = generated.sources.Yams;
+
+    # Conflicts with BUILD file on case-insensitive filesystems.
+    cmakeBuildDir = "_build";
+
+    postInstall = cmakeGlue.Yams;
+  };
+
+  llbuild = mkBootstrapDerivation {
+    name = "llbuild";
+    src = generated.sources.swift-llbuild;
+
+    nativeBuildInputs = lib.optional stdenv.isDarwin xcbuild;
+    buildInputs = [ ncursesInput sqlite ];
+
+    patches = [
+      ./patches/llbuild-cmake-disable-rpath.patch
+    ];
+
+    postPatch = ''
+      # Substitute ncurses for curses.
+      find . -name CMakeLists.txt | xargs sed -i -e 's/curses/ncurses/'
+
+      # Use absolute install names instead of rpath.
+      substituteInPlace \
+        products/libllbuild/CMakeLists.txt \
+        products/llbuildSwift/CMakeLists.txt \
+        --replace '@rpath' "$out/lib"
+
+      # This subdirectory is enabled for Darwin only, but requires ObjC XCTest
+      # (and only Swift XCTest is open source).
+      substituteInPlace perftests/CMakeLists.txt \
+        --replace 'add_subdirectory(Xcode/' '#add_subdirectory(Xcode/'
+    '';
+
+    cmakeFlags = [
+      "-DLLBUILD_SUPPORT_BINDINGS=Swift"
+    ];
+
+    postInstall = cmakeGlue.LLBuild + ''
+      # Install module map.
+      cp ../products/libllbuild/include/module.modulemap $out/include
+
+      # Swift modules are not installed.
+      mkdir -p $out/${swiftModuleSubdir}
+      cp products/llbuildSwift/*.swift{module,doc} $out/${swiftModuleSubdir}/
+    '';
+  };
+
+  swift-driver = mkBootstrapDerivation {
+    name = "swift-driver";
+    src = generated.sources.swift-driver;
+
+    buildInputs = [
+      Yams
+      llbuild
+      swift-system
+      swift-argument-parser
+      swift-tools-support-core
+    ];
+
+    postPatch = ''
+      # Tries to link against CYaml, but that's private.
+      substituteInPlace Sources/SwiftDriver/CMakeLists.txt \
+        --replace CYaml ""
+    '';
+
+    postInstall = cmakeGlue.SwiftDriver + ''
+      # Swift modules are not installed.
+      mkdir -p $out/${swiftModuleSubdir}
+      cp swift/*.swift{module,doc} $out/${swiftModuleSubdir}/
+    '';
+  };
+
+  swift-crypto = mkBootstrapDerivation {
+    name = "swift-crypto";
+    src = generated.sources.swift-crypto;
+
+    postPatch = ''
+      # Fix use of hardcoded tool paths on Darwin.
+      substituteInPlace CMakeLists.txt \
+        --replace /usr/bin/ar $NIX_CC/bin/ar
+      substituteInPlace CMakeLists.txt \
+        --replace /usr/bin/ranlib $NIX_CC/bin/ranlib
+    '';
+
+    postInstall = cmakeGlue.SwiftCrypto + ''
+      # Static libs are not installed.
+      cp lib/*.a $out/lib/
+
+      # Headers are not installed.
+      cp -r ../Sources/CCryptoBoringSSL/include $out/include
+    '';
+  };
+
+  # Build a bootrapping swiftpm using CMake.
+  swiftpm-bootstrap = mkBootstrapDerivation (commonAttrs // {
+    pname = "swiftpm-bootstrap";
+
+    buildInputs = [
+      llbuild
+      sqlite
+      swift-argument-parser
+      swift-collections
+      swift-crypto
+      swift-driver
+      swift-system
+      swift-tools-support-core
+    ];
+
+    cmakeFlags = [
+      "-DUSE_CMAKE_INSTALL=ON"
+    ];
+
+    postInstall = ''
+      for program in $out/bin/swift-*; do
+        wrapProgram $program --prefix PATH : ${lib.makeBinPath runtimeDeps}
+      done
+    '';
+  });
+
+# Build the final swiftpm with the bootstrapping swiftpm.
+in stdenv.mkDerivation (commonAttrs // {
+  pname = "swiftpm";
+
+  nativeBuildInputs = commonAttrs.nativeBuildInputs ++ [
+    pkg-config
+    swift
+    swiftpm-bootstrap
+  ];
+  buildInputs = [
+    ncursesInput
+    sqlite
+    XCTest
+  ]
+    ++ lib.optionals stdenv.isDarwin [
+      CryptoKit
+      LocalAuthentication
+    ];
+
+  configurePhase = generated.configure + ''
+    # Functionality provided by Xcode XCTest, but not available in
+    # swift-corelibs-xctest.
+    swiftpmMakeMutable swift-tools-support-core
+    substituteInPlace .build/checkouts/swift-tools-support-core/Sources/TSCTestSupport/XCTestCasePerf.swift \
+      --replace 'canImport(Darwin)' 'false'
+    patch -p1 -d .build/checkouts/swift-tools-support-core -i ${./patches/force-unwrap-file-handles.patch}
+
+    # Prevent a warning about SDK directories we don't have.
+    swiftpmMakeMutable swift-driver
+    patch -p1 -d .build/checkouts/swift-driver -i ${substituteAll {
+      src = ../swift-driver/patches/prevent-sdk-dirs-warnings.patch;
+      inherit (builtins) storeDir;
+    }}
+  '';
+
+  buildPhase = ''
+    # Required to link with swift-corelibs-xctest on Darwin.
+    export SWIFTTSC_MACOS_DEPLOYMENT_TARGET=10.12
+
+    TERM=dumb swift-build -c release
+  '';
+
+  # TODO: Tests depend on indexstore-db being provided by an existing Swift
+  # toolchain. (ie. looks for `../lib/libIndexStore.so` relative to swiftc.
+  #doCheck = true;
+  #checkPhase = ''
+  #  TERM=dumb swift-test -c release
+  #'';
+
+  # The following is dervied from Utilities/bootstrap, see install_swiftpm.
+  installPhase = ''
+    binPath="$(swift-build --show-bin-path -c release)"
+
+    mkdir -p $out/bin $out/lib/swift
+
+    cp $binPath/swift-package-manager $out/bin/swift-package
+    wrapProgram $out/bin/swift-package \
+      --prefix PATH : ${lib.makeBinPath runtimeDeps}
+    for tool in swift-build swift-test swift-run swift-package-collection swift-experimental-destination; do
+      ln -s $out/bin/swift-package $out/bin/$tool
+    done
+
+    installSwiftpmModule() {
+      mkdir -p $out/lib/swift/pm/$2
+      cp $binPath/lib$1${sharedLibraryExt} $out/lib/swift/pm/$2/
+
+      if [[ -f $binPath/$1.swiftinterface ]]; then
+        cp $binPath/$1.swiftinterface $out/lib/swift/pm/$2/
+      else
+        cp -r $binPath/$1.swiftmodule $out/lib/swift/pm/$2/
+      fi
+      cp $binPath/$1.swiftdoc $out/lib/swift/pm/$2/
+    }
+    installSwiftpmModule PackageDescription ManifestAPI
+    installSwiftpmModule PackagePlugin PluginAPI
+  '';
+
+  setupHook = ./setup-hook.sh;
+
+  meta = {
+    description = "The Package Manager for the Swift Programming Language";
+    homepage = "https://github.com/apple/swift-package-manager";
+    platforms = with lib.platforms; linux ++ darwin;
+    license = lib.licenses.asl20;
+    maintainers = with lib.maintainers; [ dtzWill trepetti dduan trundle stephank ];
+  };
+})
diff --git a/nixpkgs/pkgs/development/compilers/swift/swiftpm/generated/default.nix b/nixpkgs/pkgs/development/compilers/swift/swiftpm/generated/default.nix
new file mode 100644
index 000000000000..dbcd0f18e71f
--- /dev/null
+++ b/nixpkgs/pkgs/development/compilers/swift/swiftpm/generated/default.nix
@@ -0,0 +1,14 @@
+# This file was generated by swiftpm2nix.
+{
+  workspaceStateFile = ./workspace-state.json;
+  hashes = {
+    "swift-argument-parser" = "1jph9w7lk9nr20fsv2c8p4hisx3dda817fh7pybd0r0j1jwa9nmw";
+    "swift-collections" = "1k6sjx5rqmp3gklny77b480hyzy6gkhpi23r0s8ljfbrcwawgnan";
+    "swift-crypto" = "0kllp7j0hd8k67l9b9zr2c3ddc5bvshldchzivhcz3q31qvq9ag8";
+    "swift-driver" = "0cbvddj54k3sbw0vzlmzhccs7h43hi5kq6i3n2i0mysz3bf0c6zg";
+    "swift-llbuild" = "106vnssh6pgy5s9dnq1hi1c9v2wkfydqgncg5dy7c9n23iisjy3s";
+    "swift-system" = "0402hkx2q2dv27gccnn8ma79ngvwiwzkhcv4zlcdldmy6cgi0px7";
+    "swift-tools-support-core" = "1qvblyiazv58qwyxgyk2dh5ymbab3y70vm2q81qs6rmv43hs8ciz";
+    "Yams" = "0b4lprxl4f6yqq0djnp394mxgmsxm2pljr7fh4f6ihdhnpwfsfvl";
+  };
+}
diff --git a/nixpkgs/pkgs/development/compilers/swift/swiftpm/generated/workspace-state.json b/nixpkgs/pkgs/development/compilers/swift/swiftpm/generated/workspace-state.json
new file mode 100644
index 000000000000..187df519fb7b
--- /dev/null
+++ b/nixpkgs/pkgs/development/compilers/swift/swiftpm/generated/workspace-state.json
@@ -0,0 +1,144 @@
+{
+  "object": {
+    "artifacts": [],
+    "dependencies": [
+      {
+        "basedOn": null,
+        "packageRef": {
+          "identity": "swift-argument-parser",
+          "kind": "remoteSourceControl",
+          "location": "https://github.com/apple/swift-argument-parser.git",
+          "name": "swift-argument-parser"
+        },
+        "state": {
+          "checkoutState": {
+            "revision": "e394bf350e38cb100b6bc4172834770ede1b7232",
+            "version": "1.0.3"
+          },
+          "name": "sourceControlCheckout"
+        },
+        "subpath": "swift-argument-parser"
+      },
+      {
+        "basedOn": null,
+        "packageRef": {
+          "identity": "swift-collections",
+          "kind": "remoteSourceControl",
+          "location": "https://github.com/apple/swift-collections.git",
+          "name": "swift-collections"
+        },
+        "state": {
+          "checkoutState": {
+            "revision": "937e904258d22af6e447a0b72c0bc67583ef64a2",
+            "version": "1.0.4"
+          },
+          "name": "sourceControlCheckout"
+        },
+        "subpath": "swift-collections"
+      },
+      {
+        "basedOn": null,
+        "packageRef": {
+          "identity": "swift-crypto",
+          "kind": "remoteSourceControl",
+          "location": "https://github.com/apple/swift-crypto.git",
+          "name": "swift-crypto"
+        },
+        "state": {
+          "checkoutState": {
+            "revision": "75ec60b8b4cc0f085c3ac414f3dca5625fa3588e",
+            "version": "2.2.4"
+          },
+          "name": "sourceControlCheckout"
+        },
+        "subpath": "swift-crypto"
+      },
+      {
+        "basedOn": null,
+        "packageRef": {
+          "identity": "swift-driver",
+          "kind": "remoteSourceControl",
+          "location": "https://github.com/apple/swift-driver.git",
+          "name": "swift-driver"
+        },
+        "state": {
+          "checkoutState": {
+            "branch": "release/5.8",
+            "revision": "7cfe0c0b6e6297efe88a3ce34e6138ee7eda969e"
+          },
+          "name": "sourceControlCheckout"
+        },
+        "subpath": "swift-driver"
+      },
+      {
+        "basedOn": null,
+        "packageRef": {
+          "identity": "swift-llbuild",
+          "kind": "remoteSourceControl",
+          "location": "https://github.com/apple/swift-llbuild.git",
+          "name": "llbuild"
+        },
+        "state": {
+          "checkoutState": {
+            "branch": "release/5.8",
+            "revision": "dccfc2e127a34b89a849407594cf2d604b598ba9"
+          },
+          "name": "sourceControlCheckout"
+        },
+        "subpath": "swift-llbuild"
+      },
+      {
+        "basedOn": null,
+        "packageRef": {
+          "identity": "swift-system",
+          "kind": "remoteSourceControl",
+          "location": "https://github.com/apple/swift-system.git",
+          "name": "swift-system"
+        },
+        "state": {
+          "checkoutState": {
+            "revision": "836bc4557b74fe6d2660218d56e3ce96aff76574",
+            "version": "1.1.1"
+          },
+          "name": "sourceControlCheckout"
+        },
+        "subpath": "swift-system"
+      },
+      {
+        "basedOn": null,
+        "packageRef": {
+          "identity": "swift-tools-support-core",
+          "kind": "remoteSourceControl",
+          "location": "https://github.com/apple/swift-tools-support-core.git",
+          "name": "swift-tools-support-core"
+        },
+        "state": {
+          "checkoutState": {
+            "branch": "release/5.8",
+            "revision": "ac4871e01ef338cb95b5d28328cab0ec1dfae935"
+          },
+          "name": "sourceControlCheckout"
+        },
+        "subpath": "swift-tools-support-core"
+      },
+      {
+        "basedOn": null,
+        "packageRef": {
+          "identity": "yams",
+          "kind": "remoteSourceControl",
+          "location": "https://github.com/jpsim/Yams.git",
+          "name": "Yams"
+        },
+        "state": {
+          "checkoutState": {
+            "revision": "f47ba4838c30dbd59998a4e4c87ab620ff959e8a",
+            "version": "5.0.5"
+          },
+          "name": "sourceControlCheckout"
+        },
+        "subpath": "Yams"
+      }
+    ]
+  },
+  "version": 6
+}
diff --git a/nixpkgs/pkgs/development/compilers/swift/swiftpm/patches/cmake-disable-rpath.patch b/nixpkgs/pkgs/development/compilers/swift/swiftpm/patches/cmake-disable-rpath.patch
new file mode 100644
index 000000000000..9aeba452f9e8
--- /dev/null
+++ b/nixpkgs/pkgs/development/compilers/swift/swiftpm/patches/cmake-disable-rpath.patch
@@ -0,0 +1,36 @@
+Disable rpath for the bootstrap build with CMake.
+
+--- a/Sources/PackageDescription/CMakeLists.txt
++++ b/Sources/PackageDescription/CMakeLists.txt
+@@ -31,14 +31,11 @@ if(CMAKE_HOST_SYSTEM_NAME STREQUAL Darwin)
+   set(SWIFT_INTERFACE_PATH ${CMAKE_BINARY_DIR}/pm/ManifestAPI/PackageDescription.swiftinterface)
+   target_compile_options(PackageDescription PUBLIC
+     $<$<COMPILE_LANGUAGE:Swift>:-emit-module-interface-path$<SEMICOLON>${SWIFT_INTERFACE_PATH}>)
+-  target_link_options(PackageDescription PRIVATE
+-    "SHELL:-Xlinker -install_name -Xlinker @rpath/libPackageDescription.dylib")
+ endif()
+ 
+ set_target_properties(PackageDescription PROPERTIES
+     Swift_MODULE_NAME PackageDescription
+     Swift_MODULE_DIRECTORY ${CMAKE_BINARY_DIR}/pm/ManifestAPI
+-    INSTALL_NAME_DIR \\@rpath
+     OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/pm/ManifestAPI
+     OUTPUT_NAME PackageDescription
+     ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/pm/ManifestAPI
+--- a/Sources/PackagePlugin/CMakeLists.txt
++++ b/Sources/PackagePlugin/CMakeLists.txt
+@@ -29,14 +29,11 @@ if(CMAKE_HOST_SYSTEM_NAME STREQUAL Darwin)
+   set(SWIFT_INTERFACE_PATH ${CMAKE_BINARY_DIR}/pm/PluginAPI/PackagePlugin.swiftinterface)
+   target_compile_options(PackagePlugin PUBLIC
+     $<$<COMPILE_LANGUAGE:Swift>:-emit-module-interface-path$<SEMICOLON>${SWIFT_INTERFACE_PATH}>)
+-  target_link_options(PackagePlugin PRIVATE
+-    "SHELL:-Xlinker -install_name -Xlinker @rpath/libPackagePlugin.dylib")
+ endif()
+ 
+ set_target_properties(PackagePlugin PROPERTIES
+   Swift_MODULE_NAME PackagePlugin
+   Swift_MODULE_DIRECTORY ${CMAKE_BINARY_DIR}/pm/PluginAPI
+-  INSTALL_NAME_DIR \\@rpath
+   OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/pm/PluginAPI
+   OUTPUT_NAME PackagePlugin
+   ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/pm/PluginAPI
diff --git a/nixpkgs/pkgs/development/compilers/swift/swiftpm/patches/cmake-fix-quoting.patch b/nixpkgs/pkgs/development/compilers/swift/swiftpm/patches/cmake-fix-quoting.patch
new file mode 100644
index 000000000000..04f51e9ec835
--- /dev/null
+++ b/nixpkgs/pkgs/development/compilers/swift/swiftpm/patches/cmake-fix-quoting.patch
@@ -0,0 +1,12 @@
+--- a/Sources/PackageCollectionsSigning/CMakeLists.txt
++++ b/Sources/PackageCollectionsSigning/CMakeLists.txt
+@@ -43,6 +43,7 @@ target_link_libraries(PackageCollectionsSigning PUBLIC
+   PackageCollectionsModel
+   TSCBasic)
+ target_link_libraries(PackageCollectionsSigning PRIVATE
+-  PackageCollectionsSigningLibc
+-  $<$<PLATFORM_ID:Darwin>:SHELL:-Xlinker -framework -Xlinker Security>)
++  PackageCollectionsSigningLibc)
++target_link_options(PackageCollectionsSigning PRIVATE
++  "$<$<PLATFORM_ID:Darwin>:SHELL:-Xlinker -framework -Xlinker Security>")
+ 
diff --git a/nixpkgs/pkgs/development/compilers/swift/swiftpm/patches/disable-index-store.patch b/nixpkgs/pkgs/development/compilers/swift/swiftpm/patches/disable-index-store.patch
new file mode 100644
index 000000000000..bef8d43a0dbc
--- /dev/null
+++ b/nixpkgs/pkgs/development/compilers/swift/swiftpm/patches/disable-index-store.patch
@@ -0,0 +1,23 @@
+The `-index-store-path` option is an Apple extension not available in our
+Clang. Make it opt-in by default.
+
+(It is assumed the `target.type == test` check is for Xcode support, because
+there is no evidence of it in swift-corelibs-xctest.)
+
+--- a/Sources/Build/BuildPlan.swift
++++ b/Sources/Build/BuildPlan.swift
+@@ -103,14 +103,7 @@ extension BuildParameters {
+         case .off:
+             addIndexStoreArguments = false
+         case .auto:
+-            if configuration == .debug {
+-                addIndexStoreArguments = true
+-            } else if target.type == .test {
+-                // Test discovery requires an index store for the test target to discover the tests
+-                addIndexStoreArguments = true
+-            } else {
+                 addIndexStoreArguments = false
+-            }
+         }
+ 
+         if addIndexStoreArguments {
diff --git a/nixpkgs/pkgs/development/compilers/swift/swiftpm/patches/disable-sandbox.patch b/nixpkgs/pkgs/development/compilers/swift/swiftpm/patches/disable-sandbox.patch
new file mode 100644
index 000000000000..0c76d59f9dfb
--- /dev/null
+++ b/nixpkgs/pkgs/development/compilers/swift/swiftpm/patches/disable-sandbox.patch
@@ -0,0 +1,21 @@
+Nix may already sandbox the build, in which case sandbox_apply will fail.
+
+--- a/Sources/Basics/Sandbox.swift
++++ b/Sources/Basics/Sandbox.swift
+@@ -33,12 +33,14 @@ public enum Sandbox {
+         readOnlyDirectories: [AbsolutePath] = []
+     ) throws -> [String] {
+         #if os(macOS)
++        let env = ProcessInfo.processInfo.environment
++        if env["NIX_BUILD_TOP"] == nil || env["IN_NIX_SHELL"] != nil {
+         let profile = try macOSSandboxProfile(strictness: strictness, writableDirectories: writableDirectories, readOnlyDirectories: readOnlyDirectories)
+         return ["/usr/bin/sandbox-exec", "-p", profile] + command
+-        #else
++        }
++        #endif
+         // rdar://40235432, rdar://75636874 tracks implementing sandboxes for other platforms.
+         return command
+-        #endif
+     }
+ 
+     /// Basic strictness level of a sandbox applied to a command line.
diff --git a/nixpkgs/pkgs/development/compilers/swift/swiftpm/patches/disable-xctest.patch b/nixpkgs/pkgs/development/compilers/swift/swiftpm/patches/disable-xctest.patch
new file mode 100644
index 000000000000..b587393dc2a2
--- /dev/null
+++ b/nixpkgs/pkgs/development/compilers/swift/swiftpm/patches/disable-xctest.patch
@@ -0,0 +1,37 @@
+XCTest is not fully open-source, only the Swift library parts. We don't have a
+command-line runner available, so disable support.
+
+--- a/Sources/Commands/Utilities/TestingSupport.swift
++++ b/Sources/Commands/Utilities/TestingSupport.swift
+@@ -72,7 +72,7 @@ enum TestingSupport {
+     /// - Returns: Array of TestSuite
+     static func getTestSuites(fromTestAt path: AbsolutePath, swiftTool: SwiftTool, enableCodeCoverage: Bool, sanitizers: [Sanitizer]) throws -> [TestSuite] {
+         // Run the correct tool.
+-        #if os(macOS)
++        #if false
+         let data: String = try withTemporaryFile { tempFile in
+             let args = [try Self.xctestHelperPath(swiftTool: swiftTool).pathString, path.pathString, tempFile.path.pathString]
+             var env = try Self.constructTestEnvironment(
+--- a/Sources/swiftpm-xctest-helper/main.swift
++++ b/Sources/swiftpm-xctest-helper/main.swift
+@@ -11,8 +11,11 @@
+ //===----------------------------------------------------------------------===//
+ 
+ #if os(macOS)
+-import XCTest
+ import func Darwin.C.exit
++print("Not supported in Nix.")
++exit(1)
++#if false
++import XCTest
+ 
+ /// A helper tool to get list of tests from a XCTest Bundle on macOS.
+ ///
+@@ -134,6 +137,7 @@ do {
+     exit(1)
+ }
+ 
++#endif // nix
+ #else
+ 
+ #if os(Windows)
diff --git a/nixpkgs/pkgs/development/compilers/swift/swiftpm/patches/fix-clang-cxx.patch b/nixpkgs/pkgs/development/compilers/swift/swiftpm/patches/fix-clang-cxx.patch
new file mode 100644
index 000000000000..93c43c664ed3
--- /dev/null
+++ b/nixpkgs/pkgs/development/compilers/swift/swiftpm/patches/fix-clang-cxx.patch
@@ -0,0 +1,121 @@
+Swiftpm may invoke clang, not clang++, to compile C++. Our cc-wrapper also
+doesn't pick up the arguments that enable C++ compilation in this case. Patch
+swiftpm to properly invoke clang++.
+
+--- a/Sources/Build/BuildPlan.swift
++++ b/Sources/Build/BuildPlan.swift
+@@ -2089,7 +2089,7 @@ public class BuildPlan: SPMBuildCore.BuildPlan {
+         for target in dependencies.staticTargets {
+             if case let target as ClangTarget = target.underlyingTarget, target.isCXX {
+                 if buildParameters.hostTriple.isDarwin() {
+-                    buildProduct.additionalFlags += ["-lc++"]
++                    buildProduct.additionalFlags += ["-lc++", "-lc++abi"]
+                 } else if buildParameters.hostTriple.isWindows() {
+                     // Don't link any C++ library.
+                 } else {
+--- a/Sources/Build/LLBuildManifestBuilder.swift
++++ b/Sources/Build/LLBuildManifestBuilder.swift
+@@ -786,7 +786,7 @@ extension LLBuildManifestBuilder {
+ 
+             args += ["-c", path.source.pathString, "-o", path.object.pathString]
+ 
+-            let clangCompiler = try buildParameters.toolchain.getClangCompiler().pathString
++            let clangCompiler = try buildParameters.toolchain.getClangCompiler(isCXX: isCXX).pathString
+             args.insert(clangCompiler, at: 0)
+ 
+             let objectFileNode: Node = .file(path.object)
+--- a/Sources/PackageModel/Toolchain.swift
++++ b/Sources/PackageModel/Toolchain.swift
+@@ -23,7 +23,7 @@ public protocol Toolchain {
+     var macosSwiftStdlib: AbsolutePath { get throws }
+ 
+     /// Path of the `clang` compiler.
+-    func getClangCompiler() throws -> AbsolutePath
++    func getClangCompiler(isCXX: Bool) throws -> AbsolutePath
+ 
+     // FIXME: This is a temporary API until index store is widely available in
+     // the OSS clang compiler. This API should not used for any other purpose.
+--- a/Sources/PackageModel/UserToolchain.swift
++++ b/Sources/PackageModel/UserToolchain.swift
+@@ -57,7 +57,7 @@ public final class UserToolchain: Toolchain {
+     /// Only use search paths, do not fall back to `xcrun`.
+     let useXcrun: Bool
+ 
+-    private var _clangCompiler: AbsolutePath?
++    private var _clangCompiler: [Bool: AbsolutePath] = [:]
+ 
+     private let environment: EnvironmentVariables
+ 
+@@ -196,29 +196,31 @@ public final class UserToolchain: Toolchain {
+     }
+ 
+     /// Returns the path to clang compiler tool.
+-    public func getClangCompiler() throws -> AbsolutePath {
++    public func getClangCompiler(isCXX: Bool) throws -> AbsolutePath {
+         // Check if we already computed.
+-        if let clang = self._clangCompiler {
++        if let clang = self._clangCompiler[isCXX] {
+             return clang
+         }
+ 
+         // Check in the environment variable first.
+-        if let toolPath = UserToolchain.lookup(variable: "CC", searchPaths: self.envSearchPaths, environment: environment) {
+-            self._clangCompiler = toolPath
++        let envVar = isCXX ? "CXX" : "CC";
++        if let toolPath = UserToolchain.lookup(variable: envVar, searchPaths: self.envSearchPaths, environment: environment) {
++            self._clangCompiler[isCXX] = toolPath
+             return toolPath
+         }
+ 
+         // Then, check the toolchain.
++        let tool = isCXX ? "clang++" : "clang";
+         do {
+-            if let toolPath = try? UserToolchain.getTool("clang", binDir: self.destination.toolchainBinDir) {
+-                self._clangCompiler = toolPath
++            if let toolPath = try? UserToolchain.getTool(tool, binDir: self.destination.binDir) {
++                self._clangCompiler[isCXX] = toolPath
+                 return toolPath
+             }
+         }
+ 
+         // Otherwise, lookup it up on the system.
+-        let toolPath = try UserToolchain.findTool("clang", envSearchPaths: self.envSearchPaths, useXcrun: useXcrun)
+-        self._clangCompiler = toolPath
++        let toolPath = try UserToolchain.findTool(tool, envSearchPaths: self.envSearchPaths, useXcrun: useXcrun)
++        self._clangCompiler[isCXX] = toolPath
+         return toolPath
+     }
+ 
+--- a/Sources/SPMBuildCore/BuildParameters.swift
++++ b/Sources/SPMBuildCore/BuildParameters.swift
+@@ -394,7 +394,7 @@ private struct _Toolchain: Encodable {
+     public func encode(to encoder: Encoder) throws {
+         var container = encoder.container(keyedBy: CodingKeys.self)
+         try container.encode(toolchain.swiftCompilerPath, forKey: .swiftCompiler)
+-        try container.encode(toolchain.getClangCompiler(), forKey: .clangCompiler)
++        try container.encode(toolchain.getClangCompiler(isCXX: false), forKey: .clangCompiler)
+ 
+         try container.encode(toolchain.extraFlags.cCompilerFlags, forKey: .extraCCFlags)
+         // Maintaining `extraCPPFlags` key for compatibility with older encoding.
+--- a/Sources/XCBuildSupport/XcodeBuildSystem.swift
++++ b/Sources/XCBuildSupport/XcodeBuildSystem.swift
+@@ -182,7 +182,7 @@ public final class XcodeBuildSystem: SPMBuildCore.BuildSystem {
+         // Generate a table of any overriding build settings.
+         var settings: [String: String] = [:]
+         // An error with determining the override should not be fatal here.
+-        settings["CC"] = try? buildParameters.toolchain.getClangCompiler().pathString
++        settings["CC"] = try? buildParameters.toolchain.getClangCompiler(isCXX: false).pathString
+         // Always specify the path of the effective Swift compiler, which was determined in the same way as for the native build system.
+         settings["SWIFT_EXEC"] = buildParameters.toolchain.swiftCompilerPath.pathString
+         settings["LIBRARY_SEARCH_PATHS"] = "$(inherited) \(try buildParameters.toolchain.toolchainLibDir.pathString)"
+--- a/Tests/BuildTests/MockBuildTestHelper.swift
++++ b/Tests/BuildTests/MockBuildTestHelper.swift
+@@ -23,7 +23,7 @@ struct MockToolchain: PackageModel.Toolchain {
+     #else
+     let extraFlags = BuildFlags(cxxCompilerFlags: ["-lstdc++"])
+     #endif
+-    func getClangCompiler() throws -> AbsolutePath {
++    func getClangCompiler(isCXX: Bool) throws -> AbsolutePath {
+         return AbsolutePath(path: "/fake/path/to/clang")
+     }
+ 
diff --git a/nixpkgs/pkgs/development/compilers/swift/swiftpm/patches/fix-stdlib-path.patch b/nixpkgs/pkgs/development/compilers/swift/swiftpm/patches/fix-stdlib-path.patch
new file mode 100644
index 000000000000..6c9c21cfb98e
--- /dev/null
+++ b/nixpkgs/pkgs/development/compilers/swift/swiftpm/patches/fix-stdlib-path.patch
@@ -0,0 +1,25 @@
+Swiftpm looks for the Swift stdlib relative to the swift compiler, but that's a
+wrapper in our case. It wants to add the stdlib to the rpath, which is
+necessary for back-deployment of some features.
+
+--- a/Sources/PackageModel/Toolchain.swift
++++ b/Sources/PackageModel/Toolchain.swift
+@@ -53,12 +53,18 @@ extension Toolchain {
+ 
+     public var macosSwiftStdlib: AbsolutePath {
+         get throws {
++            if swiftCompilerPath.pathString.starts(with: "@storeDir@") {
++                return AbsolutePath("@swiftLib@/lib/swift/macosx")
++            }
+             return try AbsolutePath(validating: "../../lib/swift/macosx", relativeTo: resolveSymlinks(swiftCompilerPath))
+         }
+     }
+ 
+     public var toolchainLibDir: AbsolutePath {
+         get throws {
++            if swiftCompilerPath.pathString.starts(with: "@storeDir@") {
++                return AbsolutePath("@swiftLib@/lib")
++            }
+             // FIXME: Not sure if it's better to base this off of Swift compiler or our own binary.
+             return try AbsolutePath(validating: "../../lib", relativeTo: resolveSymlinks(swiftCompilerPath))
+         }
diff --git a/nixpkgs/pkgs/development/compilers/swift/swiftpm/patches/force-unwrap-file-handles.patch b/nixpkgs/pkgs/development/compilers/swift/swiftpm/patches/force-unwrap-file-handles.patch
new file mode 100644
index 000000000000..a2f2d38c37c8
--- /dev/null
+++ b/nixpkgs/pkgs/development/compilers/swift/swiftpm/patches/force-unwrap-file-handles.patch
@@ -0,0 +1,33 @@
+From 8d9ab4b6ed24a97e8af0cc338a52aacdcf438b8c Mon Sep 17 00:00:00 2001
+From: Pavel Sobolev <paveloom@riseup.net>
+Date: Tue, 21 Nov 2023 20:53:33 +0300
+Subject: [PATCH] Force-unwrap file handles.
+
+---
+ Sources/TSCBasic/FileSystem.swift | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/Sources/TSCBasic/FileSystem.swift b/Sources/TSCBasic/FileSystem.swift
+index 3a63bdf..a1f3d9d 100644
+--- a/Sources/TSCBasic/FileSystem.swift
++++ b/Sources/TSCBasic/FileSystem.swift
+@@ -425,7 +425,7 @@ private class LocalFileSystem: FileSystem {
+         if fp == nil {
+             throw FileSystemError(errno: errno, path)
+         }
+-        defer { fclose(fp) }
++        defer { fclose(fp!) }
+
+         // Read the data one block at a time.
+         let data = BufferedOutputByteStream()
+@@ -455,7 +455,7 @@ private class LocalFileSystem: FileSystem {
+         if fp == nil {
+             throw FileSystemError(errno: errno, path)
+         }
+-        defer { fclose(fp) }
++        defer { fclose(fp!) }
+
+         // Write the data in one chunk.
+         var contents = bytes.contents
+--
+2.42.0
diff --git a/nixpkgs/pkgs/development/compilers/swift/swiftpm/patches/llbuild-cmake-disable-rpath.patch b/nixpkgs/pkgs/development/compilers/swift/swiftpm/patches/llbuild-cmake-disable-rpath.patch
new file mode 100644
index 000000000000..785e82cc34b6
--- /dev/null
+++ b/nixpkgs/pkgs/development/compilers/swift/swiftpm/patches/llbuild-cmake-disable-rpath.patch
@@ -0,0 +1,14 @@
+Specifying `-platform_version` targeting macos before 10.15 causes cctools ld
+to link with `@rpath`. This may have something to do with Swift ABI stability.
+
+--- a/products/llbuildSwift/CMakeLists.txt
++++ b/products/llbuildSwift/CMakeLists.txt
+@@ -22,7 +17,7 @@ endif()
+
+ # TODO(compnerd) move both of these outside of the CMake into the invocation
+ if(CMAKE_SYSTEM_NAME STREQUAL Darwin)
+-  add_compile_options(-target ${CMAKE_OSX_ARCHITECTURES}-apple-macosx10.10)
++  add_compile_options(-target ${CMAKE_OSX_ARCHITECTURES}-apple-macosx10.15)
+   if(NOT CMAKE_OSX_SYSROOT STREQUAL "")
+     add_compile_options(-sdk ${CMAKE_OSX_SYSROOT})
+   endif()
diff --git a/nixpkgs/pkgs/development/compilers/swift/swiftpm/patches/nix-pkgconfig-vars.patch b/nixpkgs/pkgs/development/compilers/swift/swiftpm/patches/nix-pkgconfig-vars.patch
new file mode 100644
index 000000000000..e032ce80bf90
--- /dev/null
+++ b/nixpkgs/pkgs/development/compilers/swift/swiftpm/patches/nix-pkgconfig-vars.patch
@@ -0,0 +1,28 @@
+Swift parses .pc files manually, but this means it bypasses our pkg-config
+wrapper. That wrapper normally takes care of introducing the correct
+PKG_CONFIG_PATH for cross compiling.
+
+--- a/Sources/PackageLoading/PkgConfig.swift
++++ b/Sources/PackageLoading/PkgConfig.swift
+@@ -123,14 +123,17 @@ public struct PkgConfig {
+ 
+     private static var envSearchPaths: [AbsolutePath] {
+         get throws {
+-            if let configPath = ProcessEnv.vars["PKG_CONFIG_PATH"] {
++            var result: [AbsolutePath] = []
++            for envVar in ["PKG_CONFIG_PATH", "PKG_CONFIG_PATH_FOR_TARGET"] {
++            if let configPath = ProcessEnv.vars[envVar] {
+                 #if os(Windows)
+-                return try configPath.split(separator: ";").map({ try AbsolutePath(validating: String($0)) })
++                result += try configPath.split(separator: ";").map({ try AbsolutePath(validating: String($0)) })
+                 #else
+-                return try configPath.split(separator: ":").map({ try AbsolutePath(validating: String($0)) })
++                result += try configPath.split(separator: ":").map({ try AbsolutePath(validating: String($0)) })
+                 #endif
+             }
+-            return []
++            }
++            return result
+         }
+     }
+ }
diff --git a/nixpkgs/pkgs/development/compilers/swift/swiftpm/setup-hook.sh b/nixpkgs/pkgs/development/compilers/swift/swiftpm/setup-hook.sh
new file mode 100644
index 000000000000..160fbb1ccca3
--- /dev/null
+++ b/nixpkgs/pkgs/development/compilers/swift/swiftpm/setup-hook.sh
@@ -0,0 +1,60 @@
+# Build using 'swift-build'.
+swiftpmBuildPhase() {
+    runHook preBuild
+
+    local buildCores=1
+    if [ "${enableParallelBuilding-1}" ]; then
+        buildCores="$NIX_BUILD_CORES"
+    fi
+
+    local flagsArray=(
+        -j $buildCores
+        -c "${swiftpmBuildConfig-release}"
+        $swiftpmFlags "${swiftpmFlagsArray[@]}"
+    )
+
+    echoCmd 'build flags' "${flagsArray[@]}"
+    TERM=dumb swift-build "${flagsArray[@]}"
+
+    runHook postBuild
+}
+
+if [ -z "${dontUseSwiftpmBuild-}" ] && [ -z "${buildPhase-}" ]; then
+    buildPhase=swiftpmBuildPhase
+fi
+
+# Check using 'swift-test'.
+swiftpmCheckPhase() {
+    runHook preCheck
+
+    local buildCores=1
+    if [ "${enableParallelBuilding-1}" ]; then
+        buildCores="$NIX_BUILD_CORES"
+    fi
+
+    local flagsArray=(
+        -j $buildCores
+        -c "${swiftpmBuildConfig-release}"
+        $swiftpmFlags "${swiftpmFlagsArray[@]}"
+    )
+
+    echoCmd 'check flags' "${flagsArray[@]}"
+    TERM=dumb swift-test "${flagsArray[@]}"
+
+    runHook postCheck
+}
+
+if [ -z "${dontUseSwiftpmCheck-}" ] && [ -z "${checkPhase-}" ]; then
+    checkPhase=swiftpmCheckPhase
+fi
+
+# Helper used to find the binary output path.
+# Useful for performing the installPhase of swiftpm packages.
+swiftpmBinPath() {
+    local flagsArray=(
+        -c "${swiftpmBuildConfig-release}"
+        $swiftpmFlags "${swiftpmFlagsArray[@]}"
+    )
+
+    swift-build --show-bin-path "${flagsArray[@]}"
+}