swift: compiler only build & darwin support

This commit is contained in:
Stéphan Kochen 2022-07-19 15:30:12 +02:00
parent 2c2b799dba
commit 8ed924c07a
23 changed files with 1399 additions and 574 deletions

View File

@ -0,0 +1,680 @@
{ lib
, stdenv
, cmake
, coreutils
, gnugrep
, perl
, ninja
, pkg-config
, clang
, bintools
, python3
, git
, fetchFromGitHub
, fetchpatch
, makeWrapper
, gnumake
, file
, runCommand
, writeShellScriptBin
# For lldb
, libedit
, ncurses
, swig
, libxml2
# Linux-specific
, glibc
, libuuid
# Darwin-specific
, substituteAll
, fixDarwinDylibNames
, runCommandLocal
, xcbuild
, cctools # libtool
, sigtool
, DarwinTools
, CoreServices
, Foundation
, Combine
, CLTools_Executables
}:
let
inherit (stdenv) hostPlatform targetPlatform;
# The Swift toolchain script builds projects with separate repos. By convention, some of them share
# the same version with the main Swift compiler project per release.
version = "5.7";
fetchSwiftRelease = { repo, hash }:
fetchFromGitHub {
owner = "apple";
inherit repo hash;
rev = "swift-${version}-RELEASE";
name = "${repo}-${version}-src";
};
# Names in this set match the directory the source is unpacked to.
sources = {
cmark = fetchSwiftRelease {
repo = "swift-cmark";
hash = "sha256-f0BoTs4HYdx/aJ9HIGCWMalhl8PvClWD6R4QK3qSgAw=";
};
llvm-project = fetchSwiftRelease {
repo = "llvm-project";
hash = "sha256-uW6dEAFaDOlHXnq8lFYxrKNLRPEukauZJxX4UCpWpIY=";
};
swift = fetchSwiftRelease {
repo = "swift";
hash = "sha256-n8WVQYinAyIj4wmQnDhvPsH+t8ydANkGbjFJ6blfHOY=";
};
swift-experimental-string-processing = fetchSwiftRelease {
repo = "swift-experimental-string-processing";
hash = "sha256-Ar9fQWi8bYSvGErrS0SWrxIxwEwCjsYIZcWweZ8bV28=";
};
}
// lib.optionalAttrs (!stdenv.isDarwin) {
swift-corelibs-libdispatch = fetchSwiftRelease {
repo = "swift-corelibs-libdispatch";
hash = "sha256-1qbXiC1k9+T+L6liqXKg6EZXqem6KEEx8OctuL4Kb2o=";
};
};
# Tools invoked by swift at run-time.
runtimeDeps = lib.optionals stdenv.isDarwin [
# libtool is used for static linking. This is part of cctools, but adding
# that as a build input puts an unwrapped linker in PATH, and breaks
# builds. This small derivation exposes just libtool.
# NOTE: The same applies to swift-driver, but that is currently always
# invoked via the old `swift` / `swiftc`. May change in the future.
(runCommandLocal "libtool" { } ''
mkdir -p $out/bin
ln -s ${cctools}/bin/libtool $out/bin/libtool
'')
];
# There are apparently multiple naming conventions on Darwin. Swift uses the
# xcrun naming convention. See `configure_sdk_darwin` calls in CMake files.
swiftOs = if targetPlatform.isDarwin
then {
"macos" = "macosx";
"ios" = "iphoneos";
#iphonesimulator
#appletvos
#appletvsimulator
#watchos
#watchsimulator
}.${targetPlatform.darwinPlatform}
or (throw "Cannot build Swift for target Darwin platform '${targetPlatform.darwinPlatform}'")
else targetPlatform.parsed.kernel.name;
# Apple Silicon uses a different CPU name in the target triple.
swiftArch = if stdenv.isDarwin && stdenv.isAarch64 then "arm64"
else targetPlatform.parsed.cpu.name;
# On Darwin, a `.swiftmodule` is a subdirectory in `lib/swift/<OS>`,
# containing binaries for supported archs. On other platforms, binaries are
# installed to `lib/swift/<OS>/<ARCH>`. Note that our setup-hook also adds
# `lib/swift` for convenience.
swiftLibSubdir = "lib/swift/${swiftOs}";
swiftModuleSubdir = if hostPlatform.isDarwin
then "lib/swift/${swiftOs}"
else "lib/swift/${swiftOs}/${swiftArch}";
# And then there's also a separate subtree for statically linked modules.
toStaticSubdir = lib.replaceStrings [ "/swift/" ] [ "/swift_static/" ];
swiftStaticLibSubdir = toStaticSubdir swiftLibSubdir;
swiftStaticModuleSubdir = toStaticSubdir swiftModuleSubdir;
# This matches _SWIFT_DEFAULT_COMPONENTS, with specific components disabled.
swiftInstallComponents = [
"autolink-driver"
"compiler"
# "clang-builtin-headers"
"stdlib"
"sdk-overlay"
"parser-lib"
"static-mirror-lib"
"editor-integration"
# "tools"
# "testsuite-tools"
"toolchain-tools"
"toolchain-dev-tools"
"license"
(if stdenv.isDarwin then "sourcekit-xpc-service" else "sourcekit-inproc")
"swift-remote-mirror"
"swift-remote-mirror-headers"
];
# Build a tool used during the build to create a custom clang wrapper, with
# which we wrap the clang produced by the swift build.
#
# This is used in a `POST_BUILD` for the CMake target, so we rename the
# actual clang to clang-unwrapped, then put the wrapper in place.
#
# We replace the `exec ...` command with `exec -a "$0"` in order to
# preserve $0 for clang. This is because, unlike Nix, we don't have
# separate wrappers for clang/clang++, and clang uses $0 to detect C++.
#
# Similarly, the C++ detection in the wrapper itself also won't work for us,
# so we base it on $0 as well.
makeClangWrapper = writeShellScriptBin "nix-swift-make-clang-wrapper" ''
set -euo pipefail
targetFile="$1"
unwrappedClang="$targetFile-unwrapped"
mv "$targetFile" "$unwrappedClang"
sed < '${clang}/bin/clang' > "$targetFile" \
-e 's|^\s*exec|exec -a "$0"|g' \
-e 's|^\[\[ "${clang.cc}/bin/clang" = \*++ ]]|[[ "$0" = *++ ]]|' \
-e "s|${clang.cc}/bin/clang|$unwrappedClang|g"
chmod a+x "$targetFile"
'';
# Create a tool used during the build to create a custom swift wrapper for
# each of the swift executables produced by the build.
#
# The build produces several `swift-frontend` executables during
# bootstrapping. Each of these has numerous aliases via symlinks, and the
# executable uses $0 to detect what tool is called.
wrapperParams = {
inherit bintools;
default_cc_wrapper = clang; # Instead of `@out@` in the original.
coreutils_bin = lib.getBin coreutils;
gnugrep_bin = gnugrep;
suffixSalt = lib.replaceStrings ["-" "."] ["_" "_"] targetPlatform.config;
use_response_file_by_default = 1;
# NOTE: @prog@ needs to be filled elsewhere.
};
swiftWrapper = runCommand "swift-wrapper.sh" wrapperParams ''
substituteAll '${../wrapper/wrapper.sh}' "$out"
'';
makeSwiftcWrapper = writeShellScriptBin "nix-swift-make-swift-wrapper" ''
set -euo pipefail
targetFile="$1"
unwrappedSwift="$targetFile-unwrapped"
mv "$targetFile" "$unwrappedSwift"
sed < '${swiftWrapper}' > "$targetFile" \
-e "s|@prog@|'$unwrappedSwift'|g" \
-e 's|exec "$prog"|exec -a "$0" "$prog"|g'
chmod a+x "$targetFile"
'';
in stdenv.mkDerivation {
pname = "swift";
inherit version;
outputs = [ "out" "lib" "dev" "doc" "man" ];
nativeBuildInputs = [
cmake
git
ninja
perl # pod2man
pkg-config
python3
makeWrapper
makeClangWrapper
makeSwiftcWrapper
]
++ lib.optionals stdenv.isDarwin [
xcbuild
sigtool # codesign
DarwinTools # sw_vers
fixDarwinDylibNames
];
buildInputs = [
# For lldb
python3
swig
libxml2
]
++ lib.optionals stdenv.isLinux [
libuuid
]
++ lib.optionals stdenv.isDarwin [
CoreServices
Foundation
Combine
];
# This is a partial reimplementation of our setup hook. Because we reuse
# the Swift wrapper for the Swift build itself, we need to do some of the
# same preparation.
postHook = ''
for pkg in "''${pkgsHostTarget[@]}" '${clang.libc}'; do
for subdir in ${swiftModuleSubdir} ${swiftStaticModuleSubdir} lib/swift; do
if [[ -d "$pkg/$subdir" ]]; then
export NIX_SWIFTFLAGS_COMPILE+=" -I $pkg/$subdir"
fi
done
for subdir in ${swiftLibSubdir} ${swiftStaticLibSubdir} lib/swift; do
if [[ -d "$pkg/$subdir" ]]; then
export NIX_LDFLAGS+=" -L $pkg/$subdir"
fi
done
done
'';
# We invoke cmakeConfigurePhase multiple times, but only need this once.
dontFixCmake = true;
# We setup custom build directories.
dontUseCmakeBuildDir = true;
unpackPhase = ''
mkdir src
cd src
${lib.concatStrings (lib.mapAttrsToList (dir: src: ''
cp -r ${src} ${dir}
'') sources)}
chmod -R u+w .
'';
patchPhase = ''
# Just patch all the things for now, we can focus this later.
# TODO: eliminate use of env.
find -type f -print0 | xargs -0 sed -i \
${lib.optionalString stdenv.isDarwin
"-e 's|/usr/libexec/PlistBuddy|${xcbuild}/bin/PlistBuddy|g'"} \
-e 's|/usr/bin/env|${coreutils}/bin/env|g' \
-e 's|/usr/bin/make|${gnumake}/bin/make|g' \
-e 's|/bin/mkdir|${coreutils}/bin/mkdir|g' \
-e 's|/bin/cp|${coreutils}/bin/cp|g' \
-e 's|/usr/bin/file|${file}/bin/file|g'
patch -p1 -d swift -i ${./patches/swift-wrap.patch}
patch -p1 -d swift -i ${./patches/swift-nix-resource-root.patch}
patch -p1 -d swift -i ${./patches/swift-linux-fix-linking.patch}
patch -p1 -d swift -i ${./patches/swift-darwin-fix-bootstrap.patch}
patch -p1 -d swift -i ${substituteAll {
src = ./patches/swift-darwin-plistbuddy-workaround.patch;
inherit swiftArch;
}}
patch -p1 -d swift -i ${substituteAll {
src = ./patches/swift-prevent-sdk-dirs-warning.patch;
inherit (builtins) storeDir;
}}
substituteInPlace swift/cmake/modules/SwiftConfigureSDK.cmake \
--replace '/usr/include' "${stdenv.cc.libc_dev}/include"
# This patch needs to know the lib output location, so must be substituted
# in the same derivation as the compiler.
storeDir="${builtins.storeDir}" \
substituteAll ${./patches/swift-separate-lib.patch} $TMPDIR/swift-separate-lib.patch
patch -p1 -d swift -i $TMPDIR/swift-separate-lib.patch
patch -p1 -d llvm-project/llvm -i ${./patches/llvm-module-cache.patch}
patch -p1 -d llvm-project/clang -i ${./patches/clang-toolchain-dir.patch}
patch -p1 -d llvm-project/clang -i ${./patches/clang-wrap.patch}
patch -p1 -d llvm-project/clang -i ${../../llvm/14/clang/purity.patch}
patch -p2 -d llvm-project/clang -i ${fetchpatch {
name = "clang-cmake-fix-interpreter.patch";
url = "https://github.com/llvm/llvm-project/commit/b5eaf500f2441eff2277ea2973878fb1f171fd0a.patch";
sha256 = "1rma1al0rbm3s3ql6bnvbcighp74lri1lcrwbyacgdqp80fgw1b6";
}}
${lib.optionalString stdenv.isLinux ''
substituteInPlace llvm-project/clang/lib/Driver/ToolChains/Linux.cpp \
--replace 'SysRoot + "/lib' '"${glibc}/lib" "' \
--replace 'SysRoot + "/usr/lib' '"${glibc}/lib" "' \
--replace 'LibDir = "lib";' 'LibDir = "${glibc}/lib";' \
--replace 'LibDir = "lib64";' 'LibDir = "${glibc}/lib";' \
--replace 'LibDir = X32 ? "libx32" : "lib64";' 'LibDir = "${glibc}/lib";'
# uuid.h is not part of glibc, but of libuuid.
sed -i 's|''${GLIBC_INCLUDE_PATH}/uuid/uuid.h|${libuuid.dev}/include/uuid/uuid.h|' \
swift/stdlib/public/Platform/glibc.modulemap.gyb
''}
# Remove tests for cross compilation, which we don't currently support.
rm swift/test/Interop/Cxx/class/constructors-copy-irgen.swift
rm swift/test/Interop/Cxx/class/constructors-irgen.swift
# TODO: consider fixing and re-adding. This test fails due to a non-standard "install_prefix".
rm swift/validation-test/Python/build_swift.swift
# We cannot handle the SDK location being in "Weird Location" due to Nix isolation.
rm swift/test/DebugInfo/compiler-flags.swift
# TODO: Fix issue with ld.gold invoked from script finding crtbeginS.o and crtendS.o.
rm swift/test/IRGen/ELF-remove-autolink-section.swift
# The following two tests fail because we use don't use the bundled libicu:
# [SOURCE_DIR/utils/build-script] ERROR: can't find source directory for libicu (tried /build/src/icu)
rm swift/validation-test/BuildSystem/default_build_still_performs_epilogue_opts_after_split.test
rm swift/validation-test/BuildSystem/test_early_swift_driver_and_infer.swift
# TODO: This test fails for some unknown reason
rm swift/test/Serialization/restrict-swiftmodule-to-revision.swift
# This test was flaky in ofborg, see #186476
rm swift/test/AutoDiff/compiler_crashers_fixed/sr14290-missing-debug-scopes-in-pullback-trampoline.swift
patchShebangs .
${lib.optionalString (!stdenv.isDarwin) ''
# NOTE: This interferes with ABI stability on Darwin, which uses the system
# libraries in the hardcoded path /usr/lib/swift.
fixCmakeFiles .
''}
'';
configurePhase = ''
export SWIFT_SOURCE_ROOT="$PWD"
mkdir -p ../build
cd ../build
export SWIFT_BUILD_ROOT="$PWD"
# Most builds set a target, but LLDB doesn't. Harmless on non-Darwin.
export MACOSX_DEPLOYMENT_TARGET=10.15
'';
# These steps are derived from doing a normal build with.
#
# ./swift/utils/build-toolchain test --dry-run
#
# But dealing with the custom Python build system is far more trouble than
# simply invoking CMake directly. Few variables it passes to CMake are
# actually required or non-default.
#
# Using CMake directly also allows us to split up the already large build,
# and package Swift components separately.
#
# Besides `--dry-run`, another good way to compare build changes between
# Swift releases is to diff the scripts:
#
# git diff swift-5.6.3-RELEASE..swift-5.7-RELEASE -- utils/build*
#
buildPhase = ''
# Helper to build a subdirectory.
#
# Always reset cmakeFlags before calling this. The cmakeConfigurePhase
# amends flags and would otherwise keep expanding it.
function buildProject() {
mkdir -p $SWIFT_BUILD_ROOT/$1
cd $SWIFT_BUILD_ROOT/$1
cmakeDir=$SWIFT_SOURCE_ROOT/''${2-$1}
cmakeConfigurePhase
ninjaBuildPhase
}
cmakeFlags="-GNinja"
buildProject cmark
# Some notes:
# - The Swift build just needs Clang.
# - We can further reduce targets to just our targetPlatform.
cmakeFlags="
-GNinja
-DLLVM_ENABLE_PROJECTS=clang
-DLLVM_TARGETS_TO_BUILD=${{
"x86_64" = "X86";
"aarch64" = "AArch64";
}.${targetPlatform.parsed.cpu.name}}
"
buildProject llvm llvm-project/llvm
# Some notes:
# - Building with libswift defaults to OFF in CMake, but is enabled in
# standard builds, so we enable it as well.
# - Experimental features are OFF by default in CMake, but some are
# required to build the stdlib.
# - SWIFT_STDLIB_ENABLE_OBJC_INTEROP is set explicitely because its check
# is buggy. (Uses SWIFT_HOST_VARIANT_SDK before initialized.)
# Fixed in: https://github.com/apple/swift/commit/84083afef1de5931904d5c815d53856cdb3fb232
cmakeFlags="
-GNinja
-DBOOTSTRAPPING_MODE=BOOTSTRAPPING
-DSWIFT_ENABLE_EXPERIMENTAL_CONCURRENCY=ON
-DLLVM_DIR=$SWIFT_BUILD_ROOT/llvm/lib/cmake/llvm
-DClang_DIR=$SWIFT_BUILD_ROOT/llvm/lib/cmake/clang
-DSWIFT_PATH_TO_CMARK_SOURCE=$SWIFT_SOURCE_ROOT/cmark
-DSWIFT_PATH_TO_CMARK_BUILD=$SWIFT_BUILD_ROOT/cmark
-DSWIFT_PATH_TO_LIBDISPATCH_SOURCE=$SWIFT_SOURCE_ROOT/swift-corelibs-libdispatch
-DEXPERIMENTAL_STRING_PROCESSING_SOURCE_DIR=$SWIFT_SOURCE_ROOT/swift-experimental-string-processing
-DSWIFT_INSTALL_COMPONENTS=${lib.concatStringsSep ";" swiftInstallComponents}
-DSWIFT_STDLIB_ENABLE_OBJC_INTEROP=${if stdenv.isDarwin then "ON" else "OFF"}
"
buildProject swift
# These are based on flags in `utils/build-script-impl`.
#
# LLDB_USE_SYSTEM_DEBUGSERVER=ON disables the debugserver build on Darwin,
# which requires a special signature.
#
# CMAKE_BUILD_WITH_INSTALL_NAME_DIR ensures we don't use rpath on Darwin.
#
# NOTE: On Darwin, we only want ncurses in the linker search path, because
# headers are part of libsystem. Adding its headers to the search path
# causes strange mixing and errors. Note that libedit propagates ncurses,
# so we add both manually here, instead of relying on setup hooks.
# TODO: Find a better way to prevent this conflict.
cmakeFlags="
-GNinja
-DLLDB_SWIFTC=$SWIFT_BUILD_ROOT/swift/bin/swiftc
-DLLDB_SWIFT_LIBS=$SWIFT_BUILD_ROOT/swift/lib/swift
-DLLVM_DIR=$SWIFT_BUILD_ROOT/llvm/lib/cmake/llvm
-DClang_DIR=$SWIFT_BUILD_ROOT/llvm/lib/cmake/clang
-DSwift_DIR=$SWIFT_BUILD_ROOT/swift/lib/cmake/swift
-DLLDB_ENABLE_CURSES=ON
-DLLDB_ENABLE_LIBEDIT=ON
-DLLDB_ENABLE_PYTHON=ON
-DLLDB_ENABLE_LZMA=OFF
-DLLDB_ENABLE_LUA=OFF
-DLLDB_INCLUDE_TESTS=OFF
-DCMAKE_BUILD_WITH_INSTALL_NAME_DIR=ON
${lib.optionalString stdenv.isDarwin ''
-DLLDB_USE_SYSTEM_DEBUGSERVER=ON
''}
-DLibEdit_INCLUDE_DIRS=${libedit.dev}/include
-DLibEdit_LIBRARIES=${libedit}/lib/libedit${stdenv.hostPlatform.extensions.sharedLibrary}
-DCURSES_INCLUDE_DIRS=${if stdenv.isDarwin then "/var/empty" else ncurses.dev}/include
-DCURSES_LIBRARIES=${ncurses}/lib/libncurses${stdenv.hostPlatform.extensions.sharedLibrary}
-DPANEL_LIBRARIES=${ncurses}/lib/libpanel${stdenv.hostPlatform.extensions.sharedLibrary}
";
buildProject lldb llvm-project/lldb
${lib.optionalString stdenv.isDarwin ''
# Need to do a standalone build of concurrency for Darwin back deployment.
# Based on: utils/swift_build_support/swift_build_support/products/backdeployconcurrency.py
cmakeFlags="
-GNinja
-DCMAKE_Swift_COMPILER=$SWIFT_BUILD_ROOT/swift/bin/swiftc
-DTOOLCHAIN_DIR=/var/empty
-DSWIFT_NATIVE_LLVM_TOOLS_PATH=${stdenv.cc}/bin
-DSWIFT_NATIVE_CLANG_TOOLS_PATH=${stdenv.cc}/bin
-DSWIFT_NATIVE_SWIFT_TOOLS_PATH=$SWIFT_BUILD_ROOT/swift/bin
-DCMAKE_CROSSCOMPILING=ON
-DBUILD_SWIFT_CONCURRENCY_BACK_DEPLOYMENT_LIBRARIES=ON
-DSWIFT_INCLUDE_TOOLS=OFF
-DSWIFT_BUILD_STDLIB_EXTRA_TOOLCHAIN_CONTENT=OFF
-DSWIFT_BUILD_TEST_SUPPORT_MODULES=OFF
-DSWIFT_BUILD_STDLIB=OFF
-DSWIFT_BUILD_DYNAMIC_STDLIB=OFF
-DSWIFT_BUILD_STATIC_STDLIB=OFF
-DSWIFT_BUILD_REMOTE_MIRROR=OFF
-DSWIFT_BUILD_SDK_OVERLAY=OFF
-DSWIFT_BUILD_DYNAMIC_SDK_OVERLAY=OFF
-DSWIFT_BUILD_STATIC_SDK_OVERLAY=OFF
-DSWIFT_INCLUDE_TESTS=OFF
-DSWIFT_BUILD_PERF_TESTSUITE=OFF
-DSWIFT_HOST_VARIANT_ARCH=${swiftArch}
-DBUILD_STANDALONE=ON
-DSWIFT_INSTALL_COMPONENTS=back-deployment
-DSWIFT_SDKS=${{
"macos" = "OSX";
"ios" = "IOS";
#IOS_SIMULATOR
#TVOS
#TVOS_SIMULATOR
#WATCHOS
#WATCHOS_SIMULATOR
}.${targetPlatform.darwinPlatform}}
-DLLVM_DIR=$SWIFT_BUILD_ROOT/llvm/lib/cmake/llvm
-DSWIFT_DEST_ROOT=$out
-DSWIFT_HOST_VARIANT_SDK=OSX
-DSWIFT_DARWIN_DEPLOYMENT_VERSION_OSX=10.15
-DSWIFT_DARWIN_DEPLOYMENT_VERSION_IOS=13.0
-DSWIFT_DARWIN_DEPLOYMENT_VERSION_MACCATALYST=13.0
-DSWIFT_DARWIN_DEPLOYMENT_VERSION_TVOS=13.0
-DSWIFT_DARWIN_DEPLOYMENT_VERSION_WATCHOS=6.0
"
# This depends on the special Clang build specific to the Swift branch.
# We also need to call a specific Ninja target.
export CC=$SWIFT_BUILD_ROOT/llvm/bin/clang
export CXX=$SWIFT_BUILD_ROOT/llvm/bin/clang++
ninjaFlags="back-deployment"
buildProject swift-concurrency-backdeploy swift
export CC=$NIX_CC/bin/clang
export CXX=$NIX_CC/bin/clang++
unset ninjaFlags
''}
'';
# TODO: ~50 failing tests on x86_64-linux. Other platforms not checked.
doCheck = false;
checkInputs = [ file ];
# TODO: consider using stress-tester and integration-test.
checkPhase = ''
cd $SWIFT_BUILD_ROOT/swift
checkTarget=check-swift-all
ninjaCheckPhase
unset checkTarget
'';
installPhase = ''
# Undo the clang and swift wrapping we did for the build.
# (This happened via patches to cmake files.)
cd $SWIFT_BUILD_ROOT
mv llvm/bin/clang-14{-unwrapped,}
mv swift/bin/swift-frontend{-unwrapped,}
mkdir $out $lib
# Install clang binaries only. We hide these with the wrapper, so they are
# for private use by Swift only.
cd $SWIFT_BUILD_ROOT/llvm
installTargets=install-clang
ninjaInstallPhase
unset installTargets
# LLDB is also a private install.
cd $SWIFT_BUILD_ROOT/lldb
ninjaInstallPhase
cd $SWIFT_BUILD_ROOT/swift
ninjaInstallPhase
${lib.optionalString stdenv.isDarwin ''
cd $SWIFT_BUILD_ROOT/swift-concurrency-backdeploy
installTargets=install-back-deployment
ninjaInstallPhase
unset installTargets
''}
# Separate $lib output here, because specific logic follows.
# Only move the dynamic run-time parts, to keep $lib small. Every Swift
# build will depend on it.
moveToOutput "lib/swift" "$lib"
moveToOutput "lib/libswiftDemangle.*" "$lib"
# This link is here because various tools (swiftpm) check for stdlib
# relative to the swift compiler. It's fine if this is for build-time
# stuff, but we should patch all cases were it would end up in an output.
ln -s $lib/lib/swift $out/lib/swift
# Swift has a separate resource root from Clang, but locates the Clang
# resource root via subdir or symlink. Provide a default here, but we also
# patch Swift to prefer NIX_CC if set.
ln -s ${clang}/resource-root $lib/lib/swift/clang
${lib.optionalString stdenv.isDarwin ''
# Install required library for ObjC interop.
# TODO: Is there no source code for this available?
cp -r ${CLTools_Executables}/usr/lib/arc $out/lib/arc
''}
'';
preFixup = lib.optionalString stdenv.isLinux ''
# This is cheesy, but helps the patchelf hook remove /build from RPATH.
cd $NIX_BUILD_TOP
mv build buildx
'';
postFixup = lib.optionalString stdenv.isDarwin ''
# These libraries need to use the system install name. The official SDK
# does the same (as opposed to using rpath). Presumably, they are part of
# the stable ABI. Not using the system libraries at run-time is known to
# cause ObjC class conflicts and segfaults.
declare -A systemLibs=(
[libswiftCore.dylib]=1
[libswiftDarwin.dylib]=1
[libswiftSwiftOnoneSupport.dylib]=1
[libswift_Concurrency.dylib]=1
)
for systemLib in "''${!systemLibs[@]}"; do
install_name_tool -id /usr/lib/swift/$systemLib $lib/${swiftLibSubdir}/$systemLib
done
for file in $out/bin/swift-frontend $lib/${swiftLibSubdir}/*.dylib; do
changeArgs=""
for dylib in $(otool -L $file | awk '{ print $1 }'); do
if [[ ''${systemLibs["$(basename $dylib)"]} ]]; then
changeArgs+=" -change $dylib /usr/lib/swift/$(basename $dylib)"
elif [[ "$dylib" = */bootstrapping1/* ]]; then
changeArgs+=" -change $dylib $lib/lib/swift/$(basename $dylib)"
fi
done
if [[ -n "$changeArgs" ]]; then
install_name_tool $changeArgs $file
fi
done
wrapProgram $out/bin/swift-frontend \
--prefix PATH : ${lib.makeBinPath runtimeDeps}
'';
passthru = {
inherit
swiftOs swiftArch
swiftModuleSubdir swiftLibSubdir
swiftStaticModuleSubdir swiftStaticLibSubdir;
# Internal attr for the wrapper.
_wrapperParams = wrapperParams;
};
meta = {
description = "The Swift Programming Language";
homepage = "https://github.com/apple/swift";
maintainers = with lib.maintainers; [ dtzWill trepetti dduan trundle stephank ];
license = lib.licenses.asl20;
platforms = with lib.platforms; linux ++ darwin;
# Swift doesn't support 32-bit Linux, unknown on other platforms.
badPlatforms = lib.platforms.i686;
timeout = 86400; # 24 hours.
};
}

View File

@ -0,0 +1,18 @@
Wrap the clang produced during the build
--- a/tools/driver/CMakeLists.txt
+++ b/tools/driver/CMakeLists.txt
@@ -59,6 +59,13 @@ endif()
add_dependencies(clang clang-resource-headers)
+# Nix: wrap the clang build.
+add_custom_command(
+ TARGET clang POST_BUILD
+ COMMAND nix-swift-make-clang-wrapper $<TARGET_FILE:clang>
+ VERBATIM
+)
+
if(NOT CLANG_LINKS_TO_CREATE)
set(CLANG_LINKS_TO_CREATE clang++ clang-cl clang-cpp)
endif()

View File

@ -0,0 +1,30 @@
The compiler fails if LLVM modules are enabled and it cannot write its module
cache. This patch detects and rejects the fake, non-existant $HOME used in Nix
builds.
We could simply return false in `cache_directory`, but that completely disables
module caching, and may unnecessarily slow down builds. Instead, let it use
'/tmp/.cache'.
--- a/lib/Support/Unix/Path.inc
+++ b/lib/Support/Unix/Path.inc
@@ -1380,6 +1380,9 @@ bool user_config_directory(SmallVectorImpl<char> &result) {
if (!home_directory(result)) {
return false;
}
+ if (std::equal(result.begin(), result.end(), "/homeless-shelter")) {
+ return false;
+ }
append(result, ".config");
return true;
}
@@ -1401,6 +1404,9 @@ bool cache_directory(SmallVectorImpl<char> &result) {
if (!home_directory(result)) {
return false;
}
+ if (std::equal(result.begin(), result.end(), "/homeless-shelter")) {
+ system_temp_directory(true/*ErasedOnReboot*/, result);
+ }
append(result, ".cache");
return true;
}

