···11+{ lib22+, stdenv33+, cmake44+, coreutils55+, gnugrep66+, perl77+, ninja88+, pkg-config99+, clang1010+, bintools1111+, python31212+, git1313+, fetchFromGitHub1414+, fetchpatch1515+, makeWrapper1616+, gnumake1717+, file1818+, runCommand1919+, writeShellScriptBin2020+# For lldb2121+, libedit2222+, ncurses2323+, swig2424+, libxml22525+# Linux-specific2626+, glibc2727+, libuuid2828+# Darwin-specific2929+, substituteAll3030+, fixDarwinDylibNames3131+, runCommandLocal3232+, xcbuild3333+, cctools # libtool3434+, sigtool3535+, DarwinTools3636+, CoreServices3737+, Foundation3838+, Combine3939+, CLTools_Executables4040+}:4141+4242+let4343+4444+ inherit (stdenv) hostPlatform targetPlatform;4545+4646+ # The Swift toolchain script builds projects with separate repos. By convention, some of them share4747+ # the same version with the main Swift compiler project per release.4848+ version = "5.7";4949+5050+ fetchSwiftRelease = { repo, hash }:5151+ fetchFromGitHub {5252+ owner = "apple";5353+ inherit repo hash;5454+ rev = "swift-${version}-RELEASE";5555+ name = "${repo}-${version}-src";5656+ };5757+5858+ # Names in this set match the directory the source is unpacked to.5959+ sources = {6060+ cmark = fetchSwiftRelease {6161+ repo = "swift-cmark";6262+ hash = "sha256-f0BoTs4HYdx/aJ9HIGCWMalhl8PvClWD6R4QK3qSgAw=";6363+ };6464+ llvm-project = fetchSwiftRelease {6565+ repo = "llvm-project";6666+ hash = "sha256-uW6dEAFaDOlHXnq8lFYxrKNLRPEukauZJxX4UCpWpIY=";6767+ };6868+ swift = fetchSwiftRelease {6969+ repo = "swift";7070+ hash = "sha256-n8WVQYinAyIj4wmQnDhvPsH+t8ydANkGbjFJ6blfHOY=";7171+ };7272+ swift-experimental-string-processing = fetchSwiftRelease {7373+ repo = "swift-experimental-string-processing";7474+ hash = "sha256-Ar9fQWi8bYSvGErrS0SWrxIxwEwCjsYIZcWweZ8bV28=";7575+ };7676+ }7777+ // lib.optionalAttrs (!stdenv.isDarwin) {7878+ swift-corelibs-libdispatch = fetchSwiftRelease {7979+ repo = "swift-corelibs-libdispatch";8080+ hash = "sha256-1qbXiC1k9+T+L6liqXKg6EZXqem6KEEx8OctuL4Kb2o=";8181+ };8282+ };8383+8484+ # Tools invoked by swift at run-time.8585+ runtimeDeps = lib.optionals stdenv.isDarwin [8686+ # libtool is used for static linking. This is part of cctools, but adding8787+ # that as a build input puts an unwrapped linker in PATH, and breaks8888+ # builds. This small derivation exposes just libtool.8989+ # NOTE: The same applies to swift-driver, but that is currently always9090+ # invoked via the old `swift` / `swiftc`. May change in the future.9191+ (runCommandLocal "libtool" { } ''9292+ mkdir -p $out/bin9393+ ln -s ${cctools}/bin/libtool $out/bin/libtool9494+ '')9595+ ];9696+9797+ # There are apparently multiple naming conventions on Darwin. Swift uses the9898+ # xcrun naming convention. See `configure_sdk_darwin` calls in CMake files.9999+ swiftOs = if targetPlatform.isDarwin100100+ then {101101+ "macos" = "macosx";102102+ "ios" = "iphoneos";103103+ #iphonesimulator104104+ #appletvos105105+ #appletvsimulator106106+ #watchos107107+ #watchsimulator108108+ }.${targetPlatform.darwinPlatform}109109+ or (throw "Cannot build Swift for target Darwin platform '${targetPlatform.darwinPlatform}'")110110+ else targetPlatform.parsed.kernel.name;111111+112112+ # Apple Silicon uses a different CPU name in the target triple.113113+ swiftArch = if stdenv.isDarwin && stdenv.isAarch64 then "arm64"114114+ else targetPlatform.parsed.cpu.name;115115+116116+ # On Darwin, a `.swiftmodule` is a subdirectory in `lib/swift/<OS>`,117117+ # containing binaries for supported archs. On other platforms, binaries are118118+ # installed to `lib/swift/<OS>/<ARCH>`. Note that our setup-hook also adds119119+ # `lib/swift` for convenience.120120+ swiftLibSubdir = "lib/swift/${swiftOs}";121121+ swiftModuleSubdir = if hostPlatform.isDarwin122122+ then "lib/swift/${swiftOs}"123123+ else "lib/swift/${swiftOs}/${swiftArch}";124124+125125+ # And then there's also a separate subtree for statically linked modules.126126+ toStaticSubdir = lib.replaceStrings [ "/swift/" ] [ "/swift_static/" ];127127+ swiftStaticLibSubdir = toStaticSubdir swiftLibSubdir;128128+ swiftStaticModuleSubdir = toStaticSubdir swiftModuleSubdir;129129+130130+ # This matches _SWIFT_DEFAULT_COMPONENTS, with specific components disabled.131131+ swiftInstallComponents = [132132+ "autolink-driver"133133+ "compiler"134134+ # "clang-builtin-headers"135135+ "stdlib"136136+ "sdk-overlay"137137+ "parser-lib"138138+ "static-mirror-lib"139139+ "editor-integration"140140+ # "tools"141141+ # "testsuite-tools"142142+ "toolchain-tools"143143+ "toolchain-dev-tools"144144+ "license"145145+ (if stdenv.isDarwin then "sourcekit-xpc-service" else "sourcekit-inproc")146146+ "swift-remote-mirror"147147+ "swift-remote-mirror-headers"148148+ ];149149+150150+ # Build a tool used during the build to create a custom clang wrapper, with151151+ # which we wrap the clang produced by the swift build.152152+ #153153+ # This is used in a `POST_BUILD` for the CMake target, so we rename the154154+ # actual clang to clang-unwrapped, then put the wrapper in place.155155+ #156156+ # We replace the `exec ...` command with `exec -a "$0"` in order to157157+ # preserve $0 for clang. This is because, unlike Nix, we don't have158158+ # separate wrappers for clang/clang++, and clang uses $0 to detect C++.159159+ #160160+ # Similarly, the C++ detection in the wrapper itself also won't work for us,161161+ # so we base it on $0 as well.162162+ makeClangWrapper = writeShellScriptBin "nix-swift-make-clang-wrapper" ''163163+ set -euo pipefail164164+165165+ targetFile="$1"166166+ unwrappedClang="$targetFile-unwrapped"167167+168168+ mv "$targetFile" "$unwrappedClang"169169+ sed < '${clang}/bin/clang' > "$targetFile" \170170+ -e 's|^\s*exec|exec -a "$0"|g' \171171+ -e 's|^\[\[ "${clang.cc}/bin/clang" = \*++ ]]|[[ "$0" = *++ ]]|' \172172+ -e "s|${clang.cc}/bin/clang|$unwrappedClang|g"173173+ chmod a+x "$targetFile"174174+ '';175175+176176+ # Create a tool used during the build to create a custom swift wrapper for177177+ # each of the swift executables produced by the build.178178+ #179179+ # The build produces several `swift-frontend` executables during180180+ # bootstrapping. Each of these has numerous aliases via symlinks, and the181181+ # executable uses $0 to detect what tool is called.182182+ wrapperParams = {183183+ inherit bintools;184184+ default_cc_wrapper = clang; # Instead of `@out@` in the original.185185+ coreutils_bin = lib.getBin coreutils;186186+ gnugrep_bin = gnugrep;187187+ suffixSalt = lib.replaceStrings ["-" "."] ["_" "_"] targetPlatform.config;188188+ use_response_file_by_default = 1;189189+ # NOTE: @prog@ needs to be filled elsewhere.190190+ };191191+ swiftWrapper = runCommand "swift-wrapper.sh" wrapperParams ''192192+ substituteAll '${../wrapper/wrapper.sh}' "$out"193193+ '';194194+ makeSwiftcWrapper = writeShellScriptBin "nix-swift-make-swift-wrapper" ''195195+ set -euo pipefail196196+197197+ targetFile="$1"198198+ unwrappedSwift="$targetFile-unwrapped"199199+200200+ mv "$targetFile" "$unwrappedSwift"201201+ sed < '${swiftWrapper}' > "$targetFile" \202202+ -e "s|@prog@|'$unwrappedSwift'|g" \203203+ -e 's|exec "$prog"|exec -a "$0" "$prog"|g'204204+ chmod a+x "$targetFile"205205+ '';206206+207207+in stdenv.mkDerivation {208208+ pname = "swift";209209+ inherit version;210210+211211+ outputs = [ "out" "lib" "dev" "doc" "man" ];212212+213213+ nativeBuildInputs = [214214+ cmake215215+ git216216+ ninja217217+ perl # pod2man218218+ pkg-config219219+ python3220220+ makeWrapper221221+ makeClangWrapper222222+ makeSwiftcWrapper223223+ ]224224+ ++ lib.optionals stdenv.isDarwin [225225+ xcbuild226226+ sigtool # codesign227227+ DarwinTools # sw_vers228228+ fixDarwinDylibNames229229+ ];230230+231231+ buildInputs = [232232+ # For lldb233233+ python3234234+ swig235235+ libxml2236236+ ]237237+ ++ lib.optionals stdenv.isLinux [238238+ libuuid239239+ ]240240+ ++ lib.optionals stdenv.isDarwin [241241+ CoreServices242242+ Foundation243243+ Combine244244+ ];245245+246246+ # This is a partial reimplementation of our setup hook. Because we reuse247247+ # the Swift wrapper for the Swift build itself, we need to do some of the248248+ # same preparation.249249+ postHook = ''250250+ for pkg in "''${pkgsHostTarget[@]}" '${clang.libc}'; do251251+ for subdir in ${swiftModuleSubdir} ${swiftStaticModuleSubdir} lib/swift; do252252+ if [[ -d "$pkg/$subdir" ]]; then253253+ export NIX_SWIFTFLAGS_COMPILE+=" -I $pkg/$subdir"254254+ fi255255+ done256256+ for subdir in ${swiftLibSubdir} ${swiftStaticLibSubdir} lib/swift; do257257+ if [[ -d "$pkg/$subdir" ]]; then258258+ export NIX_LDFLAGS+=" -L $pkg/$subdir"259259+ fi260260+ done261261+ done262262+ '';263263+264264+ # We invoke cmakeConfigurePhase multiple times, but only need this once.265265+ dontFixCmake = true;266266+ # We setup custom build directories.267267+ dontUseCmakeBuildDir = true;268268+269269+ unpackPhase = ''270270+ mkdir src271271+ cd src272272+273273+ ${lib.concatStrings (lib.mapAttrsToList (dir: src: ''274274+ cp -r ${src} ${dir}275275+ '') sources)}276276+277277+ chmod -R u+w .278278+ '';279279+280280+ patchPhase = ''281281+ # Just patch all the things for now, we can focus this later.282282+ # TODO: eliminate use of env.283283+ find -type f -print0 | xargs -0 sed -i \284284+ ${lib.optionalString stdenv.isDarwin285285+ "-e 's|/usr/libexec/PlistBuddy|${xcbuild}/bin/PlistBuddy|g'"} \286286+ -e 's|/usr/bin/env|${coreutils}/bin/env|g' \287287+ -e 's|/usr/bin/make|${gnumake}/bin/make|g' \288288+ -e 's|/bin/mkdir|${coreutils}/bin/mkdir|g' \289289+ -e 's|/bin/cp|${coreutils}/bin/cp|g' \290290+ -e 's|/usr/bin/file|${file}/bin/file|g'291291+292292+ patch -p1 -d swift -i ${./patches/swift-wrap.patch}293293+ patch -p1 -d swift -i ${./patches/swift-nix-resource-root.patch}294294+ patch -p1 -d swift -i ${./patches/swift-linux-fix-linking.patch}295295+ patch -p1 -d swift -i ${./patches/swift-darwin-fix-bootstrap.patch}296296+ patch -p1 -d swift -i ${substituteAll {297297+ src = ./patches/swift-darwin-plistbuddy-workaround.patch;298298+ inherit swiftArch;299299+ }}300300+ patch -p1 -d swift -i ${substituteAll {301301+ src = ./patches/swift-prevent-sdk-dirs-warning.patch;302302+ inherit (builtins) storeDir;303303+ }}304304+ substituteInPlace swift/cmake/modules/SwiftConfigureSDK.cmake \305305+ --replace '/usr/include' "${stdenv.cc.libc_dev}/include"306306+307307+ # This patch needs to know the lib output location, so must be substituted308308+ # in the same derivation as the compiler.309309+ storeDir="${builtins.storeDir}" \310310+ substituteAll ${./patches/swift-separate-lib.patch} $TMPDIR/swift-separate-lib.patch311311+ patch -p1 -d swift -i $TMPDIR/swift-separate-lib.patch312312+313313+ patch -p1 -d llvm-project/llvm -i ${./patches/llvm-module-cache.patch}314314+315315+ patch -p1 -d llvm-project/clang -i ${./patches/clang-toolchain-dir.patch}316316+ patch -p1 -d llvm-project/clang -i ${./patches/clang-wrap.patch}317317+ patch -p1 -d llvm-project/clang -i ${../../llvm/14/clang/purity.patch}318318+ patch -p2 -d llvm-project/clang -i ${fetchpatch {319319+ name = "clang-cmake-fix-interpreter.patch";320320+ url = "https://github.com/llvm/llvm-project/commit/b5eaf500f2441eff2277ea2973878fb1f171fd0a.patch";321321+ sha256 = "1rma1al0rbm3s3ql6bnvbcighp74lri1lcrwbyacgdqp80fgw1b6";322322+ }}323323+324324+ ${lib.optionalString stdenv.isLinux ''325325+ substituteInPlace llvm-project/clang/lib/Driver/ToolChains/Linux.cpp \326326+ --replace 'SysRoot + "/lib' '"${glibc}/lib" "' \327327+ --replace 'SysRoot + "/usr/lib' '"${glibc}/lib" "' \328328+ --replace 'LibDir = "lib";' 'LibDir = "${glibc}/lib";' \329329+ --replace 'LibDir = "lib64";' 'LibDir = "${glibc}/lib";' \330330+ --replace 'LibDir = X32 ? "libx32" : "lib64";' 'LibDir = "${glibc}/lib";'331331+332332+ # uuid.h is not part of glibc, but of libuuid.333333+ sed -i 's|''${GLIBC_INCLUDE_PATH}/uuid/uuid.h|${libuuid.dev}/include/uuid/uuid.h|' \334334+ swift/stdlib/public/Platform/glibc.modulemap.gyb335335+ ''}336336+337337+ # Remove tests for cross compilation, which we don't currently support.338338+ rm swift/test/Interop/Cxx/class/constructors-copy-irgen.swift339339+ rm swift/test/Interop/Cxx/class/constructors-irgen.swift340340+341341+ # TODO: consider fixing and re-adding. This test fails due to a non-standard "install_prefix".342342+ rm swift/validation-test/Python/build_swift.swift343343+344344+ # We cannot handle the SDK location being in "Weird Location" due to Nix isolation.345345+ rm swift/test/DebugInfo/compiler-flags.swift346346+347347+ # TODO: Fix issue with ld.gold invoked from script finding crtbeginS.o and crtendS.o.348348+ rm swift/test/IRGen/ELF-remove-autolink-section.swift349349+350350+ # The following two tests fail because we use don't use the bundled libicu:351351+ # [SOURCE_DIR/utils/build-script] ERROR: can't find source directory for libicu (tried /build/src/icu)352352+ rm swift/validation-test/BuildSystem/default_build_still_performs_epilogue_opts_after_split.test353353+ rm swift/validation-test/BuildSystem/test_early_swift_driver_and_infer.swift354354+355355+ # TODO: This test fails for some unknown reason356356+ rm swift/test/Serialization/restrict-swiftmodule-to-revision.swift357357+358358+ # This test was flaky in ofborg, see #186476359359+ rm swift/test/AutoDiff/compiler_crashers_fixed/sr14290-missing-debug-scopes-in-pullback-trampoline.swift360360+361361+ patchShebangs .362362+363363+ ${lib.optionalString (!stdenv.isDarwin) ''364364+ # NOTE: This interferes with ABI stability on Darwin, which uses the system365365+ # libraries in the hardcoded path /usr/lib/swift.366366+ fixCmakeFiles .367367+ ''}368368+ '';369369+370370+ configurePhase = ''371371+ export SWIFT_SOURCE_ROOT="$PWD"372372+ mkdir -p ../build373373+ cd ../build374374+ export SWIFT_BUILD_ROOT="$PWD"375375+376376+ # Most builds set a target, but LLDB doesn't. Harmless on non-Darwin.377377+ export MACOSX_DEPLOYMENT_TARGET=10.15378378+ '';379379+380380+ # These steps are derived from doing a normal build with.381381+ #382382+ # ./swift/utils/build-toolchain test --dry-run383383+ #384384+ # But dealing with the custom Python build system is far more trouble than385385+ # simply invoking CMake directly. Few variables it passes to CMake are386386+ # actually required or non-default.387387+ #388388+ # Using CMake directly also allows us to split up the already large build,389389+ # and package Swift components separately.390390+ #391391+ # Besides `--dry-run`, another good way to compare build changes between392392+ # Swift releases is to diff the scripts:393393+ #394394+ # git diff swift-5.6.3-RELEASE..swift-5.7-RELEASE -- utils/build*395395+ #396396+ buildPhase = ''397397+ # Helper to build a subdirectory.398398+ #399399+ # Always reset cmakeFlags before calling this. The cmakeConfigurePhase400400+ # amends flags and would otherwise keep expanding it.401401+ function buildProject() {402402+ mkdir -p $SWIFT_BUILD_ROOT/$1403403+ cd $SWIFT_BUILD_ROOT/$1404404+405405+ cmakeDir=$SWIFT_SOURCE_ROOT/''${2-$1}406406+ cmakeConfigurePhase407407+408408+ ninjaBuildPhase409409+ }410410+411411+ cmakeFlags="-GNinja"412412+ buildProject cmark413413+414414+ # Some notes:415415+ # - The Swift build just needs Clang.416416+ # - We can further reduce targets to just our targetPlatform.417417+ cmakeFlags="418418+ -GNinja419419+ -DLLVM_ENABLE_PROJECTS=clang420420+ -DLLVM_TARGETS_TO_BUILD=${{421421+ "x86_64" = "X86";422422+ "aarch64" = "AArch64";423423+ }.${targetPlatform.parsed.cpu.name}}424424+ "425425+ buildProject llvm llvm-project/llvm426426+427427+ # Some notes:428428+ # - Building with libswift defaults to OFF in CMake, but is enabled in429429+ # standard builds, so we enable it as well.430430+ # - Experimental features are OFF by default in CMake, but some are431431+ # required to build the stdlib.432432+ # - SWIFT_STDLIB_ENABLE_OBJC_INTEROP is set explicitely because its check433433+ # is buggy. (Uses SWIFT_HOST_VARIANT_SDK before initialized.)434434+ # Fixed in: https://github.com/apple/swift/commit/84083afef1de5931904d5c815d53856cdb3fb232435435+ cmakeFlags="436436+ -GNinja437437+ -DBOOTSTRAPPING_MODE=BOOTSTRAPPING438438+ -DSWIFT_ENABLE_EXPERIMENTAL_CONCURRENCY=ON439439+ -DLLVM_DIR=$SWIFT_BUILD_ROOT/llvm/lib/cmake/llvm440440+ -DClang_DIR=$SWIFT_BUILD_ROOT/llvm/lib/cmake/clang441441+ -DSWIFT_PATH_TO_CMARK_SOURCE=$SWIFT_SOURCE_ROOT/cmark442442+ -DSWIFT_PATH_TO_CMARK_BUILD=$SWIFT_BUILD_ROOT/cmark443443+ -DSWIFT_PATH_TO_LIBDISPATCH_SOURCE=$SWIFT_SOURCE_ROOT/swift-corelibs-libdispatch444444+ -DEXPERIMENTAL_STRING_PROCESSING_SOURCE_DIR=$SWIFT_SOURCE_ROOT/swift-experimental-string-processing445445+ -DSWIFT_INSTALL_COMPONENTS=${lib.concatStringsSep ";" swiftInstallComponents}446446+ -DSWIFT_STDLIB_ENABLE_OBJC_INTEROP=${if stdenv.isDarwin then "ON" else "OFF"}447447+ "448448+ buildProject swift449449+450450+ # These are based on flags in `utils/build-script-impl`.451451+ #452452+ # LLDB_USE_SYSTEM_DEBUGSERVER=ON disables the debugserver build on Darwin,453453+ # which requires a special signature.454454+ #455455+ # CMAKE_BUILD_WITH_INSTALL_NAME_DIR ensures we don't use rpath on Darwin.456456+ #457457+ # NOTE: On Darwin, we only want ncurses in the linker search path, because458458+ # headers are part of libsystem. Adding its headers to the search path459459+ # causes strange mixing and errors. Note that libedit propagates ncurses,460460+ # so we add both manually here, instead of relying on setup hooks.461461+ # TODO: Find a better way to prevent this conflict.462462+ cmakeFlags="463463+ -GNinja464464+ -DLLDB_SWIFTC=$SWIFT_BUILD_ROOT/swift/bin/swiftc465465+ -DLLDB_SWIFT_LIBS=$SWIFT_BUILD_ROOT/swift/lib/swift466466+ -DLLVM_DIR=$SWIFT_BUILD_ROOT/llvm/lib/cmake/llvm467467+ -DClang_DIR=$SWIFT_BUILD_ROOT/llvm/lib/cmake/clang468468+ -DSwift_DIR=$SWIFT_BUILD_ROOT/swift/lib/cmake/swift469469+ -DLLDB_ENABLE_CURSES=ON470470+ -DLLDB_ENABLE_LIBEDIT=ON471471+ -DLLDB_ENABLE_PYTHON=ON472472+ -DLLDB_ENABLE_LZMA=OFF473473+ -DLLDB_ENABLE_LUA=OFF474474+ -DLLDB_INCLUDE_TESTS=OFF475475+ -DCMAKE_BUILD_WITH_INSTALL_NAME_DIR=ON476476+ ${lib.optionalString stdenv.isDarwin ''477477+ -DLLDB_USE_SYSTEM_DEBUGSERVER=ON478478+ ''}479479+ -DLibEdit_INCLUDE_DIRS=${libedit.dev}/include480480+ -DLibEdit_LIBRARIES=${libedit}/lib/libedit${stdenv.hostPlatform.extensions.sharedLibrary}481481+ -DCURSES_INCLUDE_DIRS=${if stdenv.isDarwin then "/var/empty" else ncurses.dev}/include482482+ -DCURSES_LIBRARIES=${ncurses}/lib/libncurses${stdenv.hostPlatform.extensions.sharedLibrary}483483+ -DPANEL_LIBRARIES=${ncurses}/lib/libpanel${stdenv.hostPlatform.extensions.sharedLibrary}484484+ ";485485+ buildProject lldb llvm-project/lldb486486+487487+ ${lib.optionalString stdenv.isDarwin ''488488+ # Need to do a standalone build of concurrency for Darwin back deployment.489489+ # Based on: utils/swift_build_support/swift_build_support/products/backdeployconcurrency.py490490+ cmakeFlags="491491+ -GNinja492492+ -DCMAKE_Swift_COMPILER=$SWIFT_BUILD_ROOT/swift/bin/swiftc493493+494494+ -DTOOLCHAIN_DIR=/var/empty495495+ -DSWIFT_NATIVE_LLVM_TOOLS_PATH=${stdenv.cc}/bin496496+ -DSWIFT_NATIVE_CLANG_TOOLS_PATH=${stdenv.cc}/bin497497+ -DSWIFT_NATIVE_SWIFT_TOOLS_PATH=$SWIFT_BUILD_ROOT/swift/bin498498+499499+ -DCMAKE_CROSSCOMPILING=ON500500+501501+ -DBUILD_SWIFT_CONCURRENCY_BACK_DEPLOYMENT_LIBRARIES=ON502502+ -DSWIFT_INCLUDE_TOOLS=OFF503503+ -DSWIFT_BUILD_STDLIB_EXTRA_TOOLCHAIN_CONTENT=OFF504504+ -DSWIFT_BUILD_TEST_SUPPORT_MODULES=OFF505505+ -DSWIFT_BUILD_STDLIB=OFF506506+ -DSWIFT_BUILD_DYNAMIC_STDLIB=OFF507507+ -DSWIFT_BUILD_STATIC_STDLIB=OFF508508+ -DSWIFT_BUILD_REMOTE_MIRROR=OFF509509+ -DSWIFT_BUILD_SDK_OVERLAY=OFF510510+ -DSWIFT_BUILD_DYNAMIC_SDK_OVERLAY=OFF511511+ -DSWIFT_BUILD_STATIC_SDK_OVERLAY=OFF512512+ -DSWIFT_INCLUDE_TESTS=OFF513513+ -DSWIFT_BUILD_PERF_TESTSUITE=OFF514514+515515+ -DSWIFT_HOST_VARIANT_ARCH=${swiftArch}516516+ -DBUILD_STANDALONE=ON517517+518518+ -DSWIFT_INSTALL_COMPONENTS=back-deployment519519+520520+ -DSWIFT_SDKS=${{521521+ "macos" = "OSX";522522+ "ios" = "IOS";523523+ #IOS_SIMULATOR524524+ #TVOS525525+ #TVOS_SIMULATOR526526+ #WATCHOS527527+ #WATCHOS_SIMULATOR528528+ }.${targetPlatform.darwinPlatform}}529529+530530+ -DLLVM_DIR=$SWIFT_BUILD_ROOT/llvm/lib/cmake/llvm531531+532532+ -DSWIFT_DEST_ROOT=$out533533+ -DSWIFT_HOST_VARIANT_SDK=OSX534534+535535+ -DSWIFT_DARWIN_DEPLOYMENT_VERSION_OSX=10.15536536+ -DSWIFT_DARWIN_DEPLOYMENT_VERSION_IOS=13.0537537+ -DSWIFT_DARWIN_DEPLOYMENT_VERSION_MACCATALYST=13.0538538+ -DSWIFT_DARWIN_DEPLOYMENT_VERSION_TVOS=13.0539539+ -DSWIFT_DARWIN_DEPLOYMENT_VERSION_WATCHOS=6.0540540+ "541541+542542+ # This depends on the special Clang build specific to the Swift branch.543543+ # We also need to call a specific Ninja target.544544+ export CC=$SWIFT_BUILD_ROOT/llvm/bin/clang545545+ export CXX=$SWIFT_BUILD_ROOT/llvm/bin/clang++546546+ ninjaFlags="back-deployment"547547+548548+ buildProject swift-concurrency-backdeploy swift549549+550550+ export CC=$NIX_CC/bin/clang551551+ export CXX=$NIX_CC/bin/clang++552552+ unset ninjaFlags553553+ ''}554554+ '';555555+556556+ # TODO: ~50 failing tests on x86_64-linux. Other platforms not checked.557557+ doCheck = false;558558+ checkInputs = [ file ];559559+ # TODO: consider using stress-tester and integration-test.560560+ checkPhase = ''561561+ cd $SWIFT_BUILD_ROOT/swift562562+ checkTarget=check-swift-all563563+ ninjaCheckPhase564564+ unset checkTarget565565+ '';566566+567567+ installPhase = ''568568+ # Undo the clang and swift wrapping we did for the build.569569+ # (This happened via patches to cmake files.)570570+ cd $SWIFT_BUILD_ROOT571571+ mv llvm/bin/clang-14{-unwrapped,}572572+ mv swift/bin/swift-frontend{-unwrapped,}573573+574574+ mkdir $out $lib575575+576576+ # Install clang binaries only. We hide these with the wrapper, so they are577577+ # for private use by Swift only.578578+ cd $SWIFT_BUILD_ROOT/llvm579579+ installTargets=install-clang580580+ ninjaInstallPhase581581+ unset installTargets582582+583583+ # LLDB is also a private install.584584+ cd $SWIFT_BUILD_ROOT/lldb585585+ ninjaInstallPhase586586+587587+ cd $SWIFT_BUILD_ROOT/swift588588+ ninjaInstallPhase589589+590590+ ${lib.optionalString stdenv.isDarwin ''591591+ cd $SWIFT_BUILD_ROOT/swift-concurrency-backdeploy592592+ installTargets=install-back-deployment593593+ ninjaInstallPhase594594+ unset installTargets595595+ ''}596596+597597+ # Separate $lib output here, because specific logic follows.598598+ # Only move the dynamic run-time parts, to keep $lib small. Every Swift599599+ # build will depend on it.600600+ moveToOutput "lib/swift" "$lib"601601+ moveToOutput "lib/libswiftDemangle.*" "$lib"602602+603603+ # This link is here because various tools (swiftpm) check for stdlib604604+ # relative to the swift compiler. It's fine if this is for build-time605605+ # stuff, but we should patch all cases were it would end up in an output.606606+ ln -s $lib/lib/swift $out/lib/swift607607+608608+ # Swift has a separate resource root from Clang, but locates the Clang609609+ # resource root via subdir or symlink. Provide a default here, but we also610610+ # patch Swift to prefer NIX_CC if set.611611+ ln -s ${clang}/resource-root $lib/lib/swift/clang612612+613613+ ${lib.optionalString stdenv.isDarwin ''614614+ # Install required library for ObjC interop.615615+ # TODO: Is there no source code for this available?616616+ cp -r ${CLTools_Executables}/usr/lib/arc $out/lib/arc617617+ ''}618618+ '';619619+620620+ preFixup = lib.optionalString stdenv.isLinux ''621621+ # This is cheesy, but helps the patchelf hook remove /build from RPATH.622622+ cd $NIX_BUILD_TOP623623+ mv build buildx624624+ '';625625+626626+ postFixup = lib.optionalString stdenv.isDarwin ''627627+ # These libraries need to use the system install name. The official SDK628628+ # does the same (as opposed to using rpath). Presumably, they are part of629629+ # the stable ABI. Not using the system libraries at run-time is known to630630+ # cause ObjC class conflicts and segfaults.631631+ declare -A systemLibs=(632632+ [libswiftCore.dylib]=1633633+ [libswiftDarwin.dylib]=1634634+ [libswiftSwiftOnoneSupport.dylib]=1635635+ [libswift_Concurrency.dylib]=1636636+ )637637+638638+ for systemLib in "''${!systemLibs[@]}"; do639639+ install_name_tool -id /usr/lib/swift/$systemLib $lib/${swiftLibSubdir}/$systemLib640640+ done641641+642642+ for file in $out/bin/swift-frontend $lib/${swiftLibSubdir}/*.dylib; do643643+ changeArgs=""644644+ for dylib in $(otool -L $file | awk '{ print $1 }'); do645645+ if [[ ''${systemLibs["$(basename $dylib)"]} ]]; then646646+ changeArgs+=" -change $dylib /usr/lib/swift/$(basename $dylib)"647647+ elif [[ "$dylib" = */bootstrapping1/* ]]; then648648+ changeArgs+=" -change $dylib $lib/lib/swift/$(basename $dylib)"649649+ fi650650+ done651651+ if [[ -n "$changeArgs" ]]; then652652+ install_name_tool $changeArgs $file653653+ fi654654+ done655655+656656+ wrapProgram $out/bin/swift-frontend \657657+ --prefix PATH : ${lib.makeBinPath runtimeDeps}658658+ '';659659+660660+ passthru = {661661+ inherit662662+ swiftOs swiftArch663663+ swiftModuleSubdir swiftLibSubdir664664+ swiftStaticModuleSubdir swiftStaticLibSubdir;665665+666666+ # Internal attr for the wrapper.667667+ _wrapperParams = wrapperParams;668668+ };669669+670670+ meta = {671671+ description = "The Swift Programming Language";672672+ homepage = "https://github.com/apple/swift";673673+ maintainers = with lib.maintainers; [ dtzWill trepetti dduan trundle stephank ];674674+ license = lib.licenses.asl20;675675+ platforms = with lib.platforms; linux ++ darwin;676676+ # Swift doesn't support 32-bit Linux, unknown on other platforms.677677+ badPlatforms = lib.platforms.i686;678678+ timeout = 86400; # 24 hours.679679+ };680680+}
···11+The compiler fails if LLVM modules are enabled and it cannot write its module22+cache. This patch detects and rejects the fake, non-existant $HOME used in Nix33+builds.44+55+We could simply return false in `cache_directory`, but that completely disables66+module caching, and may unnecessarily slow down builds. Instead, let it use77+'/tmp/.cache'.88+99+--- a/lib/Support/Unix/Path.inc1010++++ b/lib/Support/Unix/Path.inc1111+@@ -1380,6 +1380,9 @@ bool user_config_directory(SmallVectorImpl<char> &result) {1212+ if (!home_directory(result)) {1313+ return false;1414+ }1515++ if (std::equal(result.begin(), result.end(), "/homeless-shelter")) {1616++ return false;1717++ }1818+ append(result, ".config");1919+ return true;2020+ }2121+@@ -1401,6 +1404,9 @@ bool cache_directory(SmallVectorImpl<char> &result) {2222+ if (!home_directory(result)) {2323+ return false;2424+ }2525++ if (std::equal(result.begin(), result.end(), "/homeless-shelter")) {2626++ system_temp_directory(true/*ErasedOnReboot*/, result);2727++ }2828+ append(result, ".cache");2929+ return true;3030+ }
···11+This patch fixes dylib references during bootstrapping. It's possible22+`LIBSWIFT_BUILD_MODE=BOOTSTRAPPING` is not really well tested on Darwin,33+because official builds don't use it.44+55+In the near future, Swift will require an existing Swift toolchain to66+bootstrap, and we will likely have to replace this any way.77+88+--- a/stdlib/cmake/modules/AddSwiftStdlib.cmake99++++ b/stdlib/cmake/modules/AddSwiftStdlib.cmake1010+@@ -1035,6 +1035,10 @@ function(add_swift_target_library_single target name)1111+ set(install_name_dir "${SWIFTLIB_SINGLE_DARWIN_INSTALL_NAME_DIR}")1212+ endif()1313+1414++ if(DEFINED SWIFTLIB_SINGLE_BOOTSTRAPPING)1515++ set(install_name_dir "${lib_dir}/${output_sub_dir}")1616++ endif()1717++1818+ set_target_properties("${target}"1919+ PROPERTIES2020+ INSTALL_NAME_DIR "${install_name_dir}")
···11+CMake tries to read a list field from SDKSettings.plist, but the output of22+facebook/xcbuild PlistBuddy is incompatible with Apple's.33+44+Simply set the supported architectures to the one target architecture we're55+building for.66+77+--- a/cmake/modules/SwiftConfigureSDK.cmake88++++ b/cmake/modules/SwiftConfigureSDK.cmake99+@@ -189,7 +189,7 @@ macro(configure_sdk_darwin1010+ endif()1111+1212+ # Remove any architectures not supported by the SDK.1313+- remove_sdk_unsupported_archs(${name} ${xcrun_name} ${SWIFT_SDK_${prefix}_PATH} SWIFT_SDK_${prefix}_ARCHITECTURES)1414++ set(SWIFT_SDK_${prefix}_ARCHITECTURES "@swiftArch@")1515+1616+ list_intersect(1717+ "${SWIFT_DARWIN_MODULE_ARCHS}" # lhs
···11+--- a/lib/Driver/ToolChains.cpp22++++ b/lib/Driver/ToolChains.cpp33+@@ -1475,7 +1475,17 @@ const char *ToolChain::getClangLinkerDriver(44+55+ // If there is a linker driver in the toolchain folder, use that instead.66+ if (auto tool = llvm::sys::findProgramByName(LinkerDriver, {toolchainPath}))77+- LinkerDriver = Args.MakeArgString(tool.get());88++ return Args.MakeArgString(tool.get());99++ }1010++1111++ // For Nix, prefer linking using the wrapped system clang, instead of using1212++ // the unwrapped clang packaged with swift. The latter is unable to link, but1313++ // we still want to use it for other purposes (clang importer).1414++ if (auto nixCC = llvm::sys::Process::GetEnv("NIX_CC")) {1515++ llvm::SmallString<128> binDir(nixCC.getValue());1616++ llvm::sys::path::append(binDir, "bin");1717++ if (auto tool = llvm::sys::findProgramByName(LinkerDriver, {binDir.str()}))1818++ return Args.MakeArgString(tool.get());1919+ }2020+2121+ return LinkerDriver;
···11+Swift normally looks for the Clang resource dir in a subdir/symlink of its own22+resource dir. We provide a symlink to the Swift build-time Clang as a default33+there, but we also here patch two checks to try locate it via NIX_CC.44+55+The first (ClangImporter.cpp) happens when Swift code imports C modules. The66+second (ToolChains.cpp) happens when Swift is used to link the final product.77+88+--- a/lib/ClangImporter/ClangImporter.cpp99++++ b/lib/ClangImporter/ClangImporter.cpp1010+@@ -68,6 +68,7 @@1111+ #include "llvm/Support/FileSystem.h"1212+ #include "llvm/Support/Memory.h"1313+ #include "llvm/Support/Path.h"1414++#include "llvm/Support/Process.h"1515+ #include "llvm/Support/YAMLParser.h"1616+ #include "llvm/Support/YAMLTraits.h"1717+ #include <algorithm>1818+@@ -809,6 +810,17 @@ importer::addCommonInvocationArguments(1919+2020+ const std::string &overrideResourceDir = importerOpts.OverrideResourceDir;2121+ if (overrideResourceDir.empty()) {2222++ // Prefer the Clang resource directory from NIX_CC, to allow swapping in a2323++ // different stdenv.2424++ // TODO: Figure out how to provide a user override for this. Probably a2525++ // niche use case, though, and for now a user can unset NIX_CC to work2626++ // around it if necessary.2727++ if (auto nixCC = llvm::sys::Process::GetEnv("NIX_CC")) {2828++ llvm::SmallString<128> resourceDir(nixCC.getValue());2929++ llvm::sys::path::append(resourceDir, "resource-root");3030++ invocationArgStrs.push_back("-resource-dir");3131++ invocationArgStrs.push_back(std::string(resourceDir.str()));3232++ } else {3333+ llvm::SmallString<128> resourceDir(searchPathOpts.RuntimeResourcePath);3434+3535+ // Adjust the path to refer to our copy of the Clang resource directory3636+@@ -824,6 +836,7 @@ importer::addCommonInvocationArguments(3737+ // Set the Clang resource directory to the path we computed.3838+ invocationArgStrs.push_back("-resource-dir");3939+ invocationArgStrs.push_back(std::string(resourceDir.str()));4040++ } // nixCC4141+ } else {4242+ invocationArgStrs.push_back("-resource-dir");4343+ invocationArgStrs.push_back(overrideResourceDir);4444+--- a/lib/Driver/ToolChains.cpp4545++++ b/lib/Driver/ToolChains.cpp4646+@@ -1372,10 +1372,20 @@ void ToolChain::getClangLibraryPath(const ArgList &Args,4747+ SmallString<128> &LibPath) const {4848+ const llvm::Triple &T = getTriple();4949+5050++ // Nix: We provide a `clang` symlink in the default Swift resource root, but5151++ // prefer detecting the Clang resource root via NIX_CC, to allow swapping in5252++ // a different stdenv. However, always honor a user-provided `-resource-dir`.5353++ auto nixCC = llvm::sys::Process::GetEnv("NIX_CC");5454++ if (nixCC && !Args.hasArgNoClaim(options::OPT_resource_dir)) {5555++ LibPath.assign(nixCC.getValue());5656++ llvm::sys::path::append(LibPath, "resource-root");5757++ } else {5858+ getResourceDirPath(LibPath, Args, /*Shared=*/true);5959+ // Remove platform name.6060+ llvm::sys::path::remove_filename(LibPath);6161+- llvm::sys::path::append(LibPath, "clang", "lib",6262++ llvm::sys::path::append(LibPath, "clang");6363++ } // nixCC6464++ llvm::sys::path::append(LibPath, "lib",6565+ T.isOSDarwin() ? "darwin"6666+ : getPlatformNameForTriple(T));6767+ }
···11+Patch paths to use the separate 'lib' output. One of the things this patch22+fixes is the output of `swift -frontend -print-target-info`, which swiftpm uses33+to set rpath on Linux.44+55+The check if the executable path starts with 'out' is necessary for66+bootstrapping, or the compiler will fail when run from the build directory.77+88+--- a/lib/Frontend/CompilerInvocation.cpp99++++ b/lib/Frontend/CompilerInvocation.cpp1010+@@ -49,11 +49,16 @@ swift::CompilerInvocation::CompilerInvocation() {1111+ void CompilerInvocation::computeRuntimeResourcePathFromExecutablePath(1212+ StringRef mainExecutablePath, bool shared,1313+ llvm::SmallVectorImpl<char> &runtimeResourcePath) {1414++ if (mainExecutablePath.startswith("@storeDir@")) {1515++ auto libPath = StringRef("@lib@");1616++ runtimeResourcePath.append(libPath.begin(), libPath.end());1717++ } else {1818+ runtimeResourcePath.append(mainExecutablePath.begin(),1919+ mainExecutablePath.end());2020+2121+ llvm::sys::path::remove_filename(runtimeResourcePath); // Remove /swift2222+ llvm::sys::path::remove_filename(runtimeResourcePath); // Remove /bin2323++ }2424+ appendSwiftLibDir(runtimeResourcePath, shared);2525+ }2626+
···11+{ stdenv22+, swift33+, wrapperParams ? swift._wrapperParams44+}:55+66+stdenv.mkDerivation (wrapperParams // {77+ pname = "swift-wrapper";88+ inherit (swift) version meta;99+1010+ outputs = [ "out" "man" ];1111+1212+ # Setup hook variables.1313+ inherit swift;1414+ inherit (swift)1515+ swiftOs swiftArch1616+ swiftModuleSubdir swiftLibSubdir1717+ swiftStaticModuleSubdir swiftStaticLibSubdir;1818+1919+ passAsFile = [ "buildCommand" ];2020+ buildCommand = ''2121+ mkdir -p $out/bin $out/nix-support2222+2323+ # Symlink all Swift binaries first.2424+ # NOTE: This specifically omits clang binaries. We want to hide these for2525+ # private use by Swift only.2626+ ln -s -t $out/bin/ $swift/bin/swift*2727+2828+ # Replace specific binaries with wrappers.2929+ for executable in swift swiftc swift-frontend; do3030+ export prog=$swift/bin/$executable3131+ rm $out/bin/$executable3232+ substituteAll '${./wrapper.sh}' $out/bin/$executable3333+ chmod a+x $out/bin/$executable3434+ done3535+3636+ ln -s ${swift.man} $man3737+3838+ # This link is here because various tools (swiftpm) check for stdlib3939+ # relative to the swift compiler. It's fine if this is for build-time4040+ # stuff, but we should patch all cases were it would end up in an output.4141+ ln -s ${swift.lib}/lib $out/lib4242+4343+ substituteAll ${./setup-hook.sh} $out/nix-support/setup-hook4444+ '';4545+4646+ passthru = {4747+ inherit swift;4848+ inherit (swift) swiftOs swiftArch swiftModuleSubdir swiftLibSubdir;4949+ };5050+})
···11+# Add import paths for build inputs.22+swiftWrapper_addImports () {33+ # Include subdirectories following both the Swift platform convention, and44+ # a simple `lib/swift` for Nix convenience.55+ for subdir in @swiftModuleSubdir@ @swiftStaticModuleSubdir@ lib/swift; do66+ if [[ -d "$1/$subdir" ]]; then77+ export NIX_SWIFTFLAGS_COMPILE+=" -I $1/$subdir"88+ fi99+ done1010+ for subdir in @swiftLibSubdir@ @swiftStaticLibSubdir@ lib/swift; do1111+ if [[ -d "$1/$subdir" ]]; then1212+ export NIX_LDFLAGS+=" -L $1/$subdir"1313+ fi1414+ done1515+}1616+1717+addEnvHooks "$targetOffset" swiftWrapper_addImports1818+1919+# Use a postHook here because we rely on NIX_CC, which is set by the cc-wrapper2020+# setup hook, so delay until we're sure it was run.2121+swiftWrapper_postHook () {2222+ # On Darwin, libc also contains Swift modules.2323+ if [[ -e "$NIX_CC/nix-support/orig-libc" ]]; then2424+ swiftWrapper_addImports "$(<$NIX_CC/nix-support/orig-libc)"2525+ fi2626+}2727+2828+postHooks+=(swiftWrapper_postHook)
···11+#! @shell@22+# NOTE: This wrapper is derived from cc-wrapper.sh, and is hopefully somewhat33+# diffable with the original, so changes can be merged if necessary.44+set -eu -o pipefail +o posix55+shopt -s nullglob66+77+if (( "${NIX_DEBUG:-0}" >= 7 )); then88+ set -x99+fi1010+1111+cc_wrapper="${NIX_CC:-@default_cc_wrapper@}"1212+1313+source $cc_wrapper/nix-support/utils.bash1414+1515+expandResponseParams "$@"1616+1717+# Check if we should wrap this Swift invocation at all, and how. Specifically,1818+# there are some internal tools we don't wrap, plus swift-frontend doesn't link1919+# and doesn't understand linker flags. This follows logic in2020+# `lib/DriverTool/driver.cpp`.2121+prog=@prog@2222+progName="$(basename "$prog")"2323+firstArg="${params[0]:-}"2424+isFrontend=02525+isRepl=02626+2727+# These checks follow `shouldRunAsSubcommand`.2828+if [[ "$progName" == swift ]]; then2929+ case "$firstArg" in3030+ "" | -* | *.* | */* | repl)3131+ ;;3232+ *)3333+ exec "swift-$firstArg" "${params[@]:1}"3434+ ;;3535+ esac3636+fi3737+3838+# These checks follow the first part of `run_driver`.3939+#4040+# NOTE: The original function short-circuits, but we can't here, because both4141+# paths must be wrapped. So we use an 'isFrontend' flag instead.4242+case "$firstArg" in4343+ -frontend)4444+ isFrontend=14545+ # Ensure this stays the first argument.4646+ params=( "${params[@]:1}" )4747+ extraBefore+=( "-frontend" )4848+ ;;4949+ -modulewrap)5050+ # Don't wrap this integrated tool.5151+ exec "$prog" "${params[@]}"5252+ ;;5353+ repl)5454+ isRepl=15555+ params=( "${params[@]:1}" )5656+ ;;5757+ --driver-mode=*)5858+ ;;5959+ *)6060+ if [[ "$progName" == swift-frontend ]]; then6161+ isFrontend=16262+ fi6363+ ;;6464+esac6565+6666+path_backup="$PATH"6767+6868+# That @-vars are substituted separately from bash evaluation makes6969+# shellcheck think this, and others like it, are useless conditionals.7070+# shellcheck disable=SC21577171+if [[ -n "@coreutils_bin@" && -n "@gnugrep_bin@" ]]; then7272+ PATH="@coreutils_bin@/bin:@gnugrep_bin@/bin"7373+fi7474+7575+# Parse command line options and set several variables.7676+# For instance, figure out if linker flags should be passed.7777+# GCC prints annoying warnings when they are not needed.7878+isCxx=07979+dontLink=$isFrontend8080+8181+for p in "${params[@]}"; do8282+ case "$p" in8383+ -enable-cxx-interop)8484+ isCxx=1 ;;8585+ esac8686+done8787+8888+# NOTE: We don't modify these for Swift, but sourced scripts may use them.8989+cxxInclude=19090+cxxLibrary=19191+cInclude=19292+9393+linkType=$(checkLinkType "${params[@]}")9494+9595+# Optionally filter out paths not refering to the store.9696+if [[ "${NIX_ENFORCE_PURITY:-}" = 1 && -n "$NIX_STORE" ]]; then9797+ kept=()9898+ nParams=${#params[@]}9999+ declare -i n=0100100+ while (( "$n" < "$nParams" )); do101101+ p=${params[n]}102102+ p2=${params[n+1]:-} # handle `p` being last one103103+ n+=1104104+105105+ skipNext=false106106+ path=""107107+ case "$p" in108108+ -[IL]/*) path=${p:2} ;;109109+ -[IL]) path=$p2 skipNext=true ;;110110+ esac111111+112112+ if [[ -n $path ]] && badPath "$path"; then113113+ skip "$path"114114+ $skipNext && n+=1115115+ continue116116+ fi117117+118118+ kept+=("$p")119119+ done120120+ # Old bash empty array hack121121+ params=(${kept+"${kept[@]}"})122122+fi123123+124124+# Flirting with a layer violation here.125125+if [ -z "${NIX_BINTOOLS_WRAPPER_FLAGS_SET_@suffixSalt@:-}" ]; then126126+ source @bintools@/nix-support/add-flags.sh127127+fi128128+129129+# Put this one second so libc ldflags take priority.130130+if [ -z "${NIX_CC_WRAPPER_FLAGS_SET_@suffixSalt@:-}" ]; then131131+ source $cc_wrapper/nix-support/add-flags.sh132132+fi133133+134134+if [[ "$isCxx" = 1 ]]; then135135+ if [[ "$cxxInclude" = 1 ]]; then136136+ NIX_CFLAGS_COMPILE_@suffixSalt@+=" $NIX_CXXSTDLIB_COMPILE_@suffixSalt@"137137+ fi138138+ if [[ "$cxxLibrary" = 1 ]]; then139139+ NIX_CFLAGS_LINK_@suffixSalt@+=" $NIX_CXXSTDLIB_LINK_@suffixSalt@"140140+ fi141141+fi142142+143143+source $cc_wrapper/nix-support/add-hardening.sh144144+145145+# Add the flags for the C compiler proper.146146+addCFlagsToList() {147147+ declare -n list="$1"148148+ shift149149+150150+ for ((i = 1; i <= $#; i++)); do151151+ local val="${!i}"152152+ case "$val" in153153+ # Pass through using -Xcc, but also convert to Swift -I.154154+ # These have slightly different meaning for Clang, but Swift155155+ # doesn't have exact equivalents.156156+ -isystem | -idirafter)157157+ i=$((i + 1))158158+ list+=("-Xcc" "$val" "-Xcc" "${!i}" "-I" "${!i}")159159+ ;;160160+ # Simple rename.161161+ -iframework)162162+ i=$((i + 1))163163+ list+=("-Fsystem" "${!i}")164164+ ;;165165+ # Pass through verbatim.166166+ -I | -Fsystem)167167+ i=$((i + 1))168168+ list+=("${val}" "${!i}")169169+ ;;170170+ -I* | -L* | -F*)171171+ list+=("${val}")172172+ ;;173173+ # Pass through using -Xcc.174174+ *)175175+ list+=("-Xcc" "$val")176176+ ;;177177+ esac178178+ done179179+}180180+for i in ${NIX_SWIFTFLAGS_COMPILE:-}; do181181+ extraAfter+=("$i")182182+done183183+for i in ${NIX_SWIFTFLAGS_COMPILE_BEFORE:-}; do184184+ extraBefore+=("$i")185185+done186186+addCFlagsToList extraAfter $NIX_CFLAGS_COMPILE_@suffixSalt@187187+addCFlagsToList extraBefore ${hardeningCFlags[@]+"${hardeningCFlags[@]}"} $NIX_CFLAGS_COMPILE_BEFORE_@suffixSalt@188188+189189+if [ "$dontLink" != 1 ]; then190190+191191+ # Add the flags that should only be passed to the compiler when192192+ # linking.193193+ addCFlagsToList extraAfter $(filterRpathFlags "$linkType" $NIX_CFLAGS_LINK_@suffixSalt@)194194+195195+ # Add the flags that should be passed to the linker (and prevent196196+ # `ld-wrapper' from adding NIX_LDFLAGS_@suffixSalt@ again).197197+ for i in $(filterRpathFlags "$linkType" $NIX_LDFLAGS_BEFORE_@suffixSalt@); do198198+ extraBefore+=("-Xlinker" "$i")199199+ done200200+ if [[ "$linkType" == dynamic && -n "$NIX_DYNAMIC_LINKER_@suffixSalt@" ]]; then201201+ extraBefore+=("-Xlinker" "-dynamic-linker=$NIX_DYNAMIC_LINKER_@suffixSalt@")202202+ fi203203+ for i in $(filterRpathFlags "$linkType" $NIX_LDFLAGS_@suffixSalt@); do204204+ if [ "${i:0:3}" = -L/ ]; then205205+ extraAfter+=("$i")206206+ else207207+ extraAfter+=("-Xlinker" "$i")208208+ fi209209+ done210210+ export NIX_LINK_TYPE_@suffixSalt@=$linkType211211+fi212212+213213+# TODO: If we ever need to expand functionality of this hook, it may no longer214214+# be compatible with Swift. Right now, it is only used on Darwin to force215215+# -target, which also happens to work with Swift.216216+if [[ -e $cc_wrapper/nix-support/add-local-cc-cflags-before.sh ]]; then217217+ source $cc_wrapper/nix-support/add-local-cc-cflags-before.sh218218+fi219219+220220+# May need to transform the triple injected by the above.221221+for ((i = 1; i < ${#extraBefore[@]}; i++)); do222222+ if [[ "${extraBefore[i]}" = -target ]]; then223223+ i=$((i + 1))224224+ # On Darwin only, need to change 'aarch64' to 'arm64'.225225+ extraBefore[i]="${extraBefore[i]/aarch64-apple-/arm64-apple-}"226226+ # On Darwin, Swift requires the triple to be annotated with a version.227227+ # TODO: Assumes macOS.228228+ extraBefore[i]="${extraBefore[i]/-apple-darwin/-apple-macosx${MACOSX_DEPLOYMENT_TARGET:-11.0}}"229229+ break230230+ fi231231+done232232+233233+# As a very special hack, if the arguments are just `-v', then don't234234+# add anything. This is to prevent `gcc -v' (which normally prints235235+# out the version number and returns exit code 0) from printing out236236+# `No input files specified' and returning exit code 1.237237+if [ "$*" = -v ]; then238238+ extraAfter=()239239+ extraBefore=()240240+fi241241+242242+# Optionally print debug info.243243+if (( "${NIX_DEBUG:-0}" >= 1 )); then244244+ # Old bash workaround, see ld-wrapper for explanation.245245+ echo "extra flags before to $prog:" >&2246246+ printf " %q\n" ${extraBefore+"${extraBefore[@]}"} >&2247247+ echo "original flags to $prog:" >&2248248+ printf " %q\n" ${params+"${params[@]}"} >&2249249+ echo "extra flags after to $prog:" >&2250250+ printf " %q\n" ${extraAfter+"${extraAfter[@]}"} >&2251251+fi252252+253253+PATH="$path_backup"254254+# Old bash workaround, see above.255255+256256+if (( "${NIX_CC_USE_RESPONSE_FILE:-@use_response_file_by_default@}" >= 1 )); then257257+ exec "$prog" @<(printf "%q\n" \258258+ ${extraBefore+"${extraBefore[@]}"} \259259+ ${params+"${params[@]}"} \260260+ ${extraAfter+"${extraAfter[@]}"})261261+else262262+ exec "$prog" \263263+ ${extraBefore+"${extraBefore[@]}"} \264264+ ${params+"${params[@]}"} \265265+ ${extraAfter+"${extraAfter[@]}"}266266+fi