Clone of https://github.com/NixOS/nixpkgs.git (to stress-test knotserver)
1{ 2 lib, 3 stdenv, 4 callPackage, 5 cmake, 6 bash, 7 coreutils, 8 gnugrep, 9 perl, 10 ninja_1_11, 11 pkg-config, 12 clang, 13 bintools, 14 python312Packages, 15 git, 16 fetchpatch, 17 fetchpatch2, 18 makeWrapper, 19 gnumake, 20 file, 21 runCommand, 22 writeShellScriptBin, 23 # For lldb 24 libedit, 25 ncurses, 26 swig, 27 libxml2, 28 # Linux-specific 29 glibc, 30 libuuid, 31 # Darwin-specific 32 replaceVars, 33 fixDarwinDylibNames, 34 xcbuild, 35 cctools, # libtool 36 sigtool, 37 DarwinTools, 38 apple-sdk_13, 39 darwinMinVersionHook, 40}: 41 42let 43 apple-sdk_swift = apple-sdk_13; # Use the SDK that was available when Swift shipped. 44 45 deploymentVersion = 46 if lib.versionOlder (targetPlatform.darwinMinVersion or "0") "10.15" then 47 "10.15" 48 else 49 targetPlatform.darwinMinVersion; 50 51 # Use Python 3.12 for now because Swift 5.8 depends on Python's PyEval_ThreadsInitialized(), which was removed in 3.13. 52 python3 = python312Packages.python.withPackages (p: [ p.setuptools ]); # python 3.12 compat. 53 54 inherit (stdenv) hostPlatform targetPlatform; 55 56 sources = callPackage ../sources.nix { }; 57 58 # There are apparently multiple naming conventions on Darwin. Swift uses the 59 # xcrun naming convention. See `configure_sdk_darwin` calls in CMake files. 60 swiftOs = 61 if targetPlatform.isDarwin then 62 { 63 "macos" = "macosx"; 64 "ios" = "iphoneos"; 65 #iphonesimulator 66 #appletvos 67 #appletvsimulator 68 #watchos 69 #watchsimulator 70 } 71 .${targetPlatform.darwinPlatform} 72 or (throw "Cannot build Swift for target Darwin platform '${targetPlatform.darwinPlatform}'") 73 else 74 targetPlatform.parsed.kernel.name; 75 76 # This causes swiftPackages.XCTest to fail to build on aarch64-linux 77 # as I believe this is because Apple calls the architecture aarch64 78 # on Linux rather than arm64 when used with macOS. 79 swiftArch = 80 if hostPlatform.isDarwin then hostPlatform.darwinArch else targetPlatform.parsed.cpu.name; 81 82 # On Darwin, a `.swiftmodule` is a subdirectory in `lib/swift/<OS>`, 83 # containing binaries for supported archs. On other platforms, binaries are 84 # installed to `lib/swift/<OS>/<ARCH>`. Note that our setup-hook also adds 85 # `lib/swift` for convenience. 86 swiftLibSubdir = "lib/swift/${swiftOs}"; 87 swiftModuleSubdir = 88 if hostPlatform.isDarwin then "lib/swift/${swiftOs}" else "lib/swift/${swiftOs}/${swiftArch}"; 89 90 # And then there's also a separate subtree for statically linked modules. 91 toStaticSubdir = lib.replaceStrings [ "/swift/" ] [ "/swift_static/" ]; 92 swiftStaticLibSubdir = toStaticSubdir swiftLibSubdir; 93 swiftStaticModuleSubdir = toStaticSubdir swiftModuleSubdir; 94 95 # This matches _SWIFT_DEFAULT_COMPONENTS, with specific components disabled. 96 swiftInstallComponents = [ 97 "autolink-driver" 98 "compiler" 99 # "clang-builtin-headers" 100 "stdlib" 101 "sdk-overlay" 102 "static-mirror-lib" 103 "editor-integration" 104 # "tools" 105 # "testsuite-tools" 106 "toolchain-tools" 107 "toolchain-dev-tools" 108 "license" 109 (if stdenv.hostPlatform.isDarwin then "sourcekit-xpc-service" else "sourcekit-inproc") 110 "swift-remote-mirror" 111 "swift-remote-mirror-headers" 112 ]; 113 114 # Build a tool used during the build to create a custom clang wrapper, with 115 # which we wrap the clang produced by the swift build. 116 # 117 # This is used in a `POST_BUILD` for the CMake target, so we rename the 118 # actual clang to clang-unwrapped, then put the wrapper in place. 119 # 120 # We replace the `exec ...` command with `exec -a "$0"` in order to 121 # preserve $0 for clang. This is because, unlike Nix, we don't have 122 # separate wrappers for clang/clang++, and clang uses $0 to detect C++. 123 # 124 # Similarly, the C++ detection in the wrapper itself also won't work for us, 125 # so we base it on $0 as well. 126 makeClangWrapper = writeShellScriptBin "nix-swift-make-clang-wrapper" '' 127 set -euo pipefail 128 129 targetFile="$1" 130 unwrappedClang="$targetFile-unwrapped" 131 132 mv "$targetFile" "$unwrappedClang" 133 sed < '${clang}/bin/clang' > "$targetFile" \ 134 -e 's|^\s*exec|exec -a "$0"|g' \ 135 -e 's|^\[\[ "${clang.cc}/bin/clang" = \*++ ]]|[[ "$0" = *++ ]]|' \ 136 -e "s|${clang.cc}/bin/clang|$unwrappedClang|g" \ 137 -e "s|^\(\s*\)\($unwrappedClang\) \"@\\\$responseFile\"|\1argv0=\$0\n\1${bash}/bin/bash -c \"exec -a '\$argv0' \2 '@\$responseFile'\"|" 138 chmod a+x "$targetFile" 139 ''; 140 141 # Create a tool used during the build to create a custom swift wrapper for 142 # each of the swift executables produced by the build. 143 # 144 # The build produces several `swift-frontend` executables during 145 # bootstrapping. Each of these has numerous aliases via symlinks, and the 146 # executable uses $0 to detect what tool is called. 147 wrapperParams = { 148 inherit bintools; 149 default_cc_wrapper = clang; # Instead of `@out@` in the original. 150 coreutils_bin = lib.getBin coreutils; 151 gnugrep_bin = gnugrep; 152 suffixSalt = lib.replaceStrings [ "-" "." ] [ "_" "_" ] targetPlatform.config; 153 use_response_file_by_default = 1; 154 swiftDriver = ""; 155 # NOTE: @prog@ needs to be filled elsewhere. 156 }; 157 swiftWrapper = runCommand "swift-wrapper.sh" wrapperParams '' 158 # Make empty to avoid adding the SDKs modules in the bootstrap wrapper. Otherwise, the SDK conflicts with the 159 # shims the wrapper tries to build. 160 darwinMinVersion="" substituteAll '${../wrapper/wrapper.sh}' "$out" 161 ''; 162 makeSwiftcWrapper = writeShellScriptBin "nix-swift-make-swift-wrapper" '' 163 set -euo pipefail 164 165 targetFile="$1" 166 unwrappedSwift="$targetFile-unwrapped" 167 168 mv "$targetFile" "$unwrappedSwift" 169 sed < '${swiftWrapper}' > "$targetFile" \ 170 -e "s|@prog@|'$unwrappedSwift'|g" \ 171 -e 's|exec "$prog"|exec -a "$0" "$prog"|g' 172 chmod a+x "$targetFile" 173 ''; 174 175 # On Darwin, we need to use BOOTSTRAPPING-WITH-HOSTLIBS because of ABI 176 # stability, and have to provide the definitions for the system stdlib. 177 appleSwiftCore = stdenv.mkDerivation { 178 name = "apple-swift-core"; 179 dontUnpack = true; 180 181 buildInputs = [ apple-sdk_swift ]; 182 183 installPhase = '' 184 mkdir -p $out/lib/swift 185 cp -r \ 186 "$SDKROOT/usr/lib/swift/Swift.swiftmodule" \ 187 "$SDKROOT/usr/lib/swift/CoreFoundation.swiftmodule" \ 188 "$SDKROOT/usr/lib/swift/Dispatch.swiftmodule" \ 189 "$SDKROOT/usr/lib/swift/ObjectiveC.swiftmodule" \ 190 "$SDKROOT/usr/lib/swift/libswiftCore.tbd" \ 191 "$SDKROOT/usr/lib/swift/libswiftCoreFoundation.tbd" \ 192 "$SDKROOT/usr/lib/swift/libswiftDispatch.tbd" \ 193 "$SDKROOT/usr/lib/swift/libswiftFoundation.tbd" \ 194 "$SDKROOT/usr/lib/swift/libswiftObjectiveC.tbd" \ 195 $out/lib/swift/ 196 ''; 197 }; 198 199 # https://github.com/NixOS/nixpkgs/issues/327836 200 # Fail to build with ninja 1.12 when NIX_BUILD_CORES is low (Hydra or Github Actions). 201 # Can reproduce using `nix --option cores 2 build -f . swiftPackages.swift-unwrapped`. 202 # Until we find out the exact cause, follow [swift upstream][1], pin ninja to version 203 # 1.11.1. 204 # [1]: https://github.com/swiftlang/swift/pull/72989 205 ninja = ninja_1_11; 206 207in 208stdenv.mkDerivation { 209 pname = "swift"; 210 inherit (sources) version; 211 212 outputs = [ 213 "out" 214 "lib" 215 "dev" 216 "doc" 217 "man" 218 ]; 219 220 nativeBuildInputs = [ 221 cmake 222 git 223 ninja 224 perl # pod2man 225 pkg-config 226 python3 227 makeWrapper 228 makeClangWrapper 229 makeSwiftcWrapper 230 ] 231 ++ lib.optionals stdenv.hostPlatform.isDarwin [ 232 xcbuild 233 sigtool # codesign 234 DarwinTools # sw_vers 235 fixDarwinDylibNames 236 cctools.libtool 237 ]; 238 239 buildInputs = [ 240 # For lldb 241 python3 242 swig 243 libxml2 244 ] 245 ++ lib.optionals stdenv.hostPlatform.isLinux [ 246 libuuid 247 ] 248 ++ lib.optionals stdenv.hostPlatform.isDarwin [ 249 apple-sdk_swift 250 ]; 251 252 # Will effectively be `buildInputs` when swift is put in `nativeBuildInputs`. 253 depsTargetTargetPropagated = lib.optionals stdenv.targetPlatform.isDarwin [ 254 apple-sdk_swift 255 ]; 256 257 # This is a partial reimplementation of our setup hook. Because we reuse 258 # the Swift wrapper for the Swift build itself, we need to do some of the 259 # same preparation. 260 postHook = '' 261 for pkg in "''${pkgsHostTarget[@]}" '${clang.libc}'; do 262 for subdir in ${swiftModuleSubdir} ${swiftStaticModuleSubdir} lib/swift; do 263 if [[ -d "$pkg/$subdir" ]]; then 264 export NIX_SWIFTFLAGS_COMPILE+=" -I $pkg/$subdir" 265 fi 266 done 267 for subdir in ${swiftLibSubdir} ${swiftStaticLibSubdir} lib/swift; do 268 if [[ -d "$pkg/$subdir" ]]; then 269 export NIX_LDFLAGS+=" -L $pkg/$subdir" 270 fi 271 done 272 done 273 ''; 274 275 # We invoke cmakeConfigurePhase multiple times, but only need this once. 276 dontFixCmake = true; 277 # We setup custom build directories. 278 dontUseCmakeBuildDir = true; 279 280 unpackPhase = 281 let 282 copySource = repo: "cp -r ${sources.${repo}} ${repo}"; 283 in 284 '' 285 mkdir src 286 cd src 287 288 ${copySource "swift-cmark"} 289 ${copySource "llvm-project"} 290 ${copySource "swift"} 291 ${copySource "swift-experimental-string-processing"} 292 ${copySource "swift-syntax"} 293 ${lib.optionalString (!stdenv.hostPlatform.isDarwin) (copySource "swift-corelibs-libdispatch")} 294 295 chmod -R u+w . 296 ''; 297 298 patchPhase = '' 299 # Just patch all the things for now, we can focus this later. 300 # TODO: eliminate use of env. 301 find -type f -print0 | xargs -0 sed -i \ 302 ${lib.optionalString stdenv.hostPlatform.isDarwin "-e 's|/usr/libexec/PlistBuddy|${xcbuild}/bin/PlistBuddy|g'"} \ 303 -e 's|/usr/bin/env|${coreutils}/bin/env|g' \ 304 -e 's|/usr/bin/make|${gnumake}/bin/make|g' \ 305 -e 's|/bin/mkdir|${coreutils}/bin/mkdir|g' \ 306 -e 's|/bin/cp|${coreutils}/bin/cp|g' \ 307 -e 's|/usr/bin/file|${file}/bin/file|g' 308 309 patch -p1 -d swift -i ${./patches/swift-cmake-3.25-compat.patch} 310 patch -p1 -d swift -i ${./patches/swift-wrap.patch} 311 patch -p1 -d swift -i ${./patches/swift-nix-resource-root.patch} 312 patch -p1 -d swift -i ${./patches/swift-linux-fix-libc-paths.patch} 313 patch -p1 -d swift -i ${./patches/swift-linux-fix-linking.patch} 314 patch -p1 -d swift -i ${./patches/swift-darwin-libcxx-flags.patch} 315 patch -p1 -d swift -i ${ 316 replaceVars ./patches/swift-darwin-plistbuddy-workaround.patch { 317 inherit swiftArch; 318 } 319 } 320 patch -p1 -d swift -i ${ 321 replaceVars ./patches/swift-prevent-sdk-dirs-warning.patch { 322 inherit (builtins) storeDir; 323 } 324 } 325 326 # This patch needs to know the lib output location, so must be substituted 327 # in the same derivation as the compiler. 328 storeDir="${builtins.storeDir}" \ 329 substituteAll ${./patches/swift-separate-lib.patch} $TMPDIR/swift-separate-lib.patch 330 patch -p1 -d swift -i $TMPDIR/swift-separate-lib.patch 331 332 patch -p1 -d llvm-project/llvm -i ${./patches/llvm-module-cache.patch} 333 334 for lldbPatch in ${ 335 lib.escapeShellArgs [ 336 # Fixes for SWIG 4 337 (fetchpatch2 { 338 url = "https://github.com/llvm/llvm-project/commit/81fc5f7909a4ef5a8d4b5da2a10f77f7cb01ba63.patch?full_index=1"; 339 stripLen = 1; 340 hash = "sha256-Znw+C0uEw7lGETQLKPBZV/Ymo2UigZS+Hv/j1mUo7p0="; 341 }) 342 (fetchpatch2 { 343 url = "https://github.com/llvm/llvm-project/commit/f0a25fe0b746f56295d5c02116ba28d2f965c175.patch?full_index=1"; 344 stripLen = 1; 345 hash = "sha256-QzVeZzmc99xIMiO7n//b+RNAvmxghISKQD93U2zOgFI="; 346 }) 347 (fetchpatch2 { 348 url = "https://github.com/llvm/llvm-project/commit/ba35c27ec9aa9807f5b4be2a0c33ca9b045accc7.patch?full_index=1"; 349 stripLen = 1; 350 hash = "sha256-LXl+WbpmWZww5xMDrle3BM2Tw56v8k9LO1f1Z1/wDTs="; 351 }) 352 (fetchpatch2 { 353 url = "https://github.com/llvm/llvm-project/commit/9ec115978ea2bdfc60800cd3c21264341cdc8b0a.patch?full_index=1"; 354 stripLen = 1; 355 hash = "sha256-u0zSejEjfrH3ZoMFm1j+NVv2t5AP9cE5yhsrdTS1dG4="; 356 }) 357 ] 358 }; do 359 patch -p1 -d llvm-project/lldb -i $lldbPatch 360 done 361 362 patch -p1 -d llvm-project/clang -i ${./patches/clang-toolchain-dir.patch} 363 patch -p1 -d llvm-project/clang -i ${./patches/clang-wrap.patch} 364 patch -p1 -d llvm-project/clang -i ${../../llvm/12/clang/purity.patch} 365 patch -p2 -d llvm-project/clang -i ${ 366 fetchpatch { 367 name = "clang-cmake-fix-interpreter.patch"; 368 url = "https://github.com/llvm/llvm-project/commit/b5eaf500f2441eff2277ea2973878fb1f171fd0a.patch"; 369 sha256 = "1rma1al0rbm3s3ql6bnvbcighp74lri1lcrwbyacgdqp80fgw1b6"; 370 } 371 } 372 373 # gcc-13 build fixes 374 patch -p2 -d llvm-project/llvm -i ${ 375 fetchpatch { 376 name = "gcc-13.patch"; 377 url = "https://github.com/llvm/llvm-project/commit/ff1681ddb303223973653f7f5f3f3435b48a1983.patch"; 378 hash = "sha256-nkRPWx8gNvYr7mlvEUiOAb1rTrf+skCZjAydJVUHrcI="; 379 } 380 } 381 382 ${lib.optionalString stdenv.hostPlatform.isLinux '' 383 substituteInPlace llvm-project/clang/lib/Driver/ToolChains/Linux.cpp \ 384 --replace 'SysRoot + "/lib' '"${glibc}/lib" "' \ 385 --replace 'SysRoot + "/usr/lib' '"${glibc}/lib" "' \ 386 --replace 'LibDir = "lib";' 'LibDir = "${glibc}/lib";' \ 387 --replace 'LibDir = "lib64";' 'LibDir = "${glibc}/lib";' \ 388 --replace 'LibDir = X32 ? "libx32" : "lib64";' 'LibDir = "${glibc}/lib";' 389 390 # uuid.h is not part of glibc, but of libuuid. 391 sed -i 's|''${GLIBC_INCLUDE_PATH}/uuid/uuid.h|${libuuid.dev}/include/uuid/uuid.h|' \ 392 swift/stdlib/public/Platform/glibc.modulemap.gyb 393 ''} 394 395 # Remove tests for cross compilation, which we don't currently support. 396 rm swift/test/Interop/Cxx/class/constructors-copy-irgen-*.swift 397 rm swift/test/Interop/Cxx/class/constructors-irgen-*.swift 398 399 # TODO: consider fixing and re-adding. This test fails due to a non-standard "install_prefix". 400 rm swift/validation-test/Python/build_swift.swift 401 402 # We cannot handle the SDK location being in "Weird Location" due to Nix isolation. 403 rm swift/test/DebugInfo/compiler-flags.swift 404 405 # TODO: Fix issue with ld.gold invoked from script finding crtbeginS.o and crtendS.o. 406 rm swift/test/IRGen/ELF-remove-autolink-section.swift 407 408 # The following two tests fail because we use don't use the bundled libicu: 409 # [SOURCE_DIR/utils/build-script] ERROR: can't find source directory for libicu (tried /build/src/icu) 410 rm swift/validation-test/BuildSystem/default_build_still_performs_epilogue_opts_after_split.test 411 rm swift/validation-test/BuildSystem/test_early_swift_driver_and_infer.swift 412 413 # TODO: This test fails for some unknown reason 414 rm swift/test/Serialization/restrict-swiftmodule-to-revision.swift 415 416 # This test was flaky in ofborg, see #186476 417 rm swift/test/AutoDiff/compiler_crashers_fixed/issue-56649-missing-debug-scopes-in-pullback-trampoline.swift 418 419 patchShebangs . 420 421 ${lib.optionalString (!stdenv.hostPlatform.isDarwin) '' 422 # NOTE: This interferes with ABI stability on Darwin, which uses the system 423 # libraries in the hardcoded path /usr/lib/swift. 424 fixCmakeFiles . 425 ''} 426 ''; 427 428 # > clang-15-unwrapped: error: unsupported option '-fzero-call-used-regs=used-gpr' for target 'arm64-apple-macosx10.9.0' 429 hardeningDisable = lib.optional stdenv.hostPlatform.isAarch64 "zerocallusedregs"; 430 431 configurePhase = '' 432 export SWIFT_SOURCE_ROOT="$PWD" 433 mkdir -p ../build 434 cd ../build 435 export SWIFT_BUILD_ROOT="$PWD" 436 ''; 437 438 # These steps are derived from doing a normal build with. 439 # 440 # ./swift/utils/build-toolchain test --dry-run 441 # 442 # But dealing with the custom Python build system is far more trouble than 443 # simply invoking CMake directly. Few variables it passes to CMake are 444 # actually required or non-default. 445 # 446 # Using CMake directly also allows us to split up the already large build, 447 # and package Swift components separately. 448 # 449 # Besides `--dry-run`, another good way to compare build changes between 450 # Swift releases is to diff the scripts: 451 # 452 # git diff swift-5.6.3-RELEASE..swift-5.7-RELEASE -- utils/build* 453 # 454 buildPhase = '' 455 # Helper to build a subdirectory. 456 # 457 # Always reset cmakeFlags before calling this. The cmakeConfigurePhase 458 # amends flags and would otherwise keep expanding it. 459 function buildProject() { 460 mkdir -p $SWIFT_BUILD_ROOT/$1 461 cd $SWIFT_BUILD_ROOT/$1 462 463 cmakeDir=$SWIFT_SOURCE_ROOT/''${2-$1} 464 cmakeConfigurePhase 465 466 ninjaBuildPhase 467 } 468 469 cmakeFlags="-GNinja" 470 buildProject swift-cmark 471 472 # Some notes: 473 # - The Swift build just needs Clang. 474 # - We can further reduce targets to just our targetPlatform. 475 cmakeFlags=" 476 -GNinja 477 -DLLVM_ENABLE_PROJECTS=clang 478 -DLLVM_TARGETS_TO_BUILD=${ 479 { 480 "x86_64" = "X86"; 481 "aarch64" = "AArch64"; 482 } 483 .${targetPlatform.parsed.cpu.name} 484 or (throw "Unsupported CPU architecture: ${targetPlatform.parsed.cpu.name}") 485 } 486 " 487 buildProject llvm llvm-project/llvm 488 489 '' 490 + lib.optionalString stdenv.hostPlatform.isDarwin '' 491 # Add appleSwiftCore to the search paths. Adding the whole SDK results in build failures. 492 OLD_NIX_SWIFTFLAGS_COMPILE="$NIX_SWIFTFLAGS_COMPILE" 493 OLD_NIX_LDFLAGS="$NIX_LDFLAGS" 494 export NIX_SWIFTFLAGS_COMPILE=" -I ${appleSwiftCore}/lib/swift" 495 export NIX_LDFLAGS+=" -L ${appleSwiftCore}/lib/swift" 496 '' 497 + '' 498 499 # Some notes: 500 # - BOOTSTRAPPING_MODE defaults to OFF in CMake, but is enabled in standard 501 # builds, so we enable it as well. On Darwin, we have to use the system 502 # Swift libs because of ABI-stability, but this may be trouble if the 503 # builder is an older macOS. 504 # - Experimental features are OFF by default in CMake, but are enabled in 505 # official builds, so we do the same. (Concurrency is also required in 506 # the stdlib. StringProcessing is often implicitely imported, causing 507 # lots of warnings if missing.) 508 # - SWIFT_STDLIB_ENABLE_OBJC_INTEROP is set explicitely because its check 509 # is buggy. (Uses SWIFT_HOST_VARIANT_SDK before initialized.) 510 # Fixed in: https://github.com/apple/swift/commit/84083afef1de5931904d5c815d53856cdb3fb232 511 cmakeFlags=" 512 -GNinja 513 -DBOOTSTRAPPING_MODE=BOOTSTRAPPING${lib.optionalString stdenv.hostPlatform.isDarwin "-WITH-HOSTLIBS"} 514 -DSWIFT_ENABLE_EXPERIMENTAL_DIFFERENTIABLE_PROGRAMMING=ON 515 -DSWIFT_ENABLE_EXPERIMENTAL_CONCURRENCY=ON 516 -DSWIFT_ENABLE_EXPERIMENTAL_DISTRIBUTED=ON 517 -DSWIFT_ENABLE_EXPERIMENTAL_STRING_PROCESSING=ON 518 -DLLVM_DIR=$SWIFT_BUILD_ROOT/llvm/lib/cmake/llvm 519 -DClang_DIR=$SWIFT_BUILD_ROOT/llvm/lib/cmake/clang 520 -DSWIFT_PATH_TO_CMARK_SOURCE=$SWIFT_SOURCE_ROOT/swift-cmark 521 -DSWIFT_PATH_TO_CMARK_BUILD=$SWIFT_BUILD_ROOT/swift-cmark 522 -DSWIFT_PATH_TO_LIBDISPATCH_SOURCE=$SWIFT_SOURCE_ROOT/swift-corelibs-libdispatch 523 -DSWIFT_PATH_TO_SWIFT_SYNTAX_SOURCE=$SWIFT_SOURCE_ROOT/swift-syntax 524 -DSWIFT_PATH_TO_STRING_PROCESSING_SOURCE=$SWIFT_SOURCE_ROOT/swift-experimental-string-processing 525 -DSWIFT_INSTALL_COMPONENTS=${lib.concatStringsSep ";" swiftInstallComponents} 526 -DSWIFT_STDLIB_ENABLE_OBJC_INTEROP=${if stdenv.hostPlatform.isDarwin then "ON" else "OFF"} 527 -DSWIFT_DARWIN_DEPLOYMENT_VERSION_OSX=${deploymentVersion} 528 " 529 buildProject swift 530 531 '' 532 + lib.optionalString stdenv.hostPlatform.isDarwin '' 533 # Restore search paths to remove appleSwiftCore. 534 export NIX_SWIFTFLAGS_COMPILE="$OLD_NIX_SWIFTFLAGS_COMPILE" 535 export NIX_LDFLAGS="$OLD_NIX_LDFLAGS" 536 '' 537 + '' 538 539 # These are based on flags in `utils/build-script-impl`. 540 # 541 # LLDB_USE_SYSTEM_DEBUGSERVER=ON disables the debugserver build on Darwin, 542 # which requires a special signature. 543 # 544 # CMAKE_BUILD_WITH_INSTALL_NAME_DIR ensures we don't use rpath on Darwin. 545 cmakeFlags=" 546 -GNinja 547 -DLLDB_SWIFTC=$SWIFT_BUILD_ROOT/swift/bin/swiftc 548 -DLLDB_SWIFT_LIBS=$SWIFT_BUILD_ROOT/swift/lib/swift 549 -DLLVM_DIR=$SWIFT_BUILD_ROOT/llvm/lib/cmake/llvm 550 -DClang_DIR=$SWIFT_BUILD_ROOT/llvm/lib/cmake/clang 551 -DSwift_DIR=$SWIFT_BUILD_ROOT/swift/lib/cmake/swift 552 -DLLDB_ENABLE_CURSES=ON 553 -DLLDB_ENABLE_LIBEDIT=ON 554 -DLLDB_ENABLE_PYTHON=ON 555 -DLLDB_ENABLE_LZMA=OFF 556 -DLLDB_ENABLE_LUA=OFF 557 -DLLDB_INCLUDE_TESTS=OFF 558 -DCMAKE_BUILD_WITH_INSTALL_NAME_DIR=ON 559 ${lib.optionalString stdenv.hostPlatform.isDarwin '' 560 -DLLDB_USE_SYSTEM_DEBUGSERVER=ON 561 ''} 562 -DLibEdit_INCLUDE_DIRS=${lib.getInclude libedit}/include 563 -DLibEdit_LIBRARIES=${lib.getLib libedit}/lib/libedit${stdenv.hostPlatform.extensions.sharedLibrary} 564 -DCURSES_INCLUDE_DIRS=${lib.getInclude ncurses}/include 565 -DCURSES_LIBRARIES=${lib.getLib ncurses}/lib/libncurses${stdenv.hostPlatform.extensions.sharedLibrary} 566 -DPANEL_LIBRARIES=${lib.getLib ncurses}/lib/libpanel${stdenv.hostPlatform.extensions.sharedLibrary} 567 "; 568 buildProject lldb llvm-project/lldb 569 570 ${lib.optionalString stdenv.targetPlatform.isDarwin '' 571 # Need to do a standalone build of concurrency for Darwin back deployment. 572 # Based on: utils/swift_build_support/swift_build_support/products/backdeployconcurrency.py 573 cmakeFlags=" 574 -GNinja 575 -DCMAKE_Swift_COMPILER=$SWIFT_BUILD_ROOT/swift/bin/swiftc 576 -DSWIFT_PATH_TO_SWIFT_SYNTAX_SOURCE=$SWIFT_SOURCE_ROOT/swift-syntax 577 578 -DTOOLCHAIN_DIR=/var/empty 579 -DSWIFT_NATIVE_LLVM_TOOLS_PATH=${stdenv.cc}/bin 580 -DSWIFT_NATIVE_CLANG_TOOLS_PATH=${stdenv.cc}/bin 581 -DSWIFT_NATIVE_SWIFT_TOOLS_PATH=$SWIFT_BUILD_ROOT/swift/bin 582 583 -DCMAKE_CROSSCOMPILING=ON 584 585 -DBUILD_SWIFT_CONCURRENCY_BACK_DEPLOYMENT_LIBRARIES=ON 586 -DSWIFT_INCLUDE_TOOLS=OFF 587 -DSWIFT_BUILD_STDLIB_EXTRA_TOOLCHAIN_CONTENT=OFF 588 -DSWIFT_BUILD_TEST_SUPPORT_MODULES=OFF 589 -DSWIFT_BUILD_STDLIB=OFF 590 -DSWIFT_BUILD_DYNAMIC_STDLIB=OFF 591 -DSWIFT_BUILD_STATIC_STDLIB=OFF 592 -DSWIFT_BUILD_REMOTE_MIRROR=OFF 593 -DSWIFT_BUILD_SDK_OVERLAY=OFF 594 -DSWIFT_BUILD_DYNAMIC_SDK_OVERLAY=OFF 595 -DSWIFT_BUILD_STATIC_SDK_OVERLAY=OFF 596 -DSWIFT_INCLUDE_TESTS=OFF 597 -DSWIFT_BUILD_PERF_TESTSUITE=OFF 598 599 -DSWIFT_HOST_VARIANT_ARCH=${swiftArch} 600 -DBUILD_STANDALONE=ON 601 602 -DSWIFT_INSTALL_COMPONENTS=back-deployment 603 604 -DSWIFT_SDKS=${ 605 { 606 "macos" = "OSX"; 607 "ios" = "IOS"; 608 #IOS_SIMULATOR 609 #TVOS 610 #TVOS_SIMULATOR 611 #WATCHOS 612 #WATCHOS_SIMULATOR 613 } 614 .${targetPlatform.darwinPlatform} 615 } 616 617 -DLLVM_DIR=$SWIFT_BUILD_ROOT/llvm/lib/cmake/llvm 618 619 -DSWIFT_DEST_ROOT=$out 620 -DSWIFT_HOST_VARIANT_SDK=OSX 621 622 -DSWIFT_DARWIN_DEPLOYMENT_VERSION_OSX=${deploymentVersion} 623 -DSWIFT_DARWIN_DEPLOYMENT_VERSION_IOS=13.0 624 -DSWIFT_DARWIN_DEPLOYMENT_VERSION_MACCATALYST=13.0 625 -DSWIFT_DARWIN_DEPLOYMENT_VERSION_TVOS=13.0 626 -DSWIFT_DARWIN_DEPLOYMENT_VERSION_WATCHOS=6.0 627 " 628 629 # This depends on the special Clang build specific to the Swift branch. 630 # We also need to call a specific Ninja target. 631 export CC=$SWIFT_BUILD_ROOT/llvm/bin/clang 632 export CXX=$SWIFT_BUILD_ROOT/llvm/bin/clang++ 633 ninjaFlags="back-deployment" 634 635 buildProject swift-concurrency-backdeploy swift 636 637 export CC=$NIX_CC/bin/clang 638 export CXX=$NIX_CC/bin/clang++ 639 unset ninjaFlags 640 ''} 641 ''; 642 643 # TODO: ~50 failing tests on x86_64-linux. Other platforms not checked. 644 doCheck = false; 645 nativeCheckInputs = [ file ]; 646 # TODO: consider using stress-tester and integration-test. 647 checkPhase = '' 648 cd $SWIFT_BUILD_ROOT/swift 649 checkTarget=check-swift-all 650 ninjaCheckPhase 651 unset checkTarget 652 ''; 653 654 installPhase = '' 655 # Undo the clang and swift wrapping we did for the build. 656 # (This happened via patches to cmake files.) 657 cd $SWIFT_BUILD_ROOT 658 mv llvm/bin/clang-15{-unwrapped,} 659 mv swift/bin/swift-frontend{-unwrapped,} 660 661 mkdir $out $lib 662 663 # Install clang binaries only. We hide these with the wrapper, so they are 664 # for private use by Swift only. 665 cd $SWIFT_BUILD_ROOT/llvm 666 installTargets=install-clang 667 ninjaInstallPhase 668 unset installTargets 669 670 # LLDB is also a private install. 671 cd $SWIFT_BUILD_ROOT/lldb 672 ninjaInstallPhase 673 674 cd $SWIFT_BUILD_ROOT/swift 675 ninjaInstallPhase 676 677 ${lib.optionalString stdenv.hostPlatform.isDarwin '' 678 cd $SWIFT_BUILD_ROOT/swift-concurrency-backdeploy 679 installTargets=install-back-deployment 680 ninjaInstallPhase 681 unset installTargets 682 ''} 683 684 # Separate $lib output here, because specific logic follows. 685 # Only move the dynamic run-time parts, to keep $lib small. Every Swift 686 # build will depend on it. 687 moveToOutput "lib/swift" "$lib" 688 moveToOutput "lib/libswiftDemangle.*" "$lib" 689 690 # This link is here because various tools (swiftpm) check for stdlib 691 # relative to the swift compiler. It's fine if this is for build-time 692 # stuff, but we should patch all cases were it would end up in an output. 693 ln -s $lib/lib/swift $out/lib/swift 694 695 # Swift has a separate resource root from Clang, but locates the Clang 696 # resource root via subdir or symlink. Provide a default here, but we also 697 # patch Swift to prefer NIX_CC if set. 698 # 699 # NOTE: We don't symlink directly here, because that'd add a run-time dep 700 # on the full Clang compiler to every Swift executable. The copy here is 701 # just copying the 3 symlinks inside to smaller closures. 702 mkdir $lib/lib/swift/clang 703 cp -P ${clang}/resource-root/* $lib/lib/swift/clang/ 704 ''; 705 706 preFixup = lib.optionalString stdenv.hostPlatform.isLinux '' 707 # This is cheesy, but helps the patchelf hook remove /build from RPATH. 708 cd $SWIFT_BUILD_ROOT/.. 709 mv build buildx 710 ''; 711 712 postFixup = lib.optionalString stdenv.hostPlatform.isDarwin '' 713 # These libraries need to use the system install name. The official SDK 714 # does the same (as opposed to using rpath). Presumably, they are part of 715 # the stable ABI. Not using the system libraries at run-time is known to 716 # cause ObjC class conflicts and segfaults. 717 declare -A systemLibs=( 718 [libswiftCore.dylib]=1 719 [libswiftDarwin.dylib]=1 720 [libswiftSwiftOnoneSupport.dylib]=1 721 [libswift_Concurrency.dylib]=1 722 ) 723 724 for systemLib in "''${!systemLibs[@]}"; do 725 install_name_tool -id /usr/lib/swift/$systemLib $lib/${swiftLibSubdir}/$systemLib 726 done 727 728 for file in $out/bin/swift-frontend $lib/${swiftLibSubdir}/*.dylib; do 729 changeArgs="" 730 for dylib in $(otool -L $file | awk '{ print $1 }'); do 731 if [[ ''${systemLibs["$(basename $dylib)"]} ]]; then 732 changeArgs+=" -change $dylib /usr/lib/swift/$(basename $dylib)" 733 elif [[ "$dylib" = */bootstrapping1/* ]]; then 734 changeArgs+=" -change $dylib $lib/lib/swift/$(basename $dylib)" 735 fi 736 done 737 if [[ -n "$changeArgs" ]]; then 738 install_name_tool $changeArgs $file 739 fi 740 done 741 742 wrapProgram $out/bin/swift-frontend \ 743 --prefix PATH : ${lib.makeBinPath [ cctools.libtool ]} 744 745 # Needs to be propagated by the compiler not by its dev output. 746 moveToOutput nix-support/propagated-target-target-deps "$out" 747 ''; 748 749 passthru = { 750 inherit 751 swiftOs 752 swiftArch 753 swiftModuleSubdir 754 swiftLibSubdir 755 swiftStaticModuleSubdir 756 swiftStaticLibSubdir 757 ; 758 759 # Internal attr for the wrapper. 760 _wrapperParams = wrapperParams; 761 }; 762 763 meta = { 764 description = "Swift Programming Language"; 765 homepage = "https://github.com/apple/swift"; 766 teams = [ lib.teams.swift ]; 767 license = lib.licenses.asl20; 768 platforms = with lib.platforms; linux ++ darwin; 769 # Swift doesn't support 32-bit Linux, unknown on other platforms. 770 badPlatforms = lib.platforms.i686; 771 timeout = 86400; # 24 hours. 772 }; 773}