Merge pull request #287609 from reckenrode/darwin-stdenv-improvements
darwin.stdenv: improvements and overrideSDK rewrite
This commit is contained in:
commit
81a44b6680
|
@ -105,6 +105,8 @@ let
|
|||
# conflicting LLVM modules.
|
||||
objc4 = stdenv.objc4 or (callPackage ./libobjc.nix { });
|
||||
|
||||
sdkRoot = pkgs.callPackage ../apple-sdk/sdkRoot.nix { sdkVersion = "11.0"; };
|
||||
|
||||
# questionable aliases
|
||||
configd = pkgs.darwin.apple_sdk.frameworks.SystemConfiguration;
|
||||
inherit (pkgs.darwin.apple_sdk.frameworks) IOKit;
|
||||
|
|
|
@ -352,5 +352,11 @@ in rec {
|
|||
|
||||
inherit darwin-stubs;
|
||||
|
||||
objc4 = pkgs.darwin.libobjc;
|
||||
|
||||
sdkRoot = pkgs.callPackage ./sdkRoot.nix { sdkVersion = "10.12"; };
|
||||
|
||||
inherit (pkgs.darwin) Libsystem;
|
||||
|
||||
inherit sdk;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,68 @@
|
|||
{
|
||||
lib,
|
||||
runCommand,
|
||||
writeText,
|
||||
sdkVersion,
|
||||
}:
|
||||
|
||||
let
|
||||
sdkName = "MacOSX${sdkVersion}";
|
||||
toolchainName = "com.apple.dt.toolchain.XcodeDefault";
|
||||
productBuildVer = null;
|
||||
|
||||
inherit (lib.generators) toPlist toJSON;
|
||||
|
||||
SDKSettings = {
|
||||
CanonicalName = "macosx${sdkVersion}";
|
||||
DisplayName = "macOS ${sdkVersion}";
|
||||
Toolchains = [ toolchainName ];
|
||||
Version = sdkVersion;
|
||||
MaximumDeploymentTarget = "${sdkVersion}.99";
|
||||
isBaseSDK = "YES";
|
||||
};
|
||||
|
||||
SystemVersion =
|
||||
lib.optionalAttrs (productBuildVer != null) { ProductBuildVersion = productBuildVer; }
|
||||
// {
|
||||
ProductName = "macOS";
|
||||
ProductVersion = sdkVersion;
|
||||
};
|
||||
in
|
||||
runCommand "sdkroot-${sdkVersion}" { } ''
|
||||
sdk="$out/${sdkName}.sdk"
|
||||
|
||||
install -D ${writeText "SDKSettings.plist" (toPlist { } SDKSettings)} "$sdk/SDKSettings.plist"
|
||||
install -D ${writeText "SDKSettings.json" (toJSON { } SDKSettings)} "$sdk/SDKSettings.json"
|
||||
install -D ${
|
||||
writeText "SystemVersion.plist" (toPlist { } SystemVersion)
|
||||
} "$sdk/System/Library/CoreServices/SystemVersion.plist"
|
||||
|
||||
ln -s "$sdk" "$sdk/usr"
|
||||
|
||||
install -D '${../../../build-support/setup-hooks/role.bash}' "$out/nix-support/setup-hook"
|
||||
cat >> "$out/nix-support/setup-hook" <<-hook
|
||||
#
|
||||
# See comments in cc-wrapper's setup hook. This works exactly the same way.
|
||||
#
|
||||
[[ -z \''${strictDeps-} ]] || (( "\$hostOffset" < 0 )) || return 0
|
||||
|
||||
sdkRootHook() {
|
||||
# See ../../../build-support/setup-hooks/role.bash
|
||||
local role_post
|
||||
getHostRoleEnvHook
|
||||
|
||||
# Only set the SDK root if one has not been set via this hook or some other means.
|
||||
if [[ ! \$NIX_CFLAGS_COMPILE =~ isysroot ]]; then
|
||||
export NIX_CFLAGS_COMPILE\''${role_post}+=' -isysroot $out/${sdkName}.sdk'
|
||||
fi
|
||||
}
|
||||
|
||||
# See ../../../build-support/setup-hooks/role.bash
|
||||
getTargetRole
|
||||
|
||||
addEnvHooks "\$targetOffset" sdkRootHook
|
||||
|
||||
# No local scope in sourced file
|
||||
unset -v role_post
|
||||
hook
|
||||
''
|
|
@ -317,125 +317,17 @@ rec {
|
|||
# `sdkVersion` can be any of the following:
|
||||
# * A version string indicating the requested SDK version; or
|
||||
# * An attrset consisting of either or both of the following fields: darwinSdkVersion and darwinMinVersion.
|
||||
overrideSDK = stdenv: sdkVersion:
|
||||
let
|
||||
inherit (
|
||||
{ inherit (stdenv.hostPlatform) darwinMinVersion darwinSdkVersion; }
|
||||
// (if lib.isAttrs sdkVersion then sdkVersion else { darwinSdkVersion = sdkVersion; })
|
||||
) darwinMinVersion darwinSdkVersion;
|
||||
|
||||
sdk = pkgs.darwin."apple_sdk_${lib.replaceStrings [ "." ] [ "_" ] darwinSdkVersion}";
|
||||
# TODO: Make this unconditional after #229210 has been merged,
|
||||
# and the 10.12 SDK is updated to follow the new structure.
|
||||
Libsystem = if darwinSdkVersion == "10.12" then pkgs.darwin.Libsystem else sdk.Libsystem;
|
||||
|
||||
replacePropagatedFrameworks = pkg:
|
||||
let
|
||||
propagatedInputs = pkg.propagatedBuildInputs;
|
||||
mappedInputs = map mapPackageToSDK propagatedInputs;
|
||||
|
||||
env = {
|
||||
inherit (pkg) outputs;
|
||||
# Map old frameworks to new ones and the package’s outputs to their original outPaths.
|
||||
# Also map any packages that have propagated frameworks to their proxy packages using
|
||||
# the requested SDK version. These mappings are rendered into tab-separated files to be
|
||||
# parsed and read back with `read`.
|
||||
dependencies = lib.concatMapStrings (pair: "${pair.fst}\t${pair.snd}\n") (lib.zipLists propagatedInputs mappedInputs);
|
||||
pkgOutputs = lib.concatMapStrings (output: "${output}\t${(lib.getOutput output pkg).outPath}\n") pkg.outputs;
|
||||
passAsFile = [ "dependencies" "pkgOutputs" ];
|
||||
};
|
||||
in
|
||||
# Only remap the package’s propagated inputs if there are any and if any of them were themselves remapped.
|
||||
if lib.length propagatedInputs > 0 && propagatedInputs != mappedInputs
|
||||
then pkgs.runCommand pkg.name env ''
|
||||
# Iterate over the outputs in the package being replaced to make sure the proxy is
|
||||
# a fully functional replacement. This is like `symlinkJoin` except for outputs and
|
||||
# the contents of `nix-support`, which will be customized for the requested SDK.
|
||||
while IFS=$'\t\n' read -r outputName pkgOutputPath; do
|
||||
mkdir -p "''${!outputName}"
|
||||
|
||||
for targetPath in "$pkgOutputPath"/*; do
|
||||
targetName=$(basename "$targetPath")
|
||||
|
||||
# `nix-support` is special-cased because any propagated inputs need their SDK
|
||||
# frameworks replaced with those from the requested SDK.
|
||||
if [ "$targetName" == "nix-support" ]; then
|
||||
mkdir "''${!outputName}/nix-support"
|
||||
|
||||
for file in "$targetPath"/*; do
|
||||
fileName=$(basename "$file")
|
||||
|
||||
if [ "$fileName" == "propagated-build-inputs" ]; then
|
||||
cp "$file" "''${!outputName}/nix-support/$fileName"
|
||||
|
||||
while IFS=$'\t\n' read -r oldFramework newFramework; do
|
||||
substituteInPlace "''${!outputName}/nix-support/$fileName" \
|
||||
--replace "$oldFramework" "$newFramework"
|
||||
done < "$dependenciesPath"
|
||||
fi
|
||||
done
|
||||
else
|
||||
ln -s "$targetPath" "''${!outputName}/$targetName"
|
||||
fi
|
||||
done
|
||||
done < "$pkgOutputsPath"
|
||||
''
|
||||
else pkg;
|
||||
|
||||
# Remap a framework from one SDK version to another.
|
||||
mapPackageToSDK = pkg:
|
||||
let
|
||||
name = lib.getName pkg;
|
||||
framework = lib.removePrefix "apple-framework-" name;
|
||||
in
|
||||
/**/ if pkg == null then pkg
|
||||
else if name != framework then sdk.frameworks."${framework}"
|
||||
else replacePropagatedFrameworks pkg;
|
||||
|
||||
mapRuntimeToSDK = pkg:
|
||||
# Only remap xcbuild for now, which exports the SDK used to build it.
|
||||
if pkg != null && lib.isAttrs pkg && lib.getName pkg == "xcodebuild"
|
||||
then pkg.override { stdenv = overrideSDK stdenv { inherit darwinMinVersion darwinSdkVersion; }; }
|
||||
else pkg;
|
||||
|
||||
mapInputsToSDK = inputs: args:
|
||||
let
|
||||
runsAtBuild = lib.flip lib.elem [
|
||||
"depsBuildBuild"
|
||||
"depsBuildBuildPropagated"
|
||||
"nativeBuildInputs"
|
||||
"propagatedNativeBuildInputs"
|
||||
"depsBuildTarget"
|
||||
"depsBuildTargetPropagated"
|
||||
];
|
||||
atBuildInputs = lib.filter runsAtBuild inputs;
|
||||
atRuntimeInputs = lib.subtractLists atBuildInputs inputs;
|
||||
in
|
||||
lib.genAttrs atRuntimeInputs (input: map mapPackageToSDK (args."${input}" or [ ]))
|
||||
// lib.genAttrs atBuildInputs (input: map mapRuntimeToSDK (args."${input}" or [ ]));
|
||||
|
||||
mkCC = cc: cc.override {
|
||||
bintools = cc.bintools.override { libc = Libsystem; };
|
||||
libc = Libsystem;
|
||||
};
|
||||
in
|
||||
# TODO: make this work across all input types and not just propagatedBuildInputs
|
||||
stdenv.override (old: {
|
||||
buildPlatform = old.buildPlatform // { inherit darwinMinVersion darwinSdkVersion; };
|
||||
hostPlatform = old.hostPlatform // { inherit darwinMinVersion darwinSdkVersion; };
|
||||
targetPlatform = old.targetPlatform // { inherit darwinMinVersion darwinSdkVersion; };
|
||||
|
||||
allowedRequisites = null;
|
||||
cc = mkCC old.cc;
|
||||
|
||||
extraBuildInputs = [sdk.frameworks.CoreFoundation ];
|
||||
mkDerivationFromStdenv = extendMkDerivationArgs old (mapInputsToSDK [
|
||||
"buildInputs"
|
||||
"nativeBuildInputs"
|
||||
"propagatedNativeBuildInputs"
|
||||
"propagatedBuildInputs"
|
||||
]);
|
||||
});
|
||||
overrideSDK = import ./darwin/override-sdk.nix {
|
||||
inherit lib extendMkDerivationArgs;
|
||||
inherit (pkgs)
|
||||
stdenvNoCC
|
||||
pkgsBuildBuild
|
||||
pkgsBuildHost
|
||||
pkgsBuildTarget
|
||||
pkgsHostHost
|
||||
pkgsHostTarget
|
||||
pkgsTargetTarget;
|
||||
};
|
||||
|
||||
withDefaultHardeningFlags = defaultHardeningFlags: stdenv: let
|
||||
bintools = let
|
||||
|
|
|
@ -135,9 +135,11 @@ let
|
|||
hostPlatform = localSystem;
|
||||
targetPlatform = localSystem;
|
||||
|
||||
inherit config extraNativeBuildInputs;
|
||||
inherit config;
|
||||
|
||||
extraBuildInputs = [ prevStage.darwin.CF ];
|
||||
extraNativeBuildInputs = extraNativeBuildInputs
|
||||
++ [ prevStage.darwin.apple_sdk.sdkRoot ];
|
||||
|
||||
preHook = lib.optionalString (!isBuiltByNixpkgsCompiler bash) ''
|
||||
# Don't patch #!/interpreter because it leads to retained
|
||||
|
@ -196,6 +198,7 @@ in
|
|||
cpio = null;
|
||||
|
||||
darwin = {
|
||||
apple_sdk.sdkRoot = null;
|
||||
binutils = null;
|
||||
binutils-unwrapped = null;
|
||||
cctools = null;
|
||||
|
@ -244,7 +247,7 @@ in
|
|||
version = "boot";
|
||||
};
|
||||
|
||||
binutils = (import ../../build-support/bintools-wrapper) {
|
||||
binutils = super.wrapBintoolsWith {
|
||||
name = "bootstrap-stage0-binutils-wrapper";
|
||||
|
||||
nativeTools = false;
|
||||
|
@ -435,6 +438,10 @@ in
|
|||
});
|
||||
|
||||
darwin = super.darwin.overrideScope (selfDarwin: superDarwin: {
|
||||
apple_sdk = superDarwin.apple_sdk // {
|
||||
inherit (prevStage.darwin.apple_sdk) sdkRoot;
|
||||
};
|
||||
|
||||
# Use this stage’s CF to build configd. It’s required but can’t be included in the stdenv.
|
||||
configd = superDarwin.configd.overrideAttrs (old: {
|
||||
buildInputs = old.buildInputs or [ ] ++ [ self.darwin.CF ];
|
||||
|
@ -500,7 +507,7 @@ in
|
|||
assert lib.all isFromBootstrapFiles (with prevStage; [ coreutils gnugrep ]);
|
||||
|
||||
assert lib.all isBuiltByBootstrapFilesCompiler (with prevStage; [
|
||||
autoconf automake bash binutils-unwrapped bison brotli cmake cpio curl cyrus_sasl db
|
||||
autoconf automake bash binutils-unwrapped bison brotli cmake cpio cyrus_sasl db
|
||||
ed expat flex gettext gmp groff icu libedit libffi libiconv libidn2 libkrb5 libssh2
|
||||
libtool libunistring libxml2 m4 ncurses nghttp2 ninja openldap openssh openssl
|
||||
patchutils pbzx perl pkg-config.pkg-config python3 python3Minimal scons serf sqlite
|
||||
|
@ -527,7 +534,7 @@ in
|
|||
overrides = self: super: {
|
||||
inherit (prevStage) ccWrapperStdenv
|
||||
autoconf automake bash binutils binutils-unwrapped bison brotli cmake cmakeMinimal
|
||||
coreutils cpio curl cyrus_sasl db ed expat flex gettext gmp gnugrep groff icu
|
||||
coreutils cpio cyrus_sasl db ed expat flex gettext gmp gnugrep groff icu
|
||||
libedit libffi libiconv libidn2 libkrb5 libssh2 libtool libunistring libxml2 m4
|
||||
ncurses nghttp2 ninja openldap openssh openssl patchutils pbzx perl pkg-config
|
||||
python3Minimal scons sed serf sharutils sqlite subversion texinfo unzip which xz
|
||||
|
@ -558,9 +565,13 @@ in
|
|||
|
||||
darwin = super.darwin.overrideScope (_: superDarwin: {
|
||||
inherit (prevStage.darwin)
|
||||
CF Libsystem binutils-unwrapped cctools cctools-port configd darwin-stubs dyld
|
||||
CF sdkRoot Libsystem binutils-unwrapped cctools cctools-port configd darwin-stubs dyld
|
||||
launchd libclosure libdispatch libobjc locale objc4 postLinkSignHook
|
||||
print-reexports rewrite-tbd signingUtils sigtool;
|
||||
|
||||
apple_sdk = superDarwin.apple_sdk // {
|
||||
inherit (prevStage.darwin.apple_sdk) sdkRoot;
|
||||
};
|
||||
});
|
||||
|
||||
llvmPackages = super.llvmPackages // (
|
||||
|
@ -599,7 +610,7 @@ in
|
|||
assert lib.all isFromBootstrapFiles (with prevStage; [ coreutils gnugrep ]);
|
||||
|
||||
assert lib.all isBuiltByBootstrapFilesCompiler (with prevStage; [
|
||||
autoconf automake bash binutils-unwrapped bison brotli cmake cpio curl cyrus_sasl db
|
||||
autoconf automake bash binutils-unwrapped bison brotli cmake cpio cyrus_sasl db
|
||||
ed expat flex gettext gmp groff icu libedit libffi libiconv libidn2 libkrb5 libssh2
|
||||
libtool libunistring libxml2 m4 ncurses nghttp2 ninja openldap openssh openssl
|
||||
patchutils pbzx perl pkg-config.pkg-config python3 python3Minimal scons serf sqlite
|
||||
|
@ -627,7 +638,7 @@ in
|
|||
overrides = self: super: {
|
||||
inherit (prevStage) ccWrapperStdenv
|
||||
autoconf automake bash binutils binutils-unwrapped bison brotli cmake cmakeMinimal
|
||||
cpio curl cyrus_sasl db ed expat flex gettext gmp groff icu libedit libffi libiconv
|
||||
cpio cyrus_sasl db ed expat flex gettext gmp groff icu libedit libffi libiconv
|
||||
libidn2 libkrb5 libssh2 libtool libunistring libxml2 m4 ncurses nghttp2 ninja
|
||||
openldap openssh openssl patchutils pbzx perl pkg-config python3 python3Minimal
|
||||
scons sed serf sharutils sqlite subversion sysctl texinfo unzip which xz zlib zstd;
|
||||
|
@ -638,6 +649,10 @@ in
|
|||
CF Libsystem configd darwin-stubs dyld launchd libclosure libdispatch libobjc
|
||||
locale objc4 postLinkSignHook print-reexports rewrite-tbd signingUtils sigtool;
|
||||
|
||||
apple_sdk = superDarwin.apple_sdk // {
|
||||
inherit (prevStage.darwin.apple_sdk) sdkRoot;
|
||||
};
|
||||
|
||||
# Avoid building unnecessary Python dependencies due to building LLVM manpages.
|
||||
cctools-llvm = superDarwin.cctools-llvm.override { enableManpages = false; };
|
||||
});
|
||||
|
@ -691,7 +706,7 @@ in
|
|||
]);
|
||||
|
||||
assert lib.all isBuiltByBootstrapFilesCompiler (with prevStage; [
|
||||
brotli curl libffi libiconv libidn2 libkrb5 libssh2 libunistring libxml2 ncurses
|
||||
brotli libffi libiconv libidn2 libkrb5 libssh2 libunistring libxml2 ncurses
|
||||
nghttp2 openssl zlib zstd
|
||||
]);
|
||||
|
||||
|
@ -719,7 +734,7 @@ in
|
|||
overrides = self: super: {
|
||||
inherit (prevStage) ccWrapperStdenv
|
||||
autoconf automake binutils-unwrapped bison brotli cmake cmakeMinimal coreutils
|
||||
cpio curl cyrus_sasl db ed expat flex gettext gmp gnugrep groff icu libedit libffi
|
||||
cpio cyrus_sasl db ed expat flex gettext gmp gnugrep groff icu libedit libffi
|
||||
libiconv libidn2 libkrb5 libssh2 libtool libunistring libxml2 m4 ncurses nghttp2
|
||||
ninja openbsm openldap openpam openssh openssl patchutils pbzx perl pkg-config
|
||||
python3 python3Minimal scons serf sqlite subversion sysctl texinfo unzip which xz
|
||||
|
@ -735,6 +750,10 @@ in
|
|||
inherit (prevStage.darwin)
|
||||
CF binutils-unwrapped cctools configd darwin-stubs launchd libobjc libtapi locale
|
||||
objc4 print-reexports rewrite-tbd signingUtils sigtool;
|
||||
|
||||
apple_sdk = superDarwin.apple_sdk // {
|
||||
inherit (prevStage.darwin.apple_sdk) sdkRoot;
|
||||
};
|
||||
});
|
||||
|
||||
llvmPackages = super.llvmPackages // (
|
||||
|
@ -773,7 +792,7 @@ in
|
|||
'';
|
||||
})
|
||||
|
||||
# This stage rebuilds CF and compiler-rt.
|
||||
# This stage rebuilds CF, compiler-rt, and the sdkRoot derivation.
|
||||
#
|
||||
# CF requires:
|
||||
# - aarch64-darwin: libobjc (due to being apple_sdk.frameworks.CoreFoundation instead of swift-corefoundation)
|
||||
|
@ -782,7 +801,7 @@ in
|
|||
# previous stage2-Libsystem stdenv:
|
||||
assert lib.all isBuiltByBootstrapFilesCompiler (with prevStage; [
|
||||
autoconf automake binutils-unwrapped bison brotli cmake cmakeMinimal coreutils
|
||||
cpio curl cyrus_sasl db ed expat flex gettext gmp gnugrep groff icu libedit libidn2
|
||||
cpio cyrus_sasl db ed expat flex gettext gmp gnugrep groff icu libedit libidn2
|
||||
libkrb5 libssh2 libtool libunistring m4 nghttp2 ninja openbsm openldap openpam openssh
|
||||
openssl patchutils pbzx perl pkg-config.pkg-config python3 python3Minimal scons serf
|
||||
sqlite subversion sysctl.provider texinfo unzip which xz zstd
|
||||
|
@ -818,7 +837,7 @@ in
|
|||
|
||||
overrides = self: super: {
|
||||
inherit (prevStage) ccWrapperStdenv
|
||||
autoconf automake bash bison brotli cmake cmakeMinimal coreutils cpio curl
|
||||
autoconf automake bash bison brotli cmake cmakeMinimal coreutils cpio
|
||||
cyrus_sasl db ed expat flex gettext gmp gnugrep groff libedit libidn2 libkrb5
|
||||
libssh2 libtool libunistring m4 ncurses nghttp2 ninja openbsm openldap openpam
|
||||
openssh openssl patchutils pbzx perl pkg-config python3 python3Minimal scons serf
|
||||
|
@ -905,7 +924,7 @@ in
|
|||
(prevStage:
|
||||
# previous stage2-CF stdenv:
|
||||
assert lib.all isBuiltByBootstrapFilesCompiler (with prevStage; [
|
||||
autoconf automake bison brotli cmake cmakeMinimal coreutils cpio curl cyrus_sasl
|
||||
autoconf automake bison brotli cmake cmakeMinimal coreutils cpio cyrus_sasl
|
||||
db ed expat flex gettext gmp gnugrep groff libedit libidn2 libkrb5 libssh2 libtool
|
||||
libunistring m4 ncurses nghttp2 ninja openbsm openldap openpam openssh openssl
|
||||
patchutils pbzx perl pkg-config.pkg-config python3 python3Minimal scons serf sqlite
|
||||
|
@ -942,7 +961,7 @@ in
|
|||
overrides = self: super: {
|
||||
inherit (prevStage) ccWrapperStdenv
|
||||
autoconf automake bash binutils binutils-unwrapped bison brotli cmake cmakeMinimal
|
||||
coreutils cpio curl cyrus_sasl db ed expat flex gettext gmp gnugrep groff libedit
|
||||
coreutils cpio cyrus_sasl db ed expat flex gettext gmp gnugrep groff libedit
|
||||
libidn2 libkrb5 libssh2 libtool libunistring m4 nghttp2 ninja openbsm openldap
|
||||
openpam openssh openssl patchutils pbzx perl pkg-config python3 python3Minimal scons
|
||||
sed serf sharutils sqlite subversion sysctl texinfo unzip which xz zstd
|
||||
|
@ -958,6 +977,10 @@ in
|
|||
CF Libsystem binutils binutils-unwrapped cctools cctools-llvm cctools-port configd
|
||||
darwin-stubs dyld launchd libclosure libdispatch libobjc libtapi locale objc4
|
||||
postLinkSignHook print-reexports rewrite-tbd signingUtils sigtool;
|
||||
|
||||
apple_sdk = superDarwin.apple_sdk // {
|
||||
inherit (prevStage.darwin.apple_sdk) sdkRoot;
|
||||
};
|
||||
});
|
||||
|
||||
llvmPackages = super.llvmPackages // (
|
||||
|
@ -985,7 +1008,7 @@ in
|
|||
(prevStage:
|
||||
# previous stage3 stdenv:
|
||||
assert lib.all isBuiltByBootstrapFilesCompiler (with prevStage; [
|
||||
autoconf automake bison brotli cmake cmakeMinimal coreutils cpio curl cyrus_sasl
|
||||
autoconf automake bison brotli cmake cmakeMinimal coreutils cpio cyrus_sasl
|
||||
db ed expat flex gettext gmp gnugrep groff libedit libidn2 libkrb5 libssh2 libtool
|
||||
libunistring m4 nghttp2 ninja openbsm openldap openpam openssh openssl patchutils pbzx
|
||||
perl pkg-config.pkg-config python3 python3Minimal scons serf sqlite subversion
|
||||
|
@ -1036,6 +1059,10 @@ in
|
|||
# CF dependencies - don’t rebuild them.
|
||||
libobjc objc4;
|
||||
|
||||
apple_sdk = superDarwin.apple_sdk // {
|
||||
inherit (prevStage.darwin.apple_sdk) sdkRoot;
|
||||
};
|
||||
|
||||
signingUtils = superDarwin.signingUtils.override {
|
||||
inherit (selfDarwin) sigtool;
|
||||
};
|
||||
|
@ -1153,7 +1180,7 @@ in
|
|||
(prevStage:
|
||||
# previous stage4 stdenv:
|
||||
assert lib.all isBuiltByNixpkgsCompiler (with prevStage; [
|
||||
bash binutils-unwrapped brotli bzip2 cpio curl diffutils ed file findutils gawk
|
||||
bash binutils-unwrapped brotli bzip2 cpio diffutils ed file findutils gawk
|
||||
gettext gmp gnugrep gnumake gnused gnutar gzip icu libffi libiconv libidn2 libkrb5
|
||||
libssh2 libunistring libxml2 libyaml ncurses nghttp2 openbsm openpam openssl patch
|
||||
pbzx pcre python3Minimal xar xz zlib zstd
|
||||
|
@ -1206,7 +1233,7 @@ in
|
|||
|
||||
extraNativeBuildInputs = lib.optionals localSystem.isAarch64 [
|
||||
prevStage.updateAutotoolsGnuConfigScriptsHook
|
||||
];
|
||||
] ++ [ prevStage.darwin.apple_sdk.sdkRoot ];
|
||||
|
||||
extraBuildInputs = [ prevStage.darwin.CF ];
|
||||
|
||||
|
@ -1293,6 +1320,7 @@ in
|
|||
dyld
|
||||
libtapi
|
||||
locale
|
||||
apple_sdk.sdkRoot
|
||||
]
|
||||
++ lib.optional useAppleSDKLibs [ objc4 ]
|
||||
++ lib.optionals doSign [ postLinkSignHook sigtool signingUtils ]);
|
||||
|
@ -1302,14 +1330,18 @@ in
|
|||
|
||||
overrides = self: super: {
|
||||
inherit (prevStage)
|
||||
bash binutils brotli bzip2 coreutils cpio curl diffutils ed file findutils gawk
|
||||
bash binutils brotli bzip2 coreutils cpio diffutils ed file findutils gawk
|
||||
gettext gmp gnugrep gnumake gnused gnutar gzip icu libffi libiconv libidn2 libssh2
|
||||
libunistring libxml2 libyaml ncurses nghttp2 openbsm openpam openssl patch pbzx
|
||||
pcre python3Minimal xar xz zlib zstd;
|
||||
|
||||
darwin = super.darwin.overrideScope (_: _: {
|
||||
darwin = super.darwin.overrideScope (_: superDarwin: {
|
||||
inherit (prevStage.darwin)
|
||||
CF ICU Libsystem darwin-stubs dyld locale libobjc libtapi rewrite-tbd xnu;
|
||||
|
||||
apple_sdk = superDarwin.apple_sdk // {
|
||||
inherit (prevStage.darwin.apple_sdk) sdkRoot;
|
||||
};
|
||||
} // lib.optionalAttrs (super.stdenv.targetPlatform == localSystem) {
|
||||
inherit (prevStage.darwin) binutils binutils-unwrapped cctools-llvm cctools-port;
|
||||
});
|
||||
|
|
|
@ -0,0 +1,437 @@
|
|||
# The basic algorithm is to rewrite the propagated inputs of a package and any of its
|
||||
# own propagated inputs recursively to replace references from the default SDK with
|
||||
# those from the requested SDK version. This is done across all propagated inputs to
|
||||
# avoid making assumptions about how those inputs are being used.
|
||||
#
|
||||
# For example, packages may propagate target-target dependencies with the expectation that
|
||||
# they will be just build inputs when the package itself is used as a native build input.
|
||||
#
|
||||
# To support this use case and operate without regard to the original package set,
|
||||
# `overrideSDK` creates a mapping from the default SDK in all package categories to the
|
||||
# requested SDK. If the lookup fails, it is assumed the package is not part of the SDK.
|
||||
# Non-SDK packages are processed per the algorithm described above.
|
||||
{
|
||||
lib,
|
||||
stdenvNoCC,
|
||||
extendMkDerivationArgs,
|
||||
pkgsBuildBuild,
|
||||
pkgsBuildHost,
|
||||
pkgsBuildTarget,
|
||||
pkgsHostHost,
|
||||
pkgsHostTarget,
|
||||
pkgsTargetTarget,
|
||||
}@args:
|
||||
|
||||
let
|
||||
# Takes a mapping from a package to its replacement and transforms it into a list of
|
||||
# mappings by output (e.g., a package with three outputs produces a list of size 3).
|
||||
expandOutputs =
|
||||
mapping:
|
||||
map (output: {
|
||||
name = builtins.unsafeDiscardStringContext (lib.getOutput output mapping.original);
|
||||
value = lib.getOutput output mapping.replacement;
|
||||
}) mapping.original.outputs;
|
||||
|
||||
# Produces a list of mappings from the default SDK to the new SDK (`sdk`).
|
||||
# `attr` indicates which SDK path to remap (e.g., `libs` remaps `apple_sdk.libs`).
|
||||
#
|
||||
# TODO: Update once the SDKs have been refactored to a common pattern to better handle
|
||||
# frameworks that are not present in both SDKs. Currently, they’re dropped.
|
||||
mkMapping =
|
||||
attr: pkgs: sdk:
|
||||
lib.foldlAttrs (
|
||||
mappings: name: pkg:
|
||||
let
|
||||
# Avoid evaluation failures due to missing or throwing
|
||||
# frameworks (such as QuickTime in the 11.0 SDK).
|
||||
maybeReplacement = builtins.tryEval sdk.${attr}.${name} or { success = false; };
|
||||
in
|
||||
if maybeReplacement.success then
|
||||
mappings
|
||||
++ expandOutputs {
|
||||
original = pkg;
|
||||
replacement = maybeReplacement.value;
|
||||
}
|
||||
else
|
||||
mappings
|
||||
) [ ] pkgs.darwin.apple_sdk.${attr};
|
||||
|
||||
# Produces a list of overrides for the given package set, SDK, and version.
|
||||
# If you want to manually specify a mapping, this is where you should do it.
|
||||
mkOverrides =
|
||||
pkgs: sdk: version:
|
||||
lib.concatMap expandOutputs [
|
||||
# Libsystem needs to match the one used by the SDK or weird errors happen.
|
||||
{
|
||||
original = pkgs.darwin.apple_sdk.Libsystem;
|
||||
replacement = sdk.Libsystem;
|
||||
}
|
||||
# Make sure darwin.CF is mapped to the correct version for the SDK.
|
||||
{
|
||||
original = pkgs.darwin.CF;
|
||||
replacement = sdk.frameworks.CoreFoundation;
|
||||
}
|
||||
# libobjc needs to be handled specially because it’s not actually in the SDK.
|
||||
{
|
||||
original = pkgs.darwin.libobjc;
|
||||
replacement = sdk.objc4;
|
||||
}
|
||||
# Unfortunately, this is not consistent between Darwin SDKs in nixpkgs, so
|
||||
# try both versions to map between them.
|
||||
{
|
||||
original = pkgs.darwin.apple_sdk.sdk or pkgs.darwin.apple_sdk.MacOSX-SDK;
|
||||
replacement = sdk.sdk or sdk.MacOSX-SDK;
|
||||
}
|
||||
# Remap the SDK root. This is used by clang to set the SDK version when
|
||||
# linking. This behavior is automatic by clang and can’t be overriden.
|
||||
# Otherwise, without the SDK root set, the SDK version will be inferred to
|
||||
# be the same as the deployment target, which is not usually what you want.
|
||||
{
|
||||
original = pkgs.darwin.apple_sdk.sdkRoot;
|
||||
replacement = sdk.sdkRoot;
|
||||
}
|
||||
# Override xcodebuild because it hardcodes the SDK version.
|
||||
# TODO: Make xcodebuild defer to the SDK root set in the stdenv.
|
||||
{
|
||||
original = pkgs.xcodebuild;
|
||||
replacement = pkgs.xcodebuild.override {
|
||||
# Do the override manually to avoid an infinite recursion.
|
||||
stdenv = pkgs.stdenv.override (old: {
|
||||
buildPlatform = mkPlatform version old.buildPlatform;
|
||||
hostPlatform = mkPlatform version old.hostPlatform;
|
||||
targetPlatform = mkPlatform version old.targetPlatform;
|
||||
|
||||
allowedRequisites = null;
|
||||
cc = mkCC sdk.Libsystem old.cc;
|
||||
});
|
||||
};
|
||||
}
|
||||
];
|
||||
|
||||
mkBintools =
|
||||
Libsystem: bintools:
|
||||
if bintools ? override then
|
||||
bintools.override { libc = Libsystem; }
|
||||
else
|
||||
let
|
||||
# `override` isn’t available, so bintools has to be rewrapped with the new libc.
|
||||
# Most of the required arguments can be recovered except for `postLinkSignHook`
|
||||
# and `signingUtils`, which have to be scrapped from the original’s `postFixup`.
|
||||
# This isn’t ideal, but it works.
|
||||
postFixup = lib.splitString "\n" bintools.postFixup;
|
||||
|
||||
postLinkSignHook = lib.pipe postFixup [
|
||||
(lib.findFirst (lib.hasPrefix "echo 'source") null)
|
||||
(builtins.match "^echo 'source (.*-post-link-sign-hook)' >> \\$out/nix-support/post-link-hook$")
|
||||
lib.head
|
||||
];
|
||||
|
||||
signingUtils = lib.pipe postFixup [
|
||||
(lib.findFirst (lib.hasPrefix "export signingUtils") null)
|
||||
(builtins.match "^export signingUtils=(.*)$")
|
||||
lib.head
|
||||
];
|
||||
|
||||
newBintools = pkgsBuildTarget.wrapBintoolsWith {
|
||||
inherit (bintools) name;
|
||||
|
||||
buildPackages = { };
|
||||
libc = Libsystem;
|
||||
|
||||
inherit lib;
|
||||
|
||||
coreutils = bintools.coreutils_bin;
|
||||
gnugrep = bintools.gnugrep_bin;
|
||||
|
||||
inherit (bintools) bintools;
|
||||
|
||||
inherit postLinkSignHook signingUtils;
|
||||
};
|
||||
in
|
||||
lib.getOutput bintools.outputName newBintools;
|
||||
|
||||
mkCC =
|
||||
Libsystem: cc:
|
||||
if cc ? override then
|
||||
cc.override {
|
||||
bintools = mkBintools Libsystem cc.bintools;
|
||||
libc = Libsystem;
|
||||
}
|
||||
else
|
||||
builtins.throw "CC has no override: ${cc}";
|
||||
|
||||
mkPlatform =
|
||||
version: platform:
|
||||
platform
|
||||
// lib.optionalAttrs platform.isDarwin { inherit (version) darwinMinVersion darwinSdkVersion; };
|
||||
|
||||
# Creates a stub package. Unchanged files from the original package are symlinked
|
||||
# into the package. The contents of `nix-support` are updated to reference any
|
||||
# replaced packages.
|
||||
#
|
||||
# Note: `env` is an attrset containing `outputs` and `dependencies`.
|
||||
# `dependencies` is a regex passed to sed and must be `passAsFile`.
|
||||
mkProxyPackage =
|
||||
name: env:
|
||||
stdenvNoCC.mkDerivation {
|
||||
inherit name;
|
||||
|
||||
inherit (env) outputs replacements sourceOutputs;
|
||||
|
||||
# Take advantage of the fact that replacements and sourceOutputs will be passed
|
||||
# via JSON and parsed into environment variables.
|
||||
__structuredAttrs = true;
|
||||
|
||||
buildCommand = ''
|
||||
# Map over the outputs in the package being replaced to make sure the proxy is
|
||||
# a fully functional replacement. This is like `symlinkJoin` except for
|
||||
# outputs and the contents of `nix-support`, which will be customized.
|
||||
function replacePropagatedInputs() {
|
||||
local sourcePath=$1
|
||||
local targetPath=$2
|
||||
|
||||
mkdir -p "$targetPath"
|
||||
|
||||
local sourceFile
|
||||
for sourceFile in "$sourcePath"/*; do
|
||||
local fileName=$(basename "$sourceFile")
|
||||
local targetFile="$targetPath/$fileName"
|
||||
|
||||
if [ -d "$sourceFile" ]; then
|
||||
replacePropagatedInputs "$sourceFile" "$targetPath/$fileName"
|
||||
# Check to see if any of the files in the folder were replaced.
|
||||
# Otherwise, replace the folder with a symlink if none were changed.
|
||||
if [ "$(find -maxdepth 1 "$targetPath/$fileName" -not -type l)" = "" ]; then
|
||||
rm "$targetPath/$fileName"/*
|
||||
ln -s "$sourceFile" "$targetPath/$fileName"
|
||||
fi
|
||||
else
|
||||
cp "$sourceFile" "$targetFile"
|
||||
local original
|
||||
for original in "''${!replacements[@]}"; do
|
||||
substituteInPlace "$targetFile" \
|
||||
--replace-quiet "$original" "''${replacements[$original]}"
|
||||
done
|
||||
if cmp -s "$sourceFile" "$targetFile"; then
|
||||
rm "$targetFile"
|
||||
ln -s "$sourceFile" "$targetFile"
|
||||
fi
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
local outputName
|
||||
for outputName in "''${!outputs[@]}"; do
|
||||
local outPath=''${outputs[$outputName]}
|
||||
mkdir -p "$outPath"
|
||||
|
||||
local sourcePath
|
||||
for sourcePath in "''${sourceOutputs[$outputName]}"/*; do
|
||||
sourceName=$(basename "$sourcePath")
|
||||
# `nix-support` is special-cased because any propagated inputs need their
|
||||
# SDK frameworks replaced with those from the requested SDK.
|
||||
if [ "$sourceName" == "nix-support" ]; then
|
||||
replacePropagatedInputs "$sourcePath" "$outPath/nix-support"
|
||||
else
|
||||
ln -s "$sourcePath" "$outPath/$sourceName"
|
||||
fi
|
||||
done
|
||||
done
|
||||
'';
|
||||
};
|
||||
|
||||
# Gets all propagated inputs in a package. This does not recurse.
|
||||
getPropagatedInputs =
|
||||
pkg:
|
||||
lib.optionals (lib.isDerivation pkg) (
|
||||
lib.concatMap (input: pkg.${input} or [ ]) [
|
||||
"depsBuildBuildPropagated"
|
||||
"propagatedNativeBuildInputs"
|
||||
"depsBuildTargetPropagated"
|
||||
"depsHostHostPropagated"
|
||||
"propagatedBuildInputs"
|
||||
"depsTargetTargetPropagated"
|
||||
]
|
||||
);
|
||||
|
||||
# Looks up the replacement for `pkg` in the `newPackages` mapping. If `pkg` is a
|
||||
# compiler (meaning it has a `libc` attribute), the compiler will be overriden.
|
||||
getReplacement =
|
||||
newPackages: pkg:
|
||||
let
|
||||
pkgOrCC =
|
||||
if pkg.libc or null != null then
|
||||
# Heuristic to determine whether package is a compiler or bintools.
|
||||
if pkg.wrapperName == "CC_WRAPPER" then
|
||||
mkCC (getReplacement newPackages pkg.libc) pkg
|
||||
else
|
||||
mkBintools (getReplacement newPackages pkg.libc) pkg
|
||||
else
|
||||
pkg;
|
||||
in
|
||||
if lib.isDerivation pkg then
|
||||
newPackages.${builtins.unsafeDiscardStringContext pkg} or pkgOrCC
|
||||
else
|
||||
pkg;
|
||||
|
||||
# Replaces all packages propagated by `pkgs` using the `newPackages` mapping.
|
||||
# It is assumed that all possible overrides have already been incorporated into
|
||||
# the mapping. If any propagated packages are replaced, a proxy package will be
|
||||
# created with references to the old packages replaced in `nix-support`.
|
||||
replacePropagatedPackages =
|
||||
newPackages: pkg:
|
||||
let
|
||||
propagatedInputs = getPropagatedInputs pkg;
|
||||
env = {
|
||||
inherit (pkg) outputs;
|
||||
|
||||
replacements = lib.pipe propagatedInputs [
|
||||
(lib.filter (pkg: pkg != null))
|
||||
(map (dep: {
|
||||
name = builtins.unsafeDiscardStringContext dep;
|
||||
value = getReplacement newPackages dep;
|
||||
}))
|
||||
(lib.filter (mapping: mapping.name != mapping.value))
|
||||
lib.listToAttrs
|
||||
];
|
||||
|
||||
sourceOutputs = lib.genAttrs pkg.outputs (output: lib.getOutput output pkg);
|
||||
};
|
||||
in
|
||||
# Only remap the package’s propagated inputs if there are any and if any of them
|
||||
# had packages remapped (with frameworks or proxy packages).
|
||||
if propagatedInputs != [ ] && env.replacements != { } then mkProxyPackage pkg.name env else pkg;
|
||||
|
||||
# Gets all propagated dependencies in a package in reverse order sorted topologically.
|
||||
# This takes advantage of the fact that items produced by `operator` are pushed to
|
||||
# the end of the working set, ensuring that dependencies always appear after their
|
||||
# parent in the list with leaf nodes at the end.
|
||||
topologicallyOrderedPropagatedDependencies =
|
||||
pkgs:
|
||||
let
|
||||
mapPackageDeps = lib.flip lib.pipe [
|
||||
(lib.filter (pkg: pkg != null))
|
||||
(map (pkg: {
|
||||
key = builtins.unsafeDiscardStringContext pkg;
|
||||
package = pkg;
|
||||
deps = getPropagatedInputs pkg;
|
||||
}))
|
||||
];
|
||||
in
|
||||
lib.genericClosure {
|
||||
startSet = mapPackageDeps pkgs;
|
||||
operator = { deps, ... }: mapPackageDeps deps;
|
||||
};
|
||||
|
||||
# Returns a package mapping based on remapping all propagated packages.
|
||||
getPackageMapping =
|
||||
baseMapping: input:
|
||||
let
|
||||
dependencies = topologicallyOrderedPropagatedDependencies input;
|
||||
in
|
||||
lib.foldr (
|
||||
pkg: newPackages:
|
||||
let
|
||||
replacement = replacePropagatedPackages newPackages pkg.package;
|
||||
outPath = pkg.key;
|
||||
in
|
||||
if pkg.key == null || newPackages ? ${outPath} then
|
||||
newPackages
|
||||
else
|
||||
newPackages // { ${outPath} = replacement; }
|
||||
) baseMapping dependencies;
|
||||
|
||||
overrideSDK =
|
||||
stdenv: sdkVersion:
|
||||
let
|
||||
newVersion = {
|
||||
inherit (stdenv.hostPlatform) darwinMinVersion darwinSdkVersion;
|
||||
} // (if lib.isAttrs sdkVersion then sdkVersion else { darwinSdkVersion = sdkVersion; });
|
||||
|
||||
inherit (newVersion) darwinMinVersion darwinSdkVersion;
|
||||
|
||||
# Used to get an SDK version corresponding to the requested `darwinSdkVersion`.
|
||||
# TODO: Treat `darwinSdkVersion` as a constraint rather than as an exact version.
|
||||
resolveSDK = pkgs: pkgs.darwin."apple_sdk_${lib.replaceStrings [ "." ] [ "_" ] darwinSdkVersion}";
|
||||
|
||||
# `newSdkPackages` is constructed based on the assumption that SDK packages only
|
||||
# propagate versioned packages from that SDK -- that they neither propagate
|
||||
# unversioned SDK packages nor propagate non-SDK packages (such as curl).
|
||||
#
|
||||
# Note: `builtins.unsafeDiscardStringContext` is used to allow the path from the
|
||||
# original package output to be mapped to the replacement. This is safe because
|
||||
# the value is not persisted anywhere and necessary because store paths are not
|
||||
# allowed as attrset names otherwise.
|
||||
baseSdkMapping = lib.pipe args [
|
||||
(lib.flip removeAttrs [
|
||||
"lib"
|
||||
"stdenvNoCC"
|
||||
"extendMkDerivationArgs"
|
||||
])
|
||||
(lib.filterAttrs (_: lib.hasAttr "darwin"))
|
||||
lib.attrValues
|
||||
(lib.concatMap (
|
||||
pkgs:
|
||||
let
|
||||
newSDK = resolveSDK pkgs;
|
||||
|
||||
frameworks = mkMapping "frameworks" pkgs newSDK;
|
||||
libs = mkMapping "libs" pkgs newSDK;
|
||||
overrides = mkOverrides pkgs newSDK newVersion;
|
||||
in
|
||||
frameworks ++ libs ++ overrides
|
||||
))
|
||||
lib.listToAttrs
|
||||
];
|
||||
|
||||
# Remaps all inputs given to the requested SDK version. The result is an attrset
|
||||
# that can be passed to `extendMkDerivationArgs`.
|
||||
mapInputsToSDK =
|
||||
inputs: args:
|
||||
lib.pipe inputs [
|
||||
(lib.filter (input: args ? ${input}))
|
||||
(lib.flip lib.genAttrs (
|
||||
inputName:
|
||||
let
|
||||
input = args.${inputName};
|
||||
newPackages = getPackageMapping baseSdkMapping input;
|
||||
in
|
||||
map (getReplacement newPackages) input
|
||||
))
|
||||
];
|
||||
in
|
||||
stdenv.override (
|
||||
old:
|
||||
{
|
||||
buildPlatform = mkPlatform newVersion old.buildPlatform;
|
||||
hostPlatform = mkPlatform newVersion old.hostPlatform;
|
||||
targetPlatform = mkPlatform newVersion old.targetPlatform;
|
||||
}
|
||||
# Only perform replacements if the SDK version has changed. Changing only the
|
||||
# deployment target does not require replacing the libc or SDK dependencies.
|
||||
// lib.optionalAttrs (old.hostPlatform.darwinSdkVersion != darwinSdkVersion) {
|
||||
allowedRequisites = null;
|
||||
|
||||
mkDerivationFromStdenv = extendMkDerivationArgs old (mapInputsToSDK [
|
||||
"depsBuildBuild"
|
||||
"nativeBuildInputs"
|
||||
"depsBuildTarget"
|
||||
"depsHostHost"
|
||||
"buildInputs"
|
||||
"depsTargetTarget"
|
||||
"depsBuildBuildPropagated"
|
||||
"propagatedNativeBuildInputs"
|
||||
"depsBuildTargetPropagated"
|
||||
"depsHostHostPropagated"
|
||||
"propagatedBuildInputs"
|
||||
"depsTargetTargetPropagated"
|
||||
]);
|
||||
|
||||
cc = getReplacement baseSdkMapping old.cc;
|
||||
|
||||
extraBuildInputs = map (getReplacement baseSdkMapping) stdenv.extraBuildInputs;
|
||||
extraNativeBuildInputs = map (getReplacement baseSdkMapping) stdenv.extraNativeBuildInputs;
|
||||
}
|
||||
);
|
||||
in
|
||||
overrideSDK
|
Loading…
Reference in New Issue