View File

@ -0,0 +1,20 @@
This patch fixes dylib references during bootstrapping. It's possible
`LIBSWIFT_BUILD_MODE=BOOTSTRAPPING` is not really well tested on Darwin,
because official builds don't use it.
In the near future, Swift will require an existing Swift toolchain to
bootstrap, and we will likely have to replace this any way.
--- a/stdlib/cmake/modules/AddSwiftStdlib.cmake
+++ b/stdlib/cmake/modules/AddSwiftStdlib.cmake
@@ -1035,6 +1035,10 @@ function(add_swift_target_library_single target name)
set(install_name_dir "${SWIFTLIB_SINGLE_DARWIN_INSTALL_NAME_DIR}")
endif()
+ if(DEFINED SWIFTLIB_SINGLE_BOOTSTRAPPING)
+ set(install_name_dir "${lib_dir}/${output_sub_dir}")
+ endif()
+
set_target_properties("${target}"
PROPERTIES
INSTALL_NAME_DIR "${install_name_dir}")

View File

@ -0,0 +1,17 @@
CMake tries to read a list field from SDKSettings.plist, but the output of
facebook/xcbuild PlistBuddy is incompatible with Apple's.
Simply set the supported architectures to the one target architecture we're
building for.
--- a/cmake/modules/SwiftConfigureSDK.cmake
+++ b/cmake/modules/SwiftConfigureSDK.cmake
@@ -189,7 +189,7 @@ macro(configure_sdk_darwin
endif()
# Remove any architectures not supported by the SDK.
- remove_sdk_unsupported_archs(${name} ${xcrun_name} ${SWIFT_SDK_${prefix}_PATH} SWIFT_SDK_${prefix}_ARCHITECTURES)
+ set(SWIFT_SDK_${prefix}_ARCHITECTURES "@swiftArch@")
list_intersect(
"${SWIFT_DARWIN_MODULE_ARCHS}" # lhs

View File

@ -0,0 +1,21 @@
--- a/lib/Driver/ToolChains.cpp
+++ b/lib/Driver/ToolChains.cpp
@@ -1475,7 +1475,17 @@ const char *ToolChain::getClangLinkerDriver(
// If there is a linker driver in the toolchain folder, use that instead.
if (auto tool = llvm::sys::findProgramByName(LinkerDriver, {toolchainPath}))
- LinkerDriver = Args.MakeArgString(tool.get());
+ return Args.MakeArgString(tool.get());
+ }
+
+ // For Nix, prefer linking using the wrapped system clang, instead of using
+ // the unwrapped clang packaged with swift. The latter is unable to link, but
+ // we still want to use it for other purposes (clang importer).
+ if (auto nixCC = llvm::sys::Process::GetEnv("NIX_CC")) {
+ llvm::SmallString<128> binDir(nixCC.getValue());
+ llvm::sys::path::append(binDir, "bin");
+ if (auto tool = llvm::sys::findProgramByName(LinkerDriver, {binDir.str()}))
+ return Args.MakeArgString(tool.get());
}
return LinkerDriver;

View File

@ -0,0 +1,67 @@
Swift normally looks for the Clang resource dir in a subdir/symlink of its own
resource dir. We provide a symlink to the Swift build-time Clang as a default
there, but we also here patch two checks to try locate it via NIX_CC.
The first (ClangImporter.cpp) happens when Swift code imports C modules. The
second (ToolChains.cpp) happens when Swift is used to link the final product.
--- a/lib/ClangImporter/ClangImporter.cpp
+++ b/lib/ClangImporter/ClangImporter.cpp
@@ -68,6 +68,7 @@
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/Memory.h"
#include "llvm/Support/Path.h"
+#include "llvm/Support/Process.h"
#include "llvm/Support/YAMLParser.h"
#include "llvm/Support/YAMLTraits.h"
#include <algorithm>
@@ -809,6 +810,17 @@ importer::addCommonInvocationArguments(
const std::string &overrideResourceDir = importerOpts.OverrideResourceDir;
if (overrideResourceDir.empty()) {
+ // Prefer the Clang resource directory from NIX_CC, to allow swapping in a
+ // different stdenv.
+ // TODO: Figure out how to provide a user override for this. Probably a
+ // niche use case, though, and for now a user can unset NIX_CC to work
+ // around it if necessary.
+ if (auto nixCC = llvm::sys::Process::GetEnv("NIX_CC")) {
+ llvm::SmallString<128> resourceDir(nixCC.getValue());
+ llvm::sys::path::append(resourceDir, "resource-root");
+ invocationArgStrs.push_back("-resource-dir");
+ invocationArgStrs.push_back(std::string(resourceDir.str()));
+ } else {
llvm::SmallString<128> resourceDir(searchPathOpts.RuntimeResourcePath);
// Adjust the path to refer to our copy of the Clang resource directory
@@ -824,6 +836,7 @@ importer::addCommonInvocationArguments(
// Set the Clang resource directory to the path we computed.
invocationArgStrs.push_back("-resource-dir");
invocationArgStrs.push_back(std::string(resourceDir.str()));
+ } // nixCC
} else {
invocationArgStrs.push_back("-resource-dir");
invocationArgStrs.push_back(overrideResourceDir);
--- a/lib/Driver/ToolChains.cpp
+++ b/lib/Driver/ToolChains.cpp
@@ -1372,10 +1372,20 @@ void ToolChain::getClangLibraryPath(const ArgList &Args,
SmallString<128> &LibPath) const {
const llvm::Triple &T = getTriple();
+ // Nix: We provide a `clang` symlink in the default Swift resource root, but
+ // prefer detecting the Clang resource root via NIX_CC, to allow swapping in
+ // a different stdenv. However, always honor a user-provided `-resource-dir`.
+ auto nixCC = llvm::sys::Process::GetEnv("NIX_CC");
+ if (nixCC && !Args.hasArgNoClaim(options::OPT_resource_dir)) {
+ LibPath.assign(nixCC.getValue());
+ llvm::sys::path::append(LibPath, "resource-root");
+ } else {
getResourceDirPath(LibPath, Args, /*Shared=*/true);
// Remove platform name.
llvm::sys::path::remove_filename(LibPath);
- llvm::sys::path::append(LibPath, "clang", "lib",
+ llvm::sys::path::append(LibPath, "clang");
+ } // nixCC
+ llvm::sys::path::append(LibPath, "lib",
T.isOSDarwin() ? "darwin"
: getPlatformNameForTriple(T));
}

View File

@ -0,0 +1,39 @@
Prevents a user-visible warning on every compilation:
ld: warning: directory not found for option '-L.../MacOSX11.0.sdk/usr/lib/swift'
--- a/lib/Driver/ToolChains.cpp
+++ b/lib/Driver/ToolChains.cpp
@@ -1455,9 +1455,11 @@ void ToolChain::getRuntimeLibraryPaths(SmallVectorImpl<std::string> &runtimeLibP
runtimeLibPaths.push_back(std::string(scratchPath.str()));
}
+ if (!SDKPath.startswith("@storeDir@")) {
scratchPath = SDKPath;
llvm::sys::path::append(scratchPath, "usr", "lib", "swift");
runtimeLibPaths.push_back(std::string(scratchPath.str()));
+ }
}
}
--- a/lib/Frontend/CompilerInvocation.cpp
+++ b/lib/Frontend/CompilerInvocation.cpp
@@ -185,7 +185,9 @@ static void updateRuntimeLibraryPaths(SearchPathOptions &SearchPathOpts,
RuntimeLibraryImportPaths.push_back(std::string(LibPath.str()));
}
- LibPath = SearchPathOpts.getSDKPath();
+ auto SDKPath = SearchPathOpts.getSDKPath();
+ if (!SDKPath.startswith("@storeDir@")) {
+ LibPath = SDKPath;
llvm::sys::path::append(LibPath, "usr", "lib", "swift");
if (!Triple.isOSDarwin()) {
// Use the non-architecture suffixed form with directory-layout
@@ -200,6 +202,7 @@ static void updateRuntimeLibraryPaths(SearchPathOptions &SearchPathOpts,
llvm::sys::path::append(LibPath, swift::getMajorArchitectureName(Triple));
}
RuntimeLibraryImportPaths.push_back(std::string(LibPath.str()));
+ }
}
SearchPathOpts.setRuntimeLibraryImportPaths(RuntimeLibraryImportPaths);
}

View File

@ -0,0 +1,26 @@
Patch paths to use the separate 'lib' output. One of the things this patch
fixes is the output of `swift -frontend -print-target-info`, which swiftpm uses
to set rpath on Linux.
The check if the executable path starts with 'out' is necessary for
bootstrapping, or the compiler will fail when run from the build directory.
--- a/lib/Frontend/CompilerInvocation.cpp
+++ b/lib/Frontend/CompilerInvocation.cpp
@@ -49,11 +49,16 @@ swift::CompilerInvocation::CompilerInvocation() {
void CompilerInvocation::computeRuntimeResourcePathFromExecutablePath(
StringRef mainExecutablePath, bool shared,
llvm::SmallVectorImpl<char> &runtimeResourcePath) {
+ if (mainExecutablePath.startswith("@storeDir@")) {
+ auto libPath = StringRef("@lib@");
+ runtimeResourcePath.append(libPath.begin(), libPath.end());
+ } else {
runtimeResourcePath.append(mainExecutablePath.begin(),
mainExecutablePath.end());
llvm::sys::path::remove_filename(runtimeResourcePath); // Remove /swift
llvm::sys::path::remove_filename(runtimeResourcePath); // Remove /bin
+ }
appendSwiftLibDir(runtimeResourcePath, shared);
}

View File

@ -0,0 +1,46 @@
Wrap the swift compiler produced during the build
--- a/tools/driver/CMakeLists.txt
+++ b/tools/driver/CMakeLists.txt
@@ -16,6 +16,13 @@ if(${LIBSWIFT_BUILD_MODE} MATCHES "BOOTSTRAPPING.*")
swiftDriverTool
libswiftStub)
+ # Nix: wrap the swift build.
+ add_custom_command(
+ TARGET swift-frontend-bootstrapping0 POST_BUILD
+ COMMAND nix-swift-make-swift-wrapper $<TARGET_FILE:swift-frontend-bootstrapping0>
+ VERBATIM
+ )
+
swift_create_post_build_symlink(swift-frontend-bootstrapping0
SOURCE "swift-frontend${CMAKE_EXECUTABLE_SUFFIX}"
DESTINATION "swiftc${CMAKE_EXECUTABLE_SUFFIX}"
@@ -34,6 +41,13 @@ if(${LIBSWIFT_BUILD_MODE} MATCHES "BOOTSTRAPPING.*")
swiftDriverTool
libswift-bootstrapping1)
+ # Nix: wrap the swift build.
+ add_custom_command(
+ TARGET swift-frontend-bootstrapping1 POST_BUILD
+ COMMAND nix-swift-make-swift-wrapper $<TARGET_FILE:swift-frontend-bootstrapping1>
+ VERBATIM
+ )
+
swift_create_post_build_symlink(swift-frontend-bootstrapping1
SOURCE "swift-frontend${CMAKE_EXECUTABLE_SUFFIX}"
DESTINATION "swiftc${CMAKE_EXECUTABLE_SUFFIX}"
@@ -50,6 +64,13 @@ target_link_libraries(swift-frontend
swiftDriverTool
libswift)
+# Nix: wrap the swift build.
+add_custom_command(
+ TARGET swift-frontend POST_BUILD
+ COMMAND nix-swift-make-swift-wrapper $<TARGET_FILE:swift-frontend>
+ VERBATIM
+)
+
# Create a `swift-driver` executable adjacent to the `swift-frontend` executable
# to ensure that `swiftc` forwards to the standalone driver when invoked.
swift_create_early_driver_copies(swift-frontend)

View File

@ -1,475 +1,62 @@
{ lib, stdenv
, cmake
, coreutils
, glibc
, gccForLibs
, which
, perl
, libedit
, ninja
, pkg-config
, sqlite
, libxml2
, clang_13
, python3
, ncurses
, libuuid
, libxcrypt
, icu
, libgcc
, libblocksruntime
, curl
, rsync
, git
, libgit2
, fetchFromGitHub
, makeWrapper
, gnumake
, file
{ lib
, pkgs
, newScope
, darwin
, llvmPackages_latest
, overrideCC
}:
let
# The Swift toolchain script builds projects with separate repos. By convention, some of them share
# the same version with the main Swift compiler project per release. We fetch these with
# `fetchSwiftRelease`. The rest have their own versions locked to each Swift release, as defined in the
# Swift compiler repo:
# utils/update_checkout/update_checkout-config.json.
#
# ... among projects listed in that file, we provide our own:
# - CMake
# - ninja
# - icu
#
# ... we'd like to include the following in the future:
# - stress-tester
# - integration-tests
self = rec {
callPackage = newScope self;
# Current versions of Swift on Darwin require macOS SDK 10.15 at least.
# Re-export this so we can rely on the minimum Swift SDK elsewhere.
apple_sdk = pkgs.darwin.apple_sdk_11_0;
# Our current Clang on Darwin is v11, but we need at least v12. The
# following applies the newer Clang with the same libc overrides as
# `apple_sdk.stdenv`.
#
# If 'latest' becomes an issue, recommend replacing it with v14, which is
# currently closest to the official Swift builds.
clang = if pkgs.stdenv.isDarwin
then
llvmPackages_latest.clang.override rec {
libc = apple_sdk.Libsystem;
bintools = pkgs.bintools.override { inherit libc; };
}
else
llvmPackages_latest.clang;
# Overrides that create a useful environment for swift packages, allowing
# packaging with `swiftPackages.callPackage`. These are similar to
# `apple_sdk_11_0.callPackage`, with our clang on top.
inherit (clang) bintools;
stdenv = overrideCC pkgs.stdenv clang;
darwin = pkgs.darwin.overrideScope (_: prev: {
inherit apple_sdk;
inherit (apple_sdk) Libsystem LibsystemCross libcharset libunwind objc4 configd IOKit Security;
CF = apple_sdk.CoreFoundation;
});
xcodebuild = pkgs.xcbuild.override {
inherit (apple_sdk.frameworks) CoreServices CoreGraphics ImageIO;
inherit stdenv;
sdkVer = "10.15";
};
xcbuild = xcodebuild;
swift-unwrapped = callPackage ./compiler {
inherit (darwin) DarwinTools cctools sigtool;
inherit (apple_sdk) CLTools_Executables;
inherit (apple_sdk.frameworks) CoreServices Foundation Combine;
};
swift = callPackage ./wrapper {
swift = swift-unwrapped;
};
versions = {
swift = "5.6.2";
yams = "4.0.2";
argumentParser = "1.0.3";
format = "release/5.6";
crypto = "1.1.5";
nio = "2.31.2";
nio-ssl = "2.15.0";
};
fetchAppleRepo = { repo, rev, sha256 }:
fetchFromGitHub {
owner = "apple";
inherit repo rev sha256;
name = "${repo}-${rev}-src";
};
fetchSwiftRelease = { repo, sha256, fetchSubmodules ? false }:
fetchFromGitHub {
owner = "apple";
inherit repo sha256 fetchSubmodules;
rev = "swift-${versions.swift}-RELEASE";
name = "${repo}-${versions.swift}-src";
};
sources = {
# Projects that share `versions.swift` for each release.
swift = fetchSwiftRelease {
repo = "swift";
sha256 = "sha256-wiRXAXWEksJuy+YQQ+B7tzr2iLkSVkgV6o+wIz7yKJA=";
};
cmark = fetchSwiftRelease {
repo = "swift-cmark";
sha256 = "sha256-f0BoTs4HYdx/aJ9HIGCWMalhl8PvClWD6R4QK3qSgAw=";
};
llbuild = fetchSwiftRelease {
repo = "swift-llbuild";
sha256 = "sha256-SQ6V0zVshIYMjayx+ZpYuLijgQ89tqRnPlXBPf2FYqM=";
};
driver = fetchSwiftRelease {
repo = "swift-driver";
sha256 = "sha256-D5/C4Rbv5KIsKpy6YbuMxGIGaQkn80PD4Cp0l6bPKzY=";
};
toolsSupportCore = fetchSwiftRelease {
repo = "swift-tools-support-core";
sha256 = "sha256-FbtQCq1sSlzrskCrgzD4iYuo5eGaXrAUUxoNX/BiOfg=";
};
swiftpm = fetchSwiftRelease {
repo = "swift-package-manager";
sha256 = "sha256-esO4Swz3UYngbVgxoV+fkhSC0AU3IaxVjWkgK/s3x68=";
};
syntax = fetchSwiftRelease {
repo = "swift-syntax";
sha256 = "sha256-C9FPCtq49BvKXtTWWeReYWNrU70pHzT2DhAv3NiTbPU=";
};
corelibsXctest = fetchSwiftRelease {
repo = "swift-corelibs-xctest";
sha256 = "sha256-0hizfnKJaUUA+jXuXzXWk72FmlSyc+UGEf7BTLdJrx4=";
};
corelibsFoundation = fetchSwiftRelease {
repo = "swift-corelibs-foundation";
sha256 = "sha256-8sCL8Ia6yb6bRsJZ52gUJH0jN3lwClM573G8jgUdEhw=";
};
corelibsLibdispatch = fetchSwiftRelease {
repo = "swift-corelibs-libdispatch";
sha256 = "sha256-1tIskUMnfblnvZaFDQPUMBfWTmBYG98s7rEww7PwZO8=";
fetchSubmodules = true;
};
indexstoreDb = fetchSwiftRelease {
repo = "indexstore-db";
sha256 = "sha256-/PO4eMiASZN3pjFjBQ1r8vYwGRn6xm3SWaB2HDZlkPs=";
};
sourcekitLsp = fetchSwiftRelease {
repo = "sourcekit-lsp";
sha256 = "sha256-ttgUC4ZHD3P/xLHllEbACtHVrJ6HXqeVWccXcoPMkts=";
};
llvmProject = fetchSwiftRelease {
repo = "llvm-project";
sha256 = "sha256-YVs3lKV2RlaovpYkdGO+vzypolrmXmbKBBP4+osNMYw=";
};
docc = fetchSwiftRelease {
repo = "swift-docc";
sha256 = "sha256-rWiaNamZoHTO1bKpubxuT7m1IBOl7amT5M71mNauilY=";
};
docc-render-artifact = fetchSwiftRelease {
repo = "swift-docc-render-artifact";
sha256 = "sha256-AX+rtDLhq8drk7N6/hoH3fQioudmmTCnEhR45bME8uU=";
};
docc-symbolkit = fetchSwiftRelease {
repo = "swift-docc-symbolkit";
sha256 = "sha256-Xy1TQ5ucDW+MnkeOvVznsATBmwcQ3p1x+ofQ22ofk+o=";
};
lmdb = fetchSwiftRelease {
repo = "swift-lmdb";
sha256 = "sha256-i2GkWRWq1W5j8rF4PiHwWgT4Dur5FCY2o44HvUU3vtQ=";
};
markdown = fetchSwiftRelease {
repo = "swift-markdown";
sha256 = "sha256-XtFSBiNHhmULjS4OqSpMgUetLu3peRg7l6HpjwVsTj8=";
};
cmark-gfm = fetchAppleRepo {
repo = "swift-cmark";
rev = "swift-${versions.swift}-RELEASE-gfm";
sha256 = "sha256-g28iKmMR2W0r1urf8Fk1HBxAp5OlonNYSVN3Ril66tQ=";
};
# Projects that have their own versions during each release
argumentParser = fetchAppleRepo {
repo = "swift-argument-parser";
rev = "${versions.argumentParser}";
sha256 = "sha256-vNqkuAwSZNCWvwe6E5BqbXQdIbmIia0dENmmSQ9P8Mo=";
};
format = fetchAppleRepo {
repo = "swift-format";
rev = "${versions.format}";
sha256 = "sha256-1f5sIrv9IbPB7Vnahq1VwH8gT41dcjWldRwvVEaMdto=";
};
crypto = fetchAppleRepo {
repo = "swift-crypto";
rev = "${versions.crypto}";
sha256 = "sha256-jwxXQuOF+CnpLMwTZ2z52Fgx2b97yWzXiPTx0Ye8KCQ=";
};
nio = fetchAppleRepo {
repo = "swift-nio";
rev = versions.nio;
sha256 = "sha256-FscOA/S7on31QCR/MZFjg4ZB3FGJ+rdptZ6MRZJXexE=";
};
nio-ssl = fetchAppleRepo {
repo = "swift-nio-ssl";
rev = versions.nio-ssl;
sha256 = "sha256-5QGkmkCOXhG3uOdf0bd3Fo1MFekB8/WcveBXGhtVZKo=";
};
yams = fetchFromGitHub {
owner = "jpsim";
repo = "Yams";
rev = versions.yams;
sha256 = "sha256-cTkCAwxxLc35laOon1ZXXV8eAxX02oDolJyPauhZado=";
name = "Yams-${versions.yams}-src";
};
};
devInputs = [
curl
glibc
icu
libblocksruntime
libedit
libgcc
libuuid
libxcrypt
libxml2
ncurses
sqlite
];
python = (python3.withPackages (ps: [ps.six]));
cmakeFlags = [
"-DGLIBC_INCLUDE_PATH=${stdenv.cc.libc.dev}/include"
"-DC_INCLUDE_DIRS=${lib.makeSearchPathOutput "dev" "include" devInputs}:${libxml2.dev}/include/libxml2"
"-DGCC_INSTALL_PREFIX=${gccForLibs}"
];
in
stdenv.mkDerivation {
pname = "swift";
version = versions.swift;
nativeBuildInputs = [
cmake
git
makeWrapper
ninja
perl
pkg-config
python
rsync
which
];
buildInputs = devInputs ++ [
clang_13
];
# TODO: Revisit what needs to be propagated and how.
propagatedBuildInputs = [
libgcc
libgit2
python
];
propagatedUserEnvPkgs = [ git pkg-config ];
hardeningDisable = [ "format" ]; # for LLDB
unpackPhase = ''
mkdir src
cd src
export SWIFT_SOURCE_ROOT=$PWD
cp -r ${sources.swift} swift
cp -r ${sources.cmark} cmark
cp -r ${sources.llbuild} llbuild
cp -r ${sources.argumentParser} swift-argument-parser
cp -r ${sources.driver} swift-driver
cp -r ${sources.toolsSupportCore} swift-tools-support-core
cp -r ${sources.swiftpm} swiftpm
cp -r ${sources.syntax} swift-syntax
cp -r ${sources.corelibsXctest} swift-corelibs-xctest
cp -r ${sources.corelibsFoundation} swift-corelibs-foundation
cp -r ${sources.corelibsLibdispatch} swift-corelibs-libdispatch
cp -r ${sources.yams} yams
cp -r ${sources.indexstoreDb} indexstore-db
cp -r ${sources.sourcekitLsp} sourcekit-lsp
cp -r ${sources.format} swift-format
cp -r ${sources.crypto} swift-crypto
cp -r ${sources.llvmProject} llvm-project
cp -r ${sources.cmark-gfm} swift-cmark-gfm
cp -r ${sources.docc} swift-docc
cp -r ${sources.docc-render-artifact} swift-docc-render-artifact
cp -r ${sources.docc-symbolkit} swift-docc-symbolkit
cp -r ${sources.lmdb} swift-lmdb
cp -r ${sources.markdown} swift-markdown
cp -r ${sources.nio} swift-nio
cp -r ${sources.nio-ssl} swift-nio-ssl
chmod -R u+w .
'';
patchPhase = ''
# Just patch all the things for now, we can focus this later.
patchShebangs $SWIFT_SOURCE_ROOT
# TODO: eliminate use of env.
find -type f -print0 | xargs -0 sed -i \
-e 's|/usr/bin/env|${coreutils}/bin/env|g' \
-e 's|/usr/bin/make|${gnumake}/bin/make|g' \
-e 's|/bin/mkdir|${coreutils}/bin/mkdir|g' \
-e 's|/bin/cp|${coreutils}/bin/cp|g' \
-e 's|/usr/bin/file|${file}/bin/file|g'
# Build configuration patches.
patch -p1 -d swift -i ${./patches/0001-build-presets-linux-don-t-require-using-Ninja.patch}
patch -p1 -d swift -i ${./patches/0002-build-presets-linux-allow-custom-install-prefix.patch}
patch -p1 -d swift -i ${./patches/0003-build-presets-linux-don-t-build-extra-libs.patch}
patch -p1 -d swift -i ${./patches/0004-build-presets-linux-plumb-extra-cmake-options.patch}
patch -p1 -d swift -i ${./patches/0007-build-presets-linux-os-stdlib.patch}
substituteInPlace swift/cmake/modules/SwiftConfigureSDK.cmake \
--replace '/usr/include' "${stdenv.cc.libc.dev}/include"
sed -i swift/utils/build-presets.ini \
-e 's/^test-installable-package$/# \0/' \
-e 's/^test$/# \0/' \
-e 's/^validation-test$/# \0/' \
-e 's/^long-test$/# \0/' \
-e 's/^stress-test$/# \0/' \
-e 's/^test-optimized$/# \0/' \
-e 's/^swift-install-components=autolink.*$/\0;editor-integration/'
# LLVM toolchain patches.
patch -p1 -d llvm-project/clang -i ${./patches/0005-clang-toolchain-dir.patch}
patch -p1 -d llvm-project/clang -i ${./patches/0006-clang-purity.patch}
substituteInPlace llvm-project/clang/lib/Driver/ToolChains/Linux.cpp \
--replace 'SysRoot + "/lib' '"${glibc}/lib" "' \
--replace 'SysRoot + "/usr/lib' '"${glibc}/lib" "' \
--replace 'LibDir = "lib";' 'LibDir = "${glibc}/lib";' \
--replace 'LibDir = "lib64";' 'LibDir = "${glibc}/lib";' \
--replace 'LibDir = X32 ? "libx32" : "lib64";' 'LibDir = "${glibc}/lib";'
# Substitute ncurses for curses in llbuild.
sed -i 's/curses/ncurses/' llbuild/*/*/CMakeLists.txt
sed -i 's/curses/ncurses/' llbuild/*/*/*/CMakeLists.txt
# uuid.h is not part of glibc, but of libuuid.
sed -i 's|''${GLIBC_INCLUDE_PATH}/uuid/uuid.h|${libuuid.dev}/include/uuid/uuid.h|' swift/stdlib/public/Platform/glibc.modulemap.gyb
# Support library build script patches.
PREFIX=''${out/#\/}
substituteInPlace swift/utils/swift_build_support/swift_build_support/products/benchmarks.py \
--replace \
"'--toolchain', toolchain_path," \
"'--toolchain', '/build/install/$PREFIX',"
substituteInPlace swift/benchmark/scripts/build_script_helper.py \
--replace \
"swiftbuild_path = os.path.join(args.toolchain, \"usr\", \"bin\", \"swift-build\")" \
"swiftbuild_path = os.path.join(args.toolchain, \"bin\", \"swift-build\")"
substituteInPlace swift-corelibs-xctest/build_script.py \
--replace usr "$PREFIX"
# Can be removed in later swift-docc versions, see
# https://github.com/apple/swift-docc/commit/bff70b847008f91ac729cfd299a85481eef3f581
substituteInPlace swift-docc/build-script-helper.py \
--replace \
"subprocess.check_output(cmd, env=env).strip(), 'docc')" \
"subprocess.check_output(cmd, env=env).strip().decode(), 'docc')"
# Can be removed in later Swift versions, see
# https://github.com/apple/swift/pull/58755
substituteInPlace swift/utils/process-stats-dir.py \
--replace \
"type=argparse.FileType('wb', 0)," \
"type=argparse.FileType('w', 0),"
# Apply Python 3 fix, see
# https://github.com/apple/swift/commit/ec6bc595092974628b27b114a472e84162261bbd
substituteInPlace swift/utils/swift_build_support/swift_build_support/productpipeline_list_builder.py \
--replace \
"filter(lambda x: x is not None, pipeline)" \
"[p for p in pipeline if p is not None]"
'';
configurePhase = ''
cd ..
mkdir build install
export SWIFT_BUILD_ROOT=$PWD/build
export SWIFT_INSTALL_DIR=$PWD/install
export INSTALLABLE_PACKAGE=$PWD/swift.tar.gz
export NIX_ENFORCE_PURITY=
cd $SWIFT_BUILD_ROOT
'';
buildPhase = ''
# Explicitly include C++ headers to prevent errors where stdlib.h is not found from cstdlib.
export NIX_CFLAGS_COMPILE="$(< ${clang_13}/nix-support/libcxx-cxxflags) $NIX_CFLAGS_COMPILE"
# During the Swift build, a full local LLVM build is performed and the resulting clang is
# invoked. This compiler is not using the Nix wrappers, so it needs some help to find things.
export NIX_LDFLAGS_BEFORE="-rpath ${gccForLibs.lib}/lib -L${gccForLibs.lib}/lib $NIX_LDFLAGS_BEFORE"
# However, we want to use the wrapped compiler whenever possible.
export CC="${clang_13}/bin/clang"
$SWIFT_SOURCE_ROOT/swift/utils/build-script \
--preset=buildbot_linux \
installable_package=$INSTALLABLE_PACKAGE \
install_prefix=$out \
install_destdir=$SWIFT_INSTALL_DIR \
extra_cmake_options="${lib.concatStringsSep "," cmakeFlags}"
'';
doCheck = true;
checkInputs = [ file ];
checkPhase = ''
# Remove compiler build system tests which fail due to our modified default build profile and
# nixpkgs-provided version of CMake.
rm $SWIFT_SOURCE_ROOT/swift/validation-test/BuildSystem/infer_implies_install_all.test
rm $SWIFT_SOURCE_ROOT/swift/validation-test/BuildSystem/infer_dumps_deps_if_verbose_build.test
# This test apparently requires Python 2 (strings are assumed to be bytes-like), but the build
# process overall now otherwise requires Python 3 (which is what we have updated to). A fix PR
# has been submitted upstream.
rm $SWIFT_SOURCE_ROOT/swift/validation-test/SIL/verify_all_overlays.py
# TODO: consider fixing and re-adding. This test fails due to a non-standard "install_prefix".
rm $SWIFT_SOURCE_ROOT/swift/validation-test/Python/build_swift.swift
# We cannot handle the SDK location being in "Weird Location" due to Nix isolation.
rm $SWIFT_SOURCE_ROOT/swift/test/DebugInfo/compiler-flags.swift
# TODO: Fix issue with ld.gold invoked from script finding crtbeginS.o and crtendS.o.
rm $SWIFT_SOURCE_ROOT/swift/test/IRGen/ELF-remove-autolink-section.swift
# The following two tests fail because we use don't use the bundled libicu:
# [SOURCE_DIR/utils/build-script] ERROR: can't find source directory for libicu (tried /build/src/icu)
rm $SWIFT_SOURCE_ROOT/swift/validation-test/BuildSystem/default_build_still_performs_epilogue_opts_after_split.test
rm $SWIFT_SOURCE_ROOT/swift/validation-test/BuildSystem/test_early_swift_driver_and_infer.swift
# TODO: This test fails for some unknown reason
rm $SWIFT_SOURCE_ROOT/swift/test/Serialization/restrict-swiftmodule-to-revision.swift
# This test was flaky in ofborg, see #186476
rm $SWIFT_SOURCE_ROOT/swift/test/AutoDiff/compiler_crashers_fixed/sr14290-missing-debug-scopes-in-pullback-trampoline.swift
# TODO: consider using stress-tester and integration-test.
# Match the wrapped version of Swift to be installed.
export LIBRARY_PATH=${lib.makeLibraryPath [icu libgcc libuuid]}:$l
checkTarget=check-swift-all-${stdenv.hostPlatform.parsed.kernel.name}-${stdenv.hostPlatform.parsed.cpu.name}
ninjaFlags='-C buildbot_linux/swift-${stdenv.hostPlatform.parsed.kernel.name}-${stdenv.hostPlatform.parsed.cpu.name}'
ninjaCheckPhase
'';
installPhase = ''
mkdir -p $out
# Extract the generated tarball into the store.
tar xf $INSTALLABLE_PACKAGE -C $out --strip-components=3 ''${out/#\/}
find $out -type d -empty -delete
# Fix installation weirdness, also present in Apples official tarballs.
mv $out/local/include/indexstore $out/include
rmdir $out/local/include $out/local
rm -r $out/bin/sdk-module-lists $out/bin/swift-api-checker.py
wrapProgram $out/bin/swift \
--set CC $out/bin/clang \
--suffix C_INCLUDE_PATH : $out/lib/swift/clang/include \
--suffix CPLUS_INCLUDE_PATH : $out/lib/swift/clang/include \
--suffix LIBRARY_PATH : ${lib.makeLibraryPath [icu libgcc libuuid]} \
--suffix PATH : ${lib.makeBinPath [ stdenv.cc.bintools ]}
wrapProgram $out/bin/swiftc \
--set CC $out/bin/clang \
--suffix C_INCLUDE_PATH : $out/lib/swift/clang/include \
--suffix CPLUS_INCLUDE_PATH : $out/lib/swift/clang/include \
--suffix LIBRARY_PATH : ${lib.makeLibraryPath [icu libgcc libuuid]} \
--suffix PATH : ${lib.makeBinPath [ stdenv.cc.bintools ]}
'';
# Hack to avoid build and install directories in RPATHs.
preFixup = "rm -rf $SWIFT_BUILD_ROOT $SWIFT_INSTALL_DIR";
meta = with lib; {
description = "The Swift Programming Language";
homepage = "https://github.com/apple/swift";
maintainers = with maintainers; [ dtzWill trepetti dduan trundle ];
license = licenses.asl20;
# Swift doesn't support 32-bit Linux, unknown on other platforms.
platforms = platforms.linux;
badPlatforms = platforms.i686;
timeout = 86400; # 24 hours.
};
}
in self

View File

@ -1,13 +0,0 @@
Don't build Ninja, we use our own.
--- a/utils/build-presets.ini
+++ b/utils/build-presets.ini
@@ -779,7 +779,7 @@ swiftpm
dash-dash
-build-ninja
+# build-ninja
install-llvm
install-swift
install-lldb

View File

@ -1,13 +0,0 @@
Use custom install prefix.
--- a/utils/build-presets.ini
+++ b/utils/build-presets.ini
@@ -788,7 +788,7 @@
install-swiftpm
install-xctest
install-libicu
-install-prefix=/usr
+install-prefix=%(install_prefix)s
install-libcxx
install-sourcekit-lsp
build-swift-static-stdlib

View File

@ -1,23 +0,0 @@
Disable targets, where we use Nix packages.
--- a/utils/build-presets.ini
+++ b/utils/build-presets.ini
@@ -818,8 +818,6 @@
swiftpm
swift-driver
xctest
-libicu
-libcxx
swiftdocc
# build-ninja
@@ -830,9 +828,7 @@
install-swiftpm
install-swift-driver
install-xctest
-install-libicu
install-prefix=%(install_prefix)s
-install-libcxx
install-sourcekit-lsp
install-swiftdocc
build-swift-static-stdlib

View File

@ -1,13 +0,0 @@
Plumb extra-cmake-options.
--- a/utils/build-presets.ini
+++ b/utils/build-presets.ini
@@ -812,6 +812,8 @@
# Path to the .tar.gz package we would create.
installable-package=%(installable_package)s
+extra-cmake-options=%(extra_cmake_options)s
+
[preset: buildbot_linux]
mixin-preset=mixin_linux_installation
build-subdir=buildbot_linux

View File

@ -1,16 +0,0 @@
Apply the "purity" patch (updated for 5.4.2).
--- a/lib/Driver/ToolChains/Gnu.cpp
+++ b/lib/Driver/ToolChains/Gnu.cpp
@@ -488,11 +488,5 @@
if (Args.hasArg(options::OPT_rdynamic))
CmdArgs.push_back("-export-dynamic");
-
- if (!Args.hasArg(options::OPT_shared) && !IsStaticPIE) {
- CmdArgs.push_back("-dynamic-linker");
- CmdArgs.push_back(Args.MakeArgString(Twine(D.DyldPrefix) +
- ToolChain.getDynamicLinker(Args)));
- }
}
CmdArgs.push_back("-o");

View File

@ -1,13 +0,0 @@
Use os-stdlib in tests.
--- a/utils/build-presets.ini
+++ b/utils/build-presets.ini
@@ -872,7 +872,7 @@
indexstore-db
sourcekit-lsp
swiftdocc
-lit-args=-v --time-tests
+lit-args=-v --time-tests --param use_os_stdlib
# rdar://problem/31454823
lldb-test-swift-only

View File

@ -0,0 +1,50 @@
{ stdenv
, swift
, wrapperParams ? swift._wrapperParams
}:
stdenv.mkDerivation (wrapperParams // {
pname = "swift-wrapper";
inherit (swift) version meta;
outputs = [ "out" "man" ];
# Setup hook variables.
inherit swift;
inherit (swift)
swiftOs swiftArch
swiftModuleSubdir swiftLibSubdir
swiftStaticModuleSubdir swiftStaticLibSubdir;
passAsFile = [ "buildCommand" ];
buildCommand = ''
mkdir -p $out/bin $out/nix-support
# Symlink all Swift binaries first.
# NOTE: This specifically omits clang binaries. We want to hide these for
# private use by Swift only.
ln -s -t $out/bin/ $swift/bin/swift*
# Replace specific binaries with wrappers.
for executable in swift swiftc swift-frontend; do
export prog=$swift/bin/$executable
rm $out/bin/$executable
substituteAll '${./wrapper.sh}' $out/bin/$executable
chmod a+x $out/bin/$executable
done
ln -s ${swift.man} $man
# This link is here because various tools (swiftpm) check for stdlib
# relative to the swift compiler. It's fine if this is for build-time
# stuff, but we should patch all cases were it would end up in an output.
ln -s ${swift.lib}/lib $out/lib
substituteAll ${./setup-hook.sh} $out/nix-support/setup-hook
'';
passthru = {
inherit swift;
inherit (swift) swiftOs swiftArch swiftModuleSubdir swiftLibSubdir;
};
})

View File

@ -0,0 +1,28 @@
# Add import paths for build inputs.
swiftWrapper_addImports () {
# Include subdirectories following both the Swift platform convention, and
# a simple `lib/swift` for Nix convenience.
for subdir in @swiftModuleSubdir@ @swiftStaticModuleSubdir@ lib/swift; do
if [[ -d "$1/$subdir" ]]; then
export NIX_SWIFTFLAGS_COMPILE+=" -I $1/$subdir"
fi
done
for subdir in @swiftLibSubdir@ @swiftStaticLibSubdir@ lib/swift; do
if [[ -d "$1/$subdir" ]]; then
export NIX_LDFLAGS+=" -L $1/$subdir"
fi
done
}
addEnvHooks "$targetOffset" swiftWrapper_addImports
# Use a postHook here because we rely on NIX_CC, which is set by the cc-wrapper
# setup hook, so delay until we're sure it was run.
swiftWrapper_postHook () {
# On Darwin, libc also contains Swift modules.
if [[ -e "$NIX_CC/nix-support/orig-libc" ]]; then
swiftWrapper_addImports "$(<$NIX_CC/nix-support/orig-libc)"
fi
}
postHooks+=(swiftWrapper_postHook)

View File

@ -0,0 +1,266 @@
#! @shell@
# NOTE: This wrapper is derived from cc-wrapper.sh, and is hopefully somewhat
# diffable with the original, so changes can be merged if necessary.
set -eu -o pipefail +o posix
shopt -s nullglob
if (( "${NIX_DEBUG:-0}" >= 7 )); then
set -x
fi
cc_wrapper="${NIX_CC:-@default_cc_wrapper@}"
source $cc_wrapper/nix-support/utils.bash
expandResponseParams "$@"
# Check if we should wrap this Swift invocation at all, and how. Specifically,
# there are some internal tools we don't wrap, plus swift-frontend doesn't link
# and doesn't understand linker flags. This follows logic in
# `lib/DriverTool/driver.cpp`.
prog=@prog@
progName="$(basename "$prog")"
firstArg="${params[0]:-}"
isFrontend=0
isRepl=0
# These checks follow `shouldRunAsSubcommand`.
if [[ "$progName" == swift ]]; then
case "$firstArg" in
"" | -* | *.* | */* | repl)
;;
*)
exec "swift-$firstArg" "${params[@]:1}"
;;
esac
fi
# These checks follow the first part of `run_driver`.
#
# NOTE: The original function short-circuits, but we can't here, because both
# paths must be wrapped. So we use an 'isFrontend' flag instead.
case "$firstArg" in
-frontend)
isFrontend=1
# Ensure this stays the first argument.
params=( "${params[@]:1}" )
extraBefore+=( "-frontend" )
;;
-modulewrap)
# Don't wrap this integrated tool.
exec "$prog" "${params[@]}"
;;
repl)
isRepl=1
params=( "${params[@]:1}" )
;;
--driver-mode=*)
;;
*)
if [[ "$progName" == swift-frontend ]]; then
isFrontend=1
fi
;;
esac
path_backup="$PATH"
# That @-vars are substituted separately from bash evaluation makes
# shellcheck think this, and others like it, are useless conditionals.
# shellcheck disable=SC2157
if [[ -n "@coreutils_bin@" && -n "@gnugrep_bin@" ]]; then
PATH="@coreutils_bin@/bin:@gnugrep_bin@/bin"
fi
# Parse command line options and set several variables.
# For instance, figure out if linker flags should be passed.
# GCC prints annoying warnings when they are not needed.
isCxx=0
dontLink=$isFrontend
for p in "${params[@]}"; do
case "$p" in
-enable-cxx-interop)
isCxx=1 ;;
esac
done
# NOTE: We don't modify these for Swift, but sourced scripts may use them.
cxxInclude=1
cxxLibrary=1
cInclude=1
linkType=$(checkLinkType "${params[@]}")
# Optionally filter out paths not refering to the store.
if [[ "${NIX_ENFORCE_PURITY:-}" = 1 && -n "$NIX_STORE" ]]; then
kept=()
nParams=${#params[@]}
declare -i n=0
while (( "$n" < "$nParams" )); do
p=${params[n]}
p2=${params[n+1]:-} # handle `p` being last one
n+=1
skipNext=false
path=""
case "$p" in
-[IL]/*) path=${p:2} ;;
-[IL]) path=$p2 skipNext=true ;;
esac
if [[ -n $path ]] && badPath "$path"; then
skip "$path"
$skipNext && n+=1
continue
fi
kept+=("$p")
done
# Old bash empty array hack
params=(${kept+"${kept[@]}"})
fi
# Flirting with a layer violation here.
if [ -z "${NIX_BINTOOLS_WRAPPER_FLAGS_SET_@suffixSalt@:-}" ]; then
source @bintools@/nix-support/add-flags.sh
fi
# Put this one second so libc ldflags take priority.
if [ -z "${NIX_CC_WRAPPER_FLAGS_SET_@suffixSalt@:-}" ]; then
source $cc_wrapper/nix-support/add-flags.sh
fi
if [[ "$isCxx" = 1 ]]; then
if [[ "$cxxInclude" = 1 ]]; then
NIX_CFLAGS_COMPILE_@suffixSalt@+=" $NIX_CXXSTDLIB_COMPILE_@suffixSalt@"
fi
if [[ "$cxxLibrary" = 1 ]]; then
NIX_CFLAGS_LINK_@suffixSalt@+=" $NIX_CXXSTDLIB_LINK_@suffixSalt@"
fi
fi
source $cc_wrapper/nix-support/add-hardening.sh
# Add the flags for the C compiler proper.
addCFlagsToList() {
declare -n list="$1"
shift
for ((i = 1; i <= $#; i++)); do
local val="${!i}"
case "$val" in
# Pass through using -Xcc, but also convert to Swift -I.
# These have slightly different meaning for Clang, but Swift
# doesn't have exact equivalents.
-isystem | -idirafter)
i=$((i + 1))
list+=("-Xcc" "$val" "-Xcc" "${!i}" "-I" "${!i}")
;;
# Simple rename.
-iframework)
i=$((i + 1))
list+=("-Fsystem" "${!i}")
;;
# Pass through verbatim.
-I | -Fsystem)
i=$((i + 1))
list+=("${val}" "${!i}")
;;
-I* | -L* | -F*)
list+=("${val}")
;;
# Pass through using -Xcc.
*)
list+=("-Xcc" "$val")
;;
esac
done
}
for i in ${NIX_SWIFTFLAGS_COMPILE:-}; do
extraAfter+=("$i")
done
for i in ${NIX_SWIFTFLAGS_COMPILE_BEFORE:-}; do
extraBefore+=("$i")
done
addCFlagsToList extraAfter $NIX_CFLAGS_COMPILE_@suffixSalt@
addCFlagsToList extraBefore ${hardeningCFlags[@]+"${hardeningCFlags[@]}"} $NIX_CFLAGS_COMPILE_BEFORE_@suffixSalt@
if [ "$dontLink" != 1 ]; then
# Add the flags that should only be passed to the compiler when
# linking.
addCFlagsToList extraAfter $(filterRpathFlags "$linkType" $NIX_CFLAGS_LINK_@suffixSalt@)
# Add the flags that should be passed to the linker (and prevent
# `ld-wrapper' from adding NIX_LDFLAGS_@suffixSalt@ again).
for i in $(filterRpathFlags "$linkType" $NIX_LDFLAGS_BEFORE_@suffixSalt@); do
extraBefore+=("-Xlinker" "$i")
done
if [[ "$linkType" == dynamic && -n "$NIX_DYNAMIC_LINKER_@suffixSalt@" ]]; then
extraBefore+=("-Xlinker" "-dynamic-linker=$NIX_DYNAMIC_LINKER_@suffixSalt@")
fi
for i in $(filterRpathFlags "$linkType" $NIX_LDFLAGS_@suffixSalt@); do
if [ "${i:0:3}" = -L/ ]; then
extraAfter+=("$i")
else
extraAfter+=("-Xlinker" "$i")
fi
done
export NIX_LINK_TYPE_@suffixSalt@=$linkType
fi
# TODO: If we ever need to expand functionality of this hook, it may no longer
# be compatible with Swift. Right now, it is only used on Darwin to force
# -target, which also happens to work with Swift.
if [[ -e $cc_wrapper/nix-support/add-local-cc-cflags-before.sh ]]; then
source $cc_wrapper/nix-support/add-local-cc-cflags-before.sh
fi
# May need to transform the triple injected by the above.
for ((i = 1; i < ${#extraBefore[@]}; i++)); do
if [[ "${extraBefore[i]}" = -target ]]; then
i=$((i + 1))
# On Darwin only, need to change 'aarch64' to 'arm64'.
extraBefore[i]="${extraBefore[i]/aarch64-apple-/arm64-apple-}"
# On Darwin, Swift requires the triple to be annotated with a version.
# TODO: Assumes macOS.
extraBefore[i]="${extraBefore[i]/-apple-darwin/-apple-macosx${MACOSX_DEPLOYMENT_TARGET:-11.0}}"
break
fi
done
# As a very special hack, if the arguments are just `-v', then don't
# add anything. This is to prevent `gcc -v' (which normally prints
# out the version number and returns exit code 0) from printing out
# `No input files specified' and returning exit code 1.
if [ "$*" = -v ]; then
extraAfter=()
extraBefore=()
fi
# Optionally print debug info.
if (( "${NIX_DEBUG:-0}" >= 1 )); then
# Old bash workaround, see ld-wrapper for explanation.
echo "extra flags before to $prog:" >&2
printf " %q\n" ${extraBefore+"${extraBefore[@]}"} >&2
echo "original flags to $prog:" >&2
printf " %q\n" ${params+"${params[@]}"} >&2
echo "extra flags after to $prog:" >&2
printf " %q\n" ${extraAfter+"${extraAfter[@]}"} >&2
fi
PATH="$path_backup"
# Old bash workaround, see above.
if (( "${NIX_CC_USE_RESPONSE_FILE:-@use_response_file_by_default@}" >= 1 )); then
exec "$prog" @<(printf "%q\n" \
${extraBefore+"${extraBefore[@]}"} \
${params+"${params[@]}"} \
${extraAfter+"${extraAfter[@]}"})
else
exec "$prog" \
${extraBefore+"${extraBefore[@]}"} \
${params+"${params[@]}"} \
${extraAfter+"${extraAfter[@]}"}
fi

View File

@ -3,16 +3,7 @@
, xar, cpio, python3, pbzx }:
let
MacOSX-SDK = stdenvNoCC.mkDerivation rec {
pname = "MacOSX-SDK";
version = "11.0.0";
# https://swscan.apple.com/content/catalogs/others/index-11-10.15-10.14-10.13-10.12-10.11-10.10-10.9-mountainlion-lion-snowleopard-leopard.merged-1.sucatalog
src = fetchurl {
url = "http://swcdn.apple.com/content/downloads/46/21/001-89745-A_56FM390IW5/v1um2qppgfdnam2e9cdqcqu2r6k8aa3lis/CLTools_macOSNMOS_SDK.pkg";
sha256 = "0n425smj4q1vxbza8fzwnk323fyzbbq866q32w288c44hl5yhwsf";
};
mkSusDerivation = args: stdenvNoCC.mkDerivation (args // {
dontBuild = true;
darwinDontCodeSign = true;
@ -24,16 +15,45 @@ let
pbzx $src | cpio -idm
'';
passthru = {
inherit (args) version;
};
});
MacOSX-SDK = mkSusDerivation {
pname = "MacOSX-SDK";
version = "11.0.0";
# https://swscan.apple.com/content/catalogs/others/index-11-10.15-10.14-10.13-10.12-10.11-10.10-10.9-mountainlion-lion-snowleopard-leopard.merged-1.sucatalog
src = fetchurl {
url = "http://swcdn.apple.com/content/downloads/46/21/001-89745-A_56FM390IW5/v1um2qppgfdnam2e9cdqcqu2r6k8aa3lis/CLTools_macOSNMOS_SDK.pkg";
sha256 = "0n425smj4q1vxbza8fzwnk323fyzbbq866q32w288c44hl5yhwsf";
};
installPhase = ''
cd Library/Developer/CommandLineTools/SDKs/MacOSX11.1.sdk
mkdir $out
cp -r System usr $out/
'';
};
passthru = {
inherit version;
CLTools_Executables = mkSusDerivation {
pname = "CLTools_Executables";
version = "11.0.0";
# https://swscan.apple.com/content/catalogs/others/index-11-10.15-10.14-10.13-10.12-10.11-10.10-10.9-mountainlion-lion-snowleopard-leopard.merged-1.sucatalog
src = fetchurl {
url = "http://swcdn.apple.com/content/downloads/46/21/001-89745-A_56FM390IW5/v1um2qppgfdnam2e9cdqcqu2r6k8aa3lis/CLTools_Executables.pkg";
sha256 = "0nvb1qx7l81l2wcl8wvgbpsg5rcn51ylhivqmlfr2hrrv3zrrpl0";
};
installPhase = ''
cd Library/Developer/CommandLineTools
mkdir $out
cp -r Library usr $out/
'';
};
callPackage = newScope (packages // pkgs.darwin // { inherit MacOSX-SDK; });
@ -43,7 +63,7 @@ let
# TODO: this is nice to be private. is it worth the callPackage above?
# Probably, I don't think that callPackage costs much at all.
inherit MacOSX-SDK;
inherit MacOSX-SDK CLTools_Executables;
Libsystem = callPackage ./libSystem.nix {};
LibsystemCross = pkgs.darwin.Libsystem;

View File

@ -15041,7 +15041,8 @@ with pkgs;
svdtools = callPackage ../development/embedded/svdtools { };
swift = callPackage ../development/compilers/swift { };
swiftPackages = recurseIntoAttrs (callPackage ../development/compilers/swift { });
inherit (swiftPackages) swift;
swiProlog = callPackage ../development/compilers/swi-prolog {
openssl = openssl_1_1;