nixpkgs mirror (for testing) github.com/NixOS/nixpkgs
nix
at python-updates 500 lines 16 kB view raw
1{ 2 lib, 3 stdenv, 4 callPackage, 5 fetchFromGitHub, 6 cmake, 7 ninja, 8 git, 9 swift, 10 swiftpm2nix, 11 Foundation, 12 XCTest, 13 pkg-config, 14 sqlite, 15 ncurses, 16 replaceVars, 17 runCommandLocal, 18 makeWrapper, 19 DarwinTools, # sw_vers 20 cctools, # vtool 21 xcbuild, 22}: 23 24let 25 26 inherit (swift) 27 swiftOs 28 swiftModuleSubdir 29 swiftStaticModuleSubdir 30 ; 31 sharedLibraryExt = stdenv.hostPlatform.extensions.sharedLibrary; 32 33 sources = callPackage ../sources.nix { }; 34 generated = swiftpm2nix.helpers ./generated; 35 cmakeGlue = callPackage ./cmake-glue.nix { }; 36 37 # Common attributes for the bootstrap swiftpm and the final swiftpm. 38 commonAttrs = { 39 inherit (sources) version; 40 src = sources.swift-package-manager; 41 nativeBuildInputs = [ makeWrapper ]; 42 # Required at run-time for the host platform to build package manifests. 43 propagatedBuildInputs = [ Foundation ]; 44 patches = [ 45 ./patches/cmake-disable-rpath.patch 46 ./patches/disable-index-store.patch 47 ./patches/disable-sandbox.patch 48 ./patches/disable-xctest.patch 49 ./patches/fix-clang-cxx.patch 50 ./patches/nix-pkgconfig-vars.patch 51 (replaceVars ./patches/fix-stdlib-path.patch { 52 inherit (builtins) storeDir; 53 swiftLib = swift.swift.lib; 54 }) 55 ]; 56 postPatch = '' 57 # The location of xcrun is hardcoded. We need PATH lookup instead. 58 find Sources -name '*.swift' | xargs sed -i -e 's|/usr/bin/xcrun|xcrun|g' 59 60 # Patch the location where swiftpm looks for its API modules. 61 substituteInPlace Sources/PackageModel/UserToolchain.swift \ 62 --replace-fail \ 63 'librariesPath = applicationPath.parentDirectory' \ 64 "librariesPath = try AbsolutePath(validating: \"$out\")" 65 ''; 66 }; 67 68 # Tools invoked by swiftpm at run-time. 69 runtimeDeps = [ 70 git 71 ] 72 ++ lib.optionals stdenv.hostPlatform.isDarwin [ 73 xcbuild.xcrun 74 # These tools are part of cctools, but adding that as a build input puts 75 # an unwrapped linker in PATH, and breaks builds. This small derivation 76 # exposes just the tools we need: 77 # - vtool is used to determine a minimum deployment target. 78 # - libtool is used to build static libraries. 79 (runCommandLocal "swiftpm-cctools" { } '' 80 mkdir -p $out/bin 81 ln -s ${cctools}/bin/vtool $out/bin/vtool 82 ln -s ${cctools}/bin/libtool $out/bin/libtool 83 '') 84 ]; 85 86 # Common attributes for the bootstrap derivations. 87 mkBootstrapDerivation = 88 attrs: 89 stdenv.mkDerivation ( 90 attrs 91 // { 92 nativeBuildInputs = 93 (attrs.nativeBuildInputs or [ ]) 94 ++ [ 95 cmake 96 ninja 97 swift 98 ] 99 ++ lib.optionals stdenv.hostPlatform.isDarwin [ DarwinTools ]; 100 101 buildInputs = (attrs.buildInputs or [ ]) ++ [ Foundation ]; 102 103 postPatch = 104 (attrs.postPatch or "") 105 + lib.optionalString stdenv.hostPlatform.isDarwin '' 106 # On Darwin only, Swift uses arm64 as cpu arch. 107 if [ -e cmake/modules/SwiftSupport.cmake ]; then 108 # At least in swift-asn1, this has been removed and the module uses the full target triple as the name 109 # (https://github.com/apple/swift-asn1/pull/103) 110 substituteInPlace cmake/modules/SwiftSupport.cmake \ 111 --replace '"aarch64" PARENT_SCOPE' '"arm64" PARENT_SCOPE' 112 fi 113 ''; 114 115 postInstall = 116 (attrs.postInstall or "") 117 + lib.optionalString stdenv.hostPlatform.isDarwin '' 118 # The install name of libraries is incorrectly set to lib/ (via our 119 # CMake setup hook) instead of lib/swift/. This'd be easily fixed by 120 # fixDarwinDylibNames, but some builds create libraries that reference 121 # eachother, and we also have to fix those references. 122 dylibs="$(find $out/lib/swift* -name '*.dylib')" 123 changes="" 124 for dylib in $dylibs; do 125 changes+=" -change $(otool -D $dylib | tail -n 1) $dylib" 126 done 127 for dylib in $dylibs; do 128 install_name_tool -id $dylib $changes $dylib 129 done 130 ''; 131 132 cmakeFlags = (attrs.cmakeFlags or [ ]) ++ [ 133 # Some builds link to libraries within the same build. Make sure these 134 # create references to $out. None of our builds run their own products, 135 # so we don't have to account for that scenario. 136 "-DCMAKE_BUILD_WITH_INSTALL_NAME_DIR=ON" 137 ]; 138 } 139 ); 140 141 # On Darwin, we only want ncurses in the linker search path, because headers 142 # are part of libsystem. Adding its headers to the search path causes strange 143 # mixing and errors. 144 # TODO: Find a better way to prevent this conflict. 145 ncursesInput = if stdenv.hostPlatform.isDarwin then ncurses.out else ncurses; 146 147 # Derivations for bootstrapping dependencies using CMake. 148 # This is based on the `swiftpm/Utilities/bootstrap` script. 149 # 150 # Some of the installation steps here are a bit hacky, because it seems like 151 # these packages were not really meant to be installed using CMake. The 152 # regular swiftpm bootstrap simply refers to the source and build 153 # directories. The advantage of separate builds is that we can more easily 154 # link libs together using existing Nixpkgs infra. 155 # 156 # In the end, we don't expose these derivations, and they only exist during 157 # the bootstrap phase. The final swiftpm derivation does not depend on them. 158 159 swift-system = mkBootstrapDerivation { 160 name = "swift-system"; 161 src = generated.sources.swift-system; 162 163 postInstall = 164 cmakeGlue.SwiftSystem 165 + lib.optionalString (!stdenv.hostPlatform.isDarwin) '' 166 # The cmake rules apparently only use the Darwin install convention. 167 # Fix up the installation so the module can be found on non-Darwin. 168 mkdir -p $out/${swiftStaticModuleSubdir} 169 mv $out/lib/swift_static/${swiftOs}/*.swiftmodule $out/${swiftStaticModuleSubdir}/ 170 ''; 171 }; 172 173 swift-collections = mkBootstrapDerivation { 174 name = "swift-collections"; 175 src = generated.sources.swift-collections; 176 177 postPatch = '' 178 # Only builds static libs on Linux, but this installation difference is a 179 # hassle. Because this installation is temporary for the bootstrap, may 180 # as well build static libs everywhere. 181 sed -i -e '/BUILD_SHARED_LIBS/d' CMakeLists.txt 182 ''; 183 184 postInstall = 185 cmakeGlue.SwiftCollections 186 + lib.optionalString (!stdenv.hostPlatform.isDarwin) '' 187 # The cmake rules apparently only use the Darwin install convention. 188 # Fix up the installation so the module can be found on non-Darwin. 189 mkdir -p $out/${swiftStaticModuleSubdir} 190 mv $out/lib/swift_static/${swiftOs}/*.swiftmodule $out/${swiftStaticModuleSubdir}/ 191 ''; 192 }; 193 194 swift-tools-support-core = mkBootstrapDerivation { 195 name = "swift-tools-support-core"; 196 src = generated.sources.swift-tools-support-core; 197 198 buildInputs = [ 199 swift-system 200 sqlite 201 ]; 202 203 postInstall = cmakeGlue.TSC + '' 204 # Swift modules are not installed. 205 mkdir -p $out/${swiftModuleSubdir} 206 cp swift/*.swift{module,doc} $out/${swiftModuleSubdir}/ 207 208 # Static libs are not installed. 209 cp lib/*.a $out/lib/ 210 211 # Headers are not installed. 212 mkdir -p $out/include 213 cp -r ../Sources/TSCclibc/include $out/include/TSC 214 ''; 215 }; 216 217 swift-argument-parser = mkBootstrapDerivation { 218 name = "swift-argument-parser"; 219 src = generated.sources.swift-argument-parser; 220 221 buildInputs = [ 222 ncursesInput 223 sqlite 224 ]; 225 226 cmakeFlags = [ 227 "-DBUILD_TESTING=NO" 228 "-DBUILD_EXAMPLES=NO" 229 ]; 230 231 postInstall = 232 cmakeGlue.ArgumentParser 233 + lib.optionalString stdenv.hostPlatform.isLinux '' 234 # Fix rpath so ArgumentParserToolInfo can be found. 235 patchelf --add-rpath "$out/lib/swift/${swiftOs}" \ 236 $out/lib/swift/${swiftOs}/libArgumentParser.so 237 ''; 238 }; 239 240 Yams = mkBootstrapDerivation { 241 name = "Yams"; 242 src = generated.sources.Yams; 243 244 # Conflicts with BUILD file on case-insensitive filesystems. 245 cmakeBuildDir = "_build"; 246 247 postInstall = cmakeGlue.Yams; 248 }; 249 250 llbuild = mkBootstrapDerivation { 251 name = "llbuild"; 252 src = generated.sources.swift-llbuild; 253 254 nativeBuildInputs = lib.optional stdenv.hostPlatform.isDarwin xcbuild; 255 buildInputs = [ 256 ncursesInput 257 sqlite 258 ]; 259 260 patches = [ 261 ./patches/llbuild-cmake-disable-rpath.patch 262 ]; 263 264 postPatch = '' 265 # Substitute ncurses for curses. 266 find . -name CMakeLists.txt | xargs sed -i -e 's/curses/ncurses/' 267 268 # Use absolute install names instead of rpath. 269 substituteInPlace \ 270 products/libllbuild/CMakeLists.txt \ 271 products/llbuildSwift/CMakeLists.txt \ 272 --replace-fail '@rpath' "$out/lib" 273 274 # This subdirectory is enabled for Darwin only, but requires ObjC XCTest 275 # (and only Swift XCTest is open source). 276 substituteInPlace perftests/CMakeLists.txt \ 277 --replace-fail 'add_subdirectory(Xcode/' '#add_subdirectory(Xcode/' 278 ''; 279 280 cmakeFlags = [ 281 "-DLLBUILD_SUPPORT_BINDINGS=Swift" 282 ]; 283 284 postInstall = cmakeGlue.LLBuild + '' 285 # Install module map. 286 cp ../products/libllbuild/include/module.modulemap $out/include 287 288 # Swift modules are not installed. 289 mkdir -p $out/${swiftModuleSubdir} 290 cp products/llbuildSwift/*.swift{module,doc} $out/${swiftModuleSubdir}/ 291 ''; 292 }; 293 294 swift-driver = mkBootstrapDerivation { 295 name = "swift-driver"; 296 src = generated.sources.swift-driver; 297 298 buildInputs = [ 299 Yams 300 llbuild 301 swift-system 302 swift-argument-parser 303 swift-tools-support-core 304 ]; 305 306 postPatch = '' 307 # Tries to link against CYaml, but that's private. 308 substituteInPlace Sources/SwiftDriver/CMakeLists.txt \ 309 --replace-fail CYaml "" 310 ''; 311 312 postInstall = cmakeGlue.SwiftDriver + '' 313 # Swift modules are not installed. 314 mkdir -p $out/${swiftModuleSubdir} 315 cp swift/*.swift{module,doc} $out/${swiftModuleSubdir}/ 316 ''; 317 }; 318 319 swift-crypto = mkBootstrapDerivation { 320 name = "swift-crypto"; 321 src = fetchFromGitHub { 322 owner = "apple"; 323 repo = "swift-crypto"; 324 rev = "95ba0316a9b733e92bb6b071255ff46263bbe7dc"; # 3.15.1, as opposed to the pinned version of 3.0.0 325 sha256 = "sha256-RzoUBx4l12v0ZamSIAEpHHCRQXxJkXJCwVBEj7Qwg9I="; 326 fetchSubmodules = true; 327 }; 328 329 buildInputs = [ 330 swift-asn1 331 ]; 332 333 patches = [ 334 ./patches/install-crypto-extras.patch 335 ]; 336 337 postPatch = '' 338 # Fix use of hardcoded tool paths on Darwin. 339 substituteInPlace CMakeLists.txt \ 340 --replace-fail /usr/bin/ar $NIX_CC/bin/ar 341 substituteInPlace CMakeLists.txt \ 342 --replace-fail /usr/bin/ranlib $NIX_CC/bin/ranlib 343 ''; 344 345 postInstall = cmakeGlue.SwiftCrypto + '' 346 # Static libs are not installed. 347 cp lib/*.a $out/lib/ 348 349 # Headers are not installed. 350 cp -r ../Sources/CCryptoBoringSSL/include $out/include 351 352 # Swift modules are put in the wrong place by default (and not all are linked) 353 mkdir -p $out/${swiftModuleSubdir} 354 rm -rf $out/${swiftModuleSubdir}/*.swift{module,doc} 355 # I assume we don't care about .swiftsourceinfo 356 cp swift/*.swift{module,doc} $out/${swiftModuleSubdir}/ 357 ''; 358 }; 359 360 swift-asn1 = mkBootstrapDerivation { 361 name = "swift-asn1"; 362 src = generated.sources.swift-asn1; 363 364 postInstall = 365 cmakeGlue.SwiftASN1 366 + lib.optionalString (!stdenv.hostPlatform.isDarwin) '' 367 # SwiftASN1 uses the full target triple as the name of the swiftmodule 368 # (https://github.com/apple/swift-asn1/pull/103) 369 mkdir -p $out/${swiftModuleSubdir} 370 cp swift/*.swift{module,doc} $out/${swiftModuleSubdir}/ 371 ''; 372 }; 373 374 swift-certificates = mkBootstrapDerivation { 375 name = "swift-certificates"; 376 src = generated.sources.swift-certificates; 377 378 buildInputs = [ 379 swift-asn1 380 swift-crypto 381 ]; 382 383 postInstall = cmakeGlue.SwiftCertificates; 384 }; 385 386 # Build a bootrapping swiftpm using CMake. 387 swiftpm-bootstrap = mkBootstrapDerivation ( 388 commonAttrs 389 // { 390 pname = "swiftpm-bootstrap"; 391 392 buildInputs = [ 393 llbuild 394 sqlite 395 swift-argument-parser 396 swift-asn1 397 swift-certificates 398 swift-collections 399 swift-crypto 400 swift-driver 401 swift-system 402 swift-tools-support-core 403 ]; 404 405 cmakeFlags = [ 406 "-DUSE_CMAKE_INSTALL=ON" 407 ]; 408 409 postInstall = '' 410 for program in $out/bin/swift-*; do 411 wrapProgram $program --prefix PATH : ${lib.makeBinPath runtimeDeps} 412 done 413 ''; 414 } 415 ); 416 417in 418# Build the final swiftpm with the bootstrapping swiftpm. 419stdenv.mkDerivation ( 420 commonAttrs 421 // { 422 pname = "swiftpm"; 423 424 nativeBuildInputs = commonAttrs.nativeBuildInputs ++ [ 425 pkg-config 426 swift 427 swiftpm-bootstrap 428 ]; 429 buildInputs = [ 430 ncursesInput 431 sqlite 432 XCTest 433 ]; 434 435 configurePhase = generated.configure + '' 436 # Functionality provided by Xcode XCTest, but not available in 437 # swift-corelibs-xctest. 438 swiftpmMakeMutable swift-tools-support-core 439 substituteInPlace .build/checkouts/swift-tools-support-core/Sources/TSCTestSupport/XCTestCasePerf.swift \ 440 --replace-fail 'canImport(Darwin)' 'false' 441 442 # Prevent a warning about SDK directories we don't have. 443 swiftpmMakeMutable swift-driver 444 patch -p1 -d .build/checkouts/swift-driver -i ${ 445 replaceVars ../swift-driver/patches/prevent-sdk-dirs-warnings.patch { 446 inherit (builtins) storeDir; 447 } 448 } 449 ''; 450 451 buildPhase = '' 452 TERM=dumb swift-build -c release 453 ''; 454 455 # TODO: Tests depend on indexstore-db being provided by an existing Swift 456 # toolchain. (ie. looks for `../lib/libIndexStore.so` relative to swiftc. 457 #doCheck = true; 458 #checkPhase = '' 459 # TERM=dumb swift-test -c release 460 #''; 461 462 # The following is derived from Utilities/bootstrap, see install_swiftpm. 463 installPhase = '' 464 binPath="$(swift-build --show-bin-path -c release)" 465 466 mkdir -p $out/bin $out/lib/swift 467 468 cp $binPath/swift-package-manager $out/bin/swift-package 469 wrapProgram $out/bin/swift-package \ 470 --prefix PATH : ${lib.makeBinPath runtimeDeps} 471 for tool in swift-build swift-test swift-run swift-package-collection swift-experimental-destination; do 472 ln -s $out/bin/swift-package $out/bin/$tool 473 done 474 475 installSwiftpmModule() { 476 mkdir -p $out/lib/swift/pm/$2 477 cp $binPath/lib$1${sharedLibraryExt} $out/lib/swift/pm/$2/ 478 479 if [[ -f $binPath/$1.swiftinterface ]]; then 480 cp $binPath/$1.swiftinterface $out/lib/swift/pm/$2/ 481 else 482 cp -r $binPath/$1.swiftmodule $out/lib/swift/pm/$2/ 483 fi 484 cp $binPath/$1.swiftdoc $out/lib/swift/pm/$2/ 485 } 486 installSwiftpmModule PackageDescription ManifestAPI 487 installSwiftpmModule PackagePlugin PluginAPI 488 ''; 489 490 setupHook = ./setup-hook.sh; 491 492 meta = { 493 description = "Package Manager for the Swift Programming Language"; 494 homepage = "https://github.com/apple/swift-package-manager"; 495 platforms = with lib.platforms; linux ++ darwin; 496 license = lib.licenses.asl20; 497 teams = [ lib.teams.swift ]; 498 }; 499 } 500)