nixpkgs mirror (for testing) github.com/NixOS/nixpkgs
nix
at python-updates 810 lines 29 kB view raw
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_14, 39 darwinMinVersionHook, 40}: 41 42let 43 apple-sdk_swift = apple-sdk_14; # 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 clangForWrappers = clang.override (prev: { 115 extraBuildCommands = 116 prev.extraBuildCommands 117 # We need to use the resource directory corresponding to Swift’s 118 # version of Clang instead of passing along the one from the 119 # `cc-wrapper` flags. 120 + '' 121 substituteInPlace $out/nix-support/cc-cflags \ 122 --replace-fail " -resource-dir=$out/resource-root" "" 123 ''; 124 }); 125 126 # Build a tool used during the build to create a custom clang wrapper, with 127 # which we wrap the clang produced by the swift build. 128 # 129 # This is used in a `POST_BUILD` for the CMake target, so we rename the 130 # actual clang to clang-unwrapped, then put the wrapper in place. 131 # 132 # We replace the `exec ...` command with `exec -a "$0"` in order to 133 # preserve $0 for clang. This is because, unlike Nix, we don't have 134 # separate wrappers for clang/clang++, and clang uses $0 to detect C++. 135 # 136 # Similarly, the C++ detection in the wrapper itself also won't work for us, 137 # so we base it on $0 as well. 138 makeClangWrapper = writeShellScriptBin "nix-swift-make-clang-wrapper" '' 139 set -euo pipefail 140 141 targetFile="$1" 142 unwrappedClang="$targetFile-unwrapped" 143 144 mv "$targetFile" "$unwrappedClang" 145 sed < '${clangForWrappers}/bin/clang' > "$targetFile" \ 146 -e 's|^\s*exec|exec -a "$0"|g' \ 147 -e 's|^\[\[ "${clang.cc}/bin/clang" = \*++ ]]|[[ "$0" = *++ ]]|' \ 148 -e "s|${clang.cc}/bin/clang|$unwrappedClang|g" \ 149 -e "s|^\(\s*\)\($unwrappedClang\) \"@\\\$responseFile\"|\1argv0=\$0\n\1${bash}/bin/bash -c \"exec -a '\$argv0' \2 '@\$responseFile'\"|" \ 150 ${lib.optionalString (clang.libcxx != null) '' 151 -e 's|$NIX_CXXSTDLIB_COMPILE_${clang.suffixSalt}|-isystem '$SWIFT_BUILD_ROOT'/libcxx/include/c++/v1|g' 152 ''} 153 chmod a+x "$targetFile" 154 ''; 155 156 # Create a tool used during the build to create a custom swift wrapper for 157 # each of the swift executables produced by the build. 158 # 159 # The build produces several `swift-frontend` executables during 160 # bootstrapping. Each of these has numerous aliases via symlinks, and the 161 # executable uses $0 to detect what tool is called. 162 wrapperParams = { 163 inherit bintools; 164 coreutils_bin = lib.getBin coreutils; 165 gnugrep_bin = gnugrep; 166 suffixSalt = lib.replaceStrings [ "-" "." ] [ "_" "_" ] targetPlatform.config; 167 use_response_file_by_default = 1; 168 swiftDriver = ""; 169 # NOTE: @cc_wrapper@ and @prog@ need to be filled elsewhere. 170 }; 171 swiftWrapper = runCommand "swift-wrapper.sh" wrapperParams '' 172 # Make empty to avoid adding the SDKs modules in the bootstrap wrapper. Otherwise, the SDK conflicts with the 173 # shims the wrapper tries to build. 174 darwinMinVersion="" substituteAll '${../wrapper/wrapper.sh}' "$out" 175 ''; 176 makeSwiftcWrapper = writeShellScriptBin "nix-swift-make-swift-wrapper" '' 177 set -euo pipefail 178 179 targetFile="$1" 180 unwrappedSwift="$targetFile-unwrapped" 181 182 mv "$targetFile" "$unwrappedSwift" 183 sed < '${swiftWrapper}' > "$targetFile" \ 184 -e "s|@prog@|'$unwrappedSwift'|g" \ 185 -e 's|@cc_wrapper@|${clangForWrappers}|g' \ 186 -e 's|exec "$prog"|exec -a "$0" "$prog"|g' \ 187 ${lib.optionalString (clang.libcxx != null) '' 188 -e 's|$NIX_CXXSTDLIB_COMPILE_${clang.suffixSalt}|-isystem '$SWIFT_BUILD_ROOT'/libcxx/include/c++/v1|g' 189 ''} 190 chmod a+x "$targetFile" 191 ''; 192 193 # On Darwin, we need to use BOOTSTRAPPING-WITH-HOSTLIBS because of ABI 194 # stability, and have to provide the definitions for the system stdlib. 195 appleSwiftCore = stdenv.mkDerivation { 196 name = "apple-swift-core"; 197 dontUnpack = true; 198 199 buildInputs = [ apple-sdk_swift ]; 200 201 installPhase = '' 202 mkdir -p $out/lib/swift 203 cp -r \ 204 "$SDKROOT/usr/lib/swift/Swift.swiftmodule" \ 205 "$SDKROOT/usr/lib/swift/CoreFoundation.swiftmodule" \ 206 "$SDKROOT/usr/lib/swift/Dispatch.swiftmodule" \ 207 "$SDKROOT/usr/lib/swift/ObjectiveC.swiftmodule" \ 208 "$SDKROOT/usr/lib/swift/libswiftCore.tbd" \ 209 "$SDKROOT/usr/lib/swift/libswiftCoreFoundation.tbd" \ 210 "$SDKROOT/usr/lib/swift/libswiftDispatch.tbd" \ 211 "$SDKROOT/usr/lib/swift/libswiftFoundation.tbd" \ 212 "$SDKROOT/usr/lib/swift/libswiftObjectiveC.tbd" \ 213 $out/lib/swift/ 214 ''; 215 }; 216 217 # https://github.com/NixOS/nixpkgs/issues/327836 218 # Fail to build with ninja 1.12 when NIX_BUILD_CORES is low (Hydra or Github Actions). 219 # Can reproduce using `nix --option cores 2 build -f . swiftPackages.swift-unwrapped`. 220 # Until we find out the exact cause, follow [swift upstream][1], pin ninja to version 221 # 1.11.1. 222 # [1]: https://github.com/swiftlang/swift/pull/72989 223 ninja = ninja_1_11; 224 225in 226stdenv.mkDerivation { 227 pname = "swift"; 228 inherit (sources) version; 229 230 outputs = [ 231 "out" 232 "lib" 233 "dev" 234 "doc" 235 "man" 236 ]; 237 238 nativeBuildInputs = [ 239 cmake 240 git 241 ninja 242 perl # pod2man 243 pkg-config 244 python3 245 makeWrapper 246 makeClangWrapper 247 makeSwiftcWrapper 248 ] 249 ++ lib.optionals stdenv.hostPlatform.isDarwin [ 250 xcbuild 251 sigtool # codesign 252 DarwinTools # sw_vers 253 fixDarwinDylibNames 254 cctools.libtool 255 ]; 256 257 buildInputs = [ 258 # For lldb 259 python3 260 swig 261 libxml2 262 ] 263 ++ lib.optionals stdenv.hostPlatform.isLinux [ 264 libuuid 265 ] 266 ++ lib.optionals stdenv.hostPlatform.isDarwin [ 267 apple-sdk_swift 268 ]; 269 270 # Will effectively be `buildInputs` when swift is put in `nativeBuildInputs`. 271 depsTargetTargetPropagated = lib.optionals stdenv.targetPlatform.isDarwin [ 272 apple-sdk_swift 273 ]; 274 275 # This is a partial reimplementation of our setup hook. Because we reuse 276 # the Swift wrapper for the Swift build itself, we need to do some of the 277 # same preparation. 278 postHook = '' 279 for pkg in "''${pkgsHostTarget[@]}" '${clang.libc}'; do 280 for subdir in ${swiftModuleSubdir} ${swiftStaticModuleSubdir} lib/swift; do 281 if [[ -d "$pkg/$subdir" ]]; then 282 export NIX_SWIFTFLAGS_COMPILE+=" -I $pkg/$subdir" 283 fi 284 done 285 for subdir in ${swiftLibSubdir} ${swiftStaticLibSubdir} lib/swift; do 286 if [[ -d "$pkg/$subdir" ]]; then 287 export NIX_LDFLAGS+=" -L $pkg/$subdir" 288 fi 289 done 290 done 291 ''; 292 293 # We setup custom build directories. 294 dontUseCmakeBuildDir = true; 295 296 unpackPhase = 297 let 298 copySource = repo: "cp -r ${sources.${repo}} ${repo}"; 299 in 300 '' 301 mkdir src 302 cd src 303 304 ${copySource "swift-cmark"} 305 ${copySource "llvm-project"} 306 ${copySource "swift"} 307 ${copySource "swift-experimental-string-processing"} 308 ${copySource "swift-syntax"} 309 ${lib.optionalString (!stdenv.hostPlatform.isDarwin) (copySource "swift-corelibs-libdispatch")} 310 311 chmod -R u+w . 312 ''; 313 314 patchPhase = '' 315 # Just patch all the things for now, we can focus this later. 316 # TODO: eliminate use of env. 317 find -type f -print0 | xargs -0 sed -i \ 318 ${lib.optionalString stdenv.hostPlatform.isDarwin "-e 's|/usr/libexec/PlistBuddy|${xcbuild}/bin/PlistBuddy|g'"} \ 319 -e 's|/usr/bin/env|${coreutils}/bin/env|g' \ 320 -e 's|/usr/bin/make|${gnumake}/bin/make|g' \ 321 -e 's|/bin/mkdir|${coreutils}/bin/mkdir|g' \ 322 -e 's|/bin/cp|${coreutils}/bin/cp|g' \ 323 -e 's|/usr/bin/file|${file}/bin/file|g' 324 325 patch -p1 -d swift -i ${./patches/swift-wrap.patch} 326 patch -p1 -d swift -i ${./patches/swift-linux-fix-libc-paths.patch} 327 patch -p1 -d swift -i ${ 328 replaceVars ./patches/swift-linux-fix-linking.patch { 329 inherit clang; 330 } 331 } 332 patch -p1 -d swift -i ${ 333 replaceVars ./patches/swift-darwin-plistbuddy-workaround.patch { 334 inherit swiftArch; 335 } 336 } 337 patch -p1 -d swift -i ${ 338 replaceVars ./patches/swift-prevent-sdk-dirs-warning.patch { 339 inherit (builtins) storeDir; 340 } 341 } 342 patch -p1 -d swift -i ${./patches/swift-Frontend-Fix-a-small-unique_ptr-array-access.patch} 343 344 # This patch needs to know the lib output location, so must be substituted 345 # in the same derivation as the compiler. 346 storeDir="${builtins.storeDir}" \ 347 substituteAll ${./patches/swift-separate-lib.patch} $TMPDIR/swift-separate-lib.patch 348 patch -p1 -d swift -i $TMPDIR/swift-separate-lib.patch 349 350 patch -p1 -d llvm-project/llvm -i ${./patches/llvm-module-cache.patch} 351 352 for lldbPatch in ${ 353 lib.escapeShellArgs [ 354 # Fix the build with modern libc++. 355 (fetchpatch { 356 name = "add-cstdio.patch"; 357 url = "https://github.com/llvm/llvm-project/commit/73e15b5edb4fa4a77e68c299a6e3b21e610d351f.patch"; 358 stripLen = 1; 359 hash = "sha256-eFcvxZaAuBsY/bda1h9212QevrXyvCHw8Cr9ngetDr0="; 360 }) 361 (fetchpatch { 362 url = "https://github.com/llvm/llvm-project/commit/68744ffbdd7daac41da274eef9ac0d191e11c16d.patch"; 363 stripLen = 1; 364 hash = "sha256-QCGhsL/mi7610ZNb5SqxjRGjwJeK2rwtsFVGeG3PUGc="; 365 }) 366 ] 367 }; do 368 patch -p1 -d llvm-project/lldb -i $lldbPatch 369 done 370 371 patch -p1 -d llvm-project/clang -i ${./patches/clang-toolchain-dir.patch} 372 patch -p1 -d llvm-project/clang -i ${./patches/clang-wrap.patch} 373 patch -p1 -d llvm-project/clang -i ${./patches/clang-purity.patch} 374 375 patch -p1 -d llvm-project/cmake -i ${ 376 fetchpatch2 { 377 name = "cmake-fix.patch"; 378 url = "https://github.com/llvm/llvm-project/commit/3676a86a4322e8c2b9c541f057b5d3704146b8f3.patch?full_index=1"; 379 stripLen = 1; 380 hash = "sha256-zP9dQOmWs7qrxkBRj70DyQBbRjH78B6tNJVy6ilA1xM="; 381 } 382 } 383 384 ${lib.optionalString stdenv.hostPlatform.isLinux '' 385 substituteInPlace llvm-project/clang/lib/Driver/ToolChains/Linux.cpp \ 386 --replace-fail 'LibDir = "lib";' 'LibDir = "${glibc}/lib";' \ 387 --replace-fail 'LibDir = "lib64";' 'LibDir = "${glibc}/lib";' \ 388 --replace-fail '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 patch -p1 -d swift-corelibs-libdispatch -i ${ 423 # Fix the build with modern Clang. 424 fetchpatch { 425 url = "https://github.com/swiftlang/swift-corelibs-libdispatch/commit/30bb8019ba79cdae0eb1dc0c967c17996dd5cc0a.patch"; 426 hash = "sha256-wPZQ4wtEWk8HaKMfzjamlU6p/IW5EFiTssY63rGM+ZA="; 427 } 428 } 429 patch -p1 -d swift-corelibs-libdispatch -i ${ 430 # Fix the build with modern Clang. 431 fetchpatch { 432 url = "https://github.com/swiftlang/swift-corelibs-libdispatch/commit/38872e2d44d66d2fb94186988509defc734888a5.patch"; 433 hash = "sha256-GABwDeTjciV36Sa0FS10mCfFCqRoBBstgW/OiKdPahA="; 434 } 435 } 436 ''} 437 ''; 438 439 # > clang-15-unwrapped: error: unsupported option '-fzero-call-used-regs=used-gpr' for target 'arm64-apple-macosx10.9.0' 440 # > clang-15-unwrapped: error: argument unused during compilation: '-fstack-clash-protection' [-Werror,-Wunused-command-line-argument] 441 hardeningDisable = lib.optionals stdenv.hostPlatform.isAarch64 [ 442 "zerocallusedregs" 443 "stackclashprotection" 444 ]; 445 446 configurePhase = '' 447 export SWIFT_SOURCE_ROOT="$PWD" 448 mkdir -p ../build 449 cd ../build 450 export SWIFT_BUILD_ROOT="$PWD" 451 ''; 452 453 # These steps are derived from doing a normal build with. 454 # 455 # ./swift/utils/build-toolchain test --dry-run 456 # 457 # But dealing with the custom Python build system is far more trouble than 458 # simply invoking CMake directly. Few variables it passes to CMake are 459 # actually required or non-default. 460 # 461 # Using CMake directly also allows us to split up the already large build, 462 # and package Swift components separately. 463 # 464 # Besides `--dry-run`, another good way to compare build changes between 465 # Swift releases is to diff the scripts: 466 # 467 # git diff swift-5.6.3-RELEASE..swift-5.7-RELEASE -- utils/build* 468 # 469 buildPhase = '' 470 # Helper to build a subdirectory. 471 # 472 # Always reset cmakeFlags before calling this. The cmakeConfigurePhase 473 # amends flags and would otherwise keep expanding it. 474 function buildProject() { 475 mkdir -p $SWIFT_BUILD_ROOT/$1 476 cd $SWIFT_BUILD_ROOT/$1 477 478 cmakeDir=$SWIFT_SOURCE_ROOT/''${2-$1} 479 cmakeConfigurePhase 480 481 ninjaBuildPhase 482 } 483 484 cmakeFlags="-GNinja" 485 buildProject swift-cmark 486 487 ${lib.optionalString (clang.libcxx != null) '' 488 # Install the libc++ headers corresponding to the LLVM version of 489 # Swifts Clang. 490 cmakeFlags=" 491 -GNinja 492 -DLLVM_ENABLE_RUNTIMES=libcxx;libcxxabi 493 -DLIBCXXABI_INSTALL_INCLUDE_DIR=$dev/include/c++/v1 494 " 495 ninjaFlags="install-cxx-headers install-cxxabi-headers" 496 buildProject libcxx llvm-project/runtimes 497 unset ninjaFlags 498 ''} 499 500 # Some notes: 501 # - The Swift build just needs Clang. 502 # - We can further reduce targets to just our targetPlatform. 503 cmakeFlags=" 504 -GNinja 505 -DLLVM_BUILD_TOOLS=NO 506 -DLLVM_ENABLE_PROJECTS=clang 507 -DLLVM_TARGETS_TO_BUILD=${ 508 { 509 "x86_64" = "X86"; 510 "aarch64" = "AArch64"; 511 } 512 .${targetPlatform.parsed.cpu.name} 513 or (throw "Unsupported CPU architecture: ${targetPlatform.parsed.cpu.name}") 514 } 515 " 516 buildProject llvm llvm-project/llvm 517 518 # Ensure that the built Clang can find the runtime libraries by 519 # copying the symlinks from the main wrapper. 520 cp -P ${clang}/resource-root/{lib,share} $SWIFT_BUILD_ROOT/llvm/lib/clang/16.0.0/ 521 522 '' 523 + lib.optionalString stdenv.hostPlatform.isDarwin '' 524 # Add appleSwiftCore to the search paths. Adding the whole SDK results in build failures. 525 OLD_NIX_SWIFTFLAGS_COMPILE="$NIX_SWIFTFLAGS_COMPILE" 526 OLD_NIX_LDFLAGS="$NIX_LDFLAGS" 527 OLD_NIX_CFLAGS_COMPILE="$NIX_CFLAGS_COMPILE" 528 export NIX_SWIFTFLAGS_COMPILE=" -I ${appleSwiftCore}/lib/swift" 529 export NIX_LDFLAGS+=" -L ${appleSwiftCore}/lib/swift" 530 export NIX_CFLAGS_COMPILE+=" -Wno-error=unguarded-availability" 531 '' 532 + '' 533 534 # Some notes: 535 # - BOOTSTRAPPING_MODE defaults to OFF in CMake, but is enabled in standard 536 # builds, so we enable it as well. On Darwin, we have to use the system 537 # Swift libs because of ABI-stability, but this may be trouble if the 538 # builder is an older macOS. 539 # - Experimental features are OFF by default in CMake, but are enabled in 540 # official builds, so we do the same. (Concurrency is also required in 541 # the stdlib. StringProcessing is often implicitely imported, causing 542 # lots of warnings if missing.) 543 # - SWIFT_STDLIB_ENABLE_OBJC_INTEROP is set explicitely because its check 544 # is buggy. (Uses SWIFT_HOST_VARIANT_SDK before initialized.) 545 # Fixed in: https://github.com/apple/swift/commit/84083afef1de5931904d5c815d53856cdb3fb232 546 cmakeFlags=" 547 -GNinja 548 -DBOOTSTRAPPING_MODE=BOOTSTRAPPING${lib.optionalString stdenv.hostPlatform.isDarwin "-WITH-HOSTLIBS"} 549 -DSWIFT_ENABLE_EXPERIMENTAL_DIFFERENTIABLE_PROGRAMMING=ON 550 -DSWIFT_ENABLE_EXPERIMENTAL_CONCURRENCY=ON 551 -DSWIFT_ENABLE_EXPERIMENTAL_CXX_INTEROP=ON 552 -DSWIFT_ENABLE_EXPERIMENTAL_DISTRIBUTED=ON 553 -DSWIFT_ENABLE_EXPERIMENTAL_STRING_PROCESSING=ON 554 -DSWIFT_ENABLE_BACKTRACING=ON 555 -DSWIFT_ENABLE_EXPERIMENTAL_OBSERVATION=ON 556 -DLLVM_DIR=$SWIFT_BUILD_ROOT/llvm/lib/cmake/llvm 557 -DClang_DIR=$SWIFT_BUILD_ROOT/llvm/lib/cmake/clang 558 -DSWIFT_PATH_TO_CMARK_SOURCE=$SWIFT_SOURCE_ROOT/swift-cmark 559 -DSWIFT_PATH_TO_CMARK_BUILD=$SWIFT_BUILD_ROOT/swift-cmark 560 -DSWIFT_PATH_TO_LIBDISPATCH_SOURCE=$SWIFT_SOURCE_ROOT/swift-corelibs-libdispatch 561 -DSWIFT_PATH_TO_SWIFT_SYNTAX_SOURCE=$SWIFT_SOURCE_ROOT/swift-syntax 562 -DSWIFT_PATH_TO_STRING_PROCESSING_SOURCE=$SWIFT_SOURCE_ROOT/swift-experimental-string-processing 563 -DSWIFT_INSTALL_COMPONENTS=${lib.concatStringsSep ";" swiftInstallComponents} 564 -DSWIFT_STDLIB_ENABLE_OBJC_INTEROP=${if stdenv.hostPlatform.isDarwin then "ON" else "OFF"} 565 -DSWIFT_DARWIN_DEPLOYMENT_VERSION_OSX=${deploymentVersion} 566 " 567 buildProject swift 568 569 '' 570 + lib.optionalString stdenv.hostPlatform.isDarwin '' 571 # Restore search paths to remove appleSwiftCore. 572 export NIX_SWIFTFLAGS_COMPILE="$OLD_NIX_SWIFTFLAGS_COMPILE" 573 export NIX_LDFLAGS="$OLD_NIX_LDFLAGS" 574 export NIX_CFLAGS_COMPILE="$OLD_NIX_CFLAGS_COMPILE" 575 '' 576 + '' 577 578 # These are based on flags in `utils/build-script-impl`. 579 # 580 # LLDB_USE_SYSTEM_DEBUGSERVER=ON disables the debugserver build on Darwin, 581 # which requires a special signature. 582 # 583 # CMAKE_BUILD_WITH_INSTALL_NAME_DIR ensures we don't use rpath on Darwin. 584 cmakeFlags=" 585 -GNinja 586 -DLLDB_SWIFTC=$SWIFT_BUILD_ROOT/swift/bin/swiftc 587 -DLLDB_SWIFT_LIBS=$SWIFT_BUILD_ROOT/swift/lib/swift 588 -DLLVM_DIR=$SWIFT_BUILD_ROOT/llvm/lib/cmake/llvm 589 -DClang_DIR=$SWIFT_BUILD_ROOT/llvm/lib/cmake/clang 590 -DSwift_DIR=$SWIFT_BUILD_ROOT/swift/lib/cmake/swift 591 -DLLDB_ENABLE_CURSES=ON 592 -DLLDB_ENABLE_LIBEDIT=ON 593 -DLLDB_ENABLE_PYTHON=ON 594 -DLLDB_ENABLE_LZMA=OFF 595 -DLLDB_ENABLE_LUA=OFF 596 -DLLDB_INCLUDE_TESTS=OFF 597 -DCMAKE_BUILD_WITH_INSTALL_NAME_DIR=ON 598 ${lib.optionalString stdenv.hostPlatform.isDarwin '' 599 -DLLDB_USE_SYSTEM_DEBUGSERVER=ON 600 ''} 601 -DLibEdit_INCLUDE_DIRS=${lib.getInclude libedit}/include 602 -DLibEdit_LIBRARIES=${lib.getLib libedit}/lib/libedit${stdenv.hostPlatform.extensions.sharedLibrary} 603 -DCURSES_INCLUDE_DIRS=${lib.getInclude ncurses}/include 604 -DCURSES_LIBRARIES=${lib.getLib ncurses}/lib/libncurses${stdenv.hostPlatform.extensions.sharedLibrary} 605 -DPANEL_LIBRARIES=${lib.getLib ncurses}/lib/libpanel${stdenv.hostPlatform.extensions.sharedLibrary} 606 "; 607 buildProject lldb llvm-project/lldb 608 609 ${lib.optionalString stdenv.targetPlatform.isDarwin '' 610 # Need to do a standalone build of concurrency for Darwin back deployment. 611 # Based on: utils/swift_build_support/swift_build_support/products/backdeployconcurrency.py 612 cmakeFlags=" 613 -GNinja 614 -DCMAKE_Swift_COMPILER=$SWIFT_BUILD_ROOT/swift/bin/swiftc 615 -DSWIFT_PATH_TO_SWIFT_SYNTAX_SOURCE=$SWIFT_SOURCE_ROOT/swift-syntax 616 617 -DTOOLCHAIN_DIR=/var/empty 618 -DSWIFT_NATIVE_LLVM_TOOLS_PATH=${stdenv.cc}/bin 619 -DSWIFT_NATIVE_CLANG_TOOLS_PATH=${stdenv.cc}/bin 620 -DSWIFT_NATIVE_SWIFT_TOOLS_PATH=$SWIFT_BUILD_ROOT/swift/bin 621 622 -DCMAKE_CROSSCOMPILING=ON 623 624 -DBUILD_SWIFT_CONCURRENCY_BACK_DEPLOYMENT_LIBRARIES=ON 625 -DSWIFT_INCLUDE_TOOLS=OFF 626 -DSWIFT_BUILD_STDLIB_EXTRA_TOOLCHAIN_CONTENT=OFF 627 -DSWIFT_BUILD_TEST_SUPPORT_MODULES=OFF 628 -DSWIFT_BUILD_STDLIB=OFF 629 -DSWIFT_BUILD_DYNAMIC_STDLIB=OFF 630 -DSWIFT_BUILD_STATIC_STDLIB=OFF 631 -DSWIFT_BUILD_REMOTE_MIRROR=OFF 632 -DSWIFT_BUILD_SDK_OVERLAY=OFF 633 -DSWIFT_BUILD_DYNAMIC_SDK_OVERLAY=OFF 634 -DSWIFT_BUILD_STATIC_SDK_OVERLAY=OFF 635 -DSWIFT_INCLUDE_TESTS=OFF 636 -DSWIFT_BUILD_PERF_TESTSUITE=OFF 637 638 -DSWIFT_HOST_VARIANT_ARCH=${swiftArch} 639 -DBUILD_STANDALONE=ON 640 641 -DSWIFT_INSTALL_COMPONENTS=back-deployment 642 643 -DSWIFT_SDKS=${ 644 { 645 "macos" = "OSX"; 646 "ios" = "IOS"; 647 #IOS_SIMULATOR 648 #TVOS 649 #TVOS_SIMULATOR 650 #WATCHOS 651 #WATCHOS_SIMULATOR 652 } 653 .${targetPlatform.darwinPlatform} 654 } 655 656 -DLLVM_DIR=$SWIFT_BUILD_ROOT/llvm/lib/cmake/llvm 657 658 -DSWIFT_DEST_ROOT=$out 659 -DSWIFT_HOST_VARIANT_SDK=OSX 660 661 -DSWIFT_DARWIN_DEPLOYMENT_VERSION_OSX=${deploymentVersion} 662 -DSWIFT_DARWIN_DEPLOYMENT_VERSION_IOS=13.0 663 -DSWIFT_DARWIN_DEPLOYMENT_VERSION_MACCATALYST=13.0 664 -DSWIFT_DARWIN_DEPLOYMENT_VERSION_TVOS=13.0 665 -DSWIFT_DARWIN_DEPLOYMENT_VERSION_WATCHOS=6.0 666 " 667 668 # This depends on the special Clang build specific to the Swift branch. 669 # We also need to call a specific Ninja target. 670 export CC=$SWIFT_BUILD_ROOT/llvm/bin/clang 671 export CXX=$SWIFT_BUILD_ROOT/llvm/bin/clang++ 672 ninjaFlags="back-deployment" 673 674 buildProject swift-concurrency-backdeploy swift 675 676 export CC=$NIX_CC/bin/clang 677 export CXX=$NIX_CC/bin/clang++ 678 unset ninjaFlags 679 ''} 680 ''; 681 682 # TODO: ~50 failing tests on x86_64-linux. Other platforms not checked. 683 doCheck = false; 684 nativeCheckInputs = [ file ]; 685 # TODO: consider using stress-tester and integration-test. 686 checkPhase = '' 687 cd $SWIFT_BUILD_ROOT/swift 688 checkTarget=check-swift-all 689 ninjaCheckPhase 690 unset checkTarget 691 ''; 692 693 installPhase = '' 694 # Undo the clang and swift wrapping we did for the build. 695 # (This happened via patches to cmake files.) 696 cd $SWIFT_BUILD_ROOT 697 mv llvm/bin/clang-16{-unwrapped,} 698 mv swift/bin/swift-frontend{-unwrapped,} 699 700 mkdir $lib 701 702 # Install clang binaries only. We hide these with the wrapper, so they are 703 # for private use by Swift only. 704 cd $SWIFT_BUILD_ROOT/llvm 705 installTargets=install-clang 706 ninjaInstallPhase 707 unset installTargets 708 709 # LLDB is also a private install. 710 cd $SWIFT_BUILD_ROOT/lldb 711 ninjaInstallPhase 712 713 cd $SWIFT_BUILD_ROOT/swift 714 ninjaInstallPhase 715 716 ${lib.optionalString stdenv.hostPlatform.isDarwin '' 717 cd $SWIFT_BUILD_ROOT/swift-concurrency-backdeploy 718 installTargets=install-back-deployment 719 ninjaInstallPhase 720 unset installTargets 721 ''} 722 723 # Separate $lib output here, because specific logic follows. 724 # Only move the dynamic run-time parts, to keep $lib small. Every Swift 725 # build will depend on it. 726 moveToOutput "lib/swift" "$lib" 727 moveToOutput "lib/libswiftDemangle.*" "$lib" 728 729 # This link is here because various tools (swiftpm) check for stdlib 730 # relative to the swift compiler. It's fine if this is for build-time 731 # stuff, but we should patch all cases were it would end up in an output. 732 ln -s $lib/lib/swift $out/lib/swift 733 734 # Swift has a separate resource root from Clang, but locates the Clang 735 # resource root via subdir or symlink. 736 mv $SWIFT_BUILD_ROOT/llvm/lib/clang/16.0.0 $lib/lib/swift/clang 737 ''; 738 739 preFixup = lib.optionalString stdenv.hostPlatform.isLinux '' 740 # This is cheesy, but helps the patchelf hook remove /build from RPATH. 741 cd $SWIFT_BUILD_ROOT/.. 742 mv build buildx 743 ''; 744 745 postFixup = lib.optionalString stdenv.hostPlatform.isDarwin '' 746 # These libraries need to use the system install name. The official SDK 747 # does the same (as opposed to using rpath). Presumably, they are part of 748 # the stable ABI. Not using the system libraries at run-time is known to 749 # cause ObjC class conflicts and segfaults. 750 declare -A systemLibs=( 751 [libswiftCore.dylib]=1 752 [libswiftDarwin.dylib]=1 753 [libswiftSwiftOnoneSupport.dylib]=1 754 [libswift_Concurrency.dylib]=1 755 ) 756 757 for systemLib in "''${!systemLibs[@]}"; do 758 install_name_tool -id /usr/lib/swift/$systemLib $lib/${swiftLibSubdir}/$systemLib 759 done 760 761 for file in $out/bin/swift-frontend $lib/${swiftLibSubdir}/*.dylib; do 762 changeArgs="" 763 for dylib in $(otool -L $file | awk '{ print $1 }'); do 764 if [[ ''${systemLibs["$(basename $dylib)"]} ]]; then 765 changeArgs+=" -change $dylib /usr/lib/swift/$(basename $dylib)" 766 elif [[ "$dylib" = */bootstrapping1/* ]]; then 767 changeArgs+=" -change $dylib $lib/lib/swift/$(basename $dylib)" 768 fi 769 done 770 if [[ -n "$changeArgs" ]]; then 771 install_name_tool $changeArgs $file 772 fi 773 done 774 775 wrapProgram $out/bin/swift-frontend \ 776 --prefix PATH : ${lib.makeBinPath [ cctools.libtool ]} 777 778 # Needs to be propagated by the compiler not by its dev output. 779 moveToOutput nix-support/propagated-target-target-deps "$out" 780 ''; 781 782 passthru = { 783 inherit 784 swiftOs 785 swiftArch 786 swiftModuleSubdir 787 swiftLibSubdir 788 swiftStaticModuleSubdir 789 swiftStaticLibSubdir 790 ; 791 792 tests = { 793 cxx-interop-test = callPackage ../cxx-interop-test { }; 794 }; 795 796 # Internal attr for the wrapper. 797 _wrapperParams = wrapperParams; 798 }; 799 800 meta = { 801 description = "Swift Programming Language"; 802 homepage = "https://github.com/apple/swift"; 803 teams = [ lib.teams.swift ]; 804 license = lib.licenses.asl20; 805 platforms = with lib.platforms; linux ++ darwin; 806 # Swift doesn't support 32-bit Linux, unknown on other platforms. 807 badPlatforms = lib.platforms.i686; 808 timeout = 86400; # 24 hours. 809 }; 810}