From cbda3182f1603e4b5422d8aefab154a4d85a73ac Mon Sep 17 00:00:00 2001 From: Randy Eckenrode Date: Thu, 6 Aug 2026 19:56:05 -0400 Subject: [PATCH] swiftPackages_ng.swift: init MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The Swift compiler expects to find the stdlib, its modules, etc relative to its location. Building everything together in one derivation would be a terrible idea because it would take a very long time to build and require rebuilding things unnecessarily during the bootstrap. Fortunately, we can symlink most of what Swift expects together. Collectively, the contents of this package is called a toolchain. One should think of it as similar to the toolchains offered on swift.org except that it’s bootstrapped from source and is part of Nixpkgs. --- .../swift_ng/by-name/sw/swift/package.nix | 133 ++++++++++++++++++ 1 file changed, 133 insertions(+) create mode 100644 pkgs/development/compilers/swift_ng/by-name/sw/swift/package.nix diff --git a/pkgs/development/compilers/swift_ng/by-name/sw/swift/package.nix b/pkgs/development/compilers/swift_ng/by-name/sw/swift/package.nix new file mode 100644 index 000000000000..22c6a496eae9 --- /dev/null +++ b/pkgs/development/compilers/swift_ng/by-name/sw/swift/package.nix @@ -0,0 +1,133 @@ +{ + lib, + apple-sdk_14, + llvmPackages_upstream, + stdenv, + swift-corelibs-libdispatch, + swiftc, + symlinkJoin, + swift_release, +}: + +let + propagated-sdk = apple-sdk_14; + + # `out` and `dev` are merged because that’s what Swift expects. + outLinks = symlinkJoin { + name = "swift" + lib.removePrefix "swiftc" (lib.getName swiftc) + "-${swift_release}-out"; + paths = [ + swiftc.out + swiftc.dev + ] + ++ lib.optionals (!stdenv.hostPlatform.isDarwin) ( + lib.optionals (swift-corelibs-libdispatch != null) [ + swift-corelibs-libdispatch.out + swift-corelibs-libdispatch.dev + ] + ); + }; + + docLinks = symlinkJoin { + name = "swift" + lib.removePrefix "swiftc" (lib.getName swiftc) + "-${swift_release}-doc"; + paths = [ + swiftc.doc + ]; + }; + + manLinks = symlinkJoin { + name = "swift" + lib.removePrefix "swiftc" (lib.getName swiftc) + "-${swift_release}-man"; + paths = [ + swiftc.man + ] + ++ lib.optionals (!stdenv.hostPlatform.isDarwin && swift-corelibs-libdispatch != null) [ + swift-corelibs-libdispatch.man + ]; + }; +in +stdenv.mkDerivation (finalAttrs: { + pname = "swift" + lib.removePrefix "swiftc" (lib.getName swiftc); + version = swift_release; + + outputs = [ + "out" + "doc" + "man" + ]; + + strictDeps = true; + + # Will effectively be `buildInputs` when swift is put in `nativeBuildInputs`. + depsTargetTargetPropagated = + lib.optionals stdenv.targetPlatform.isDarwin [ propagated-sdk ] + ++ lib.optionals (!stdenv.hostPlatform.isDarwin) ( + lib.optionals (swift-corelibs-libdispatch != null) [ + swift-corelibs-libdispatch.out + ] + ); + + buildCommand = '' + mkdir -p "$out" "$doc" "$man" + + cp -r ${lib.escapeShellArg outLinks}/* "$out" + cp -r ${lib.escapeShellArg docLinks}/* "$doc" + cp -r ${lib.escapeShellArg manLinks}/* "$man" + + # Make writable temporarily to allow for the fixups below to be made to the outputs. + chmod -R u+w "$out/bin" "$out/lib" "$out/nix-support" + + # Swift expects to find Clang next to it. + ln -s ${lib.escapeShellArg (lib.getExe' llvmPackages_upstream.clang "clang")} "$out/bin/clang" + ln -s ${lib.escapeShellArg (lib.getExe' llvmPackages_upstream.clang "clang++")} "$out/bin/clang++" + + # Swift has a separate resource root from Clang, but locates the Clang resource root via subdir or symlink. + # + # NOTE: We don’t symlink directly here, because that’d add a run-time dep on the full Clang compiler to every + # Swift executable. We instead symlink compiler-rt and copy the headers from Clang to keep the closure size down. + mkdir -p "$out/lib/swift/clang" + ln -s ${lib.escapeShellArg (lib.getBin llvmPackages.compiler-rt)}/{lib,share} "$out/lib/swift/clang/" + cp -rH ${lib.escapeShellArg (lib.getBin llvmPackages.clang)}/resource-root/include/ "$out/lib/swift/clang/" + + # `swift-frontend` expects to find everything relative to its location after resolving symlinks. + # Also copy `swift-driver` assuming it does similar. + for exe in swift-driver swift-frontend; do + if [ -e "$out/bin/$exe" ]; then + orig=$(readlink "$out/bin/$exe") + rm "$out/bin/$exe" + cp "$orig" "$out/bin/$exe" + fi + done + + # Propagated inputs in `$dev/nix-support` have to be substituted to use this derivation instead of swiftc. + for f in "$out/nix-support/"*; do + orig=$(readlink "$f") + rm "$f" + substitute "$orig" "$f" \ + --replace-quiet ${lib.escapeShellArg swiftc.out} "$out" + done + + # Don’t propagate CMake files for toolchain dependencies. These are an implementation detail of the package set. + rm -rf "$out/lib/cmake" + + recordPropagatedDependencies + + chmod -R u-w "$out/bin" "$out/lib" "$out/nix-support" + + # Have to invoke manually because of `buildCommand`. + noBrokenSymlinksInAllOutputs + ''; + + __structuredAttrs = true; + + passthru = { + inherit swiftc; + }; + + meta = { + mainProgram = "swift"; + description = "Swift Programming Language"; + homepage = "https://github.com/swiftlang/swift"; + inherit (swiftc.meta) platforms badPlatforms; + license = lib.licenses.asl20; + teams = [ lib.teams.swift ]; + }; +})