diff options
Diffstat (limited to 'pkgs/stdenv')
-rw-r--r-- | pkgs/stdenv/adapters.nix | 42 | ||||
-rw-r--r-- | pkgs/stdenv/darwin/default.nix | 63 | ||||
-rw-r--r-- | pkgs/stdenv/darwin/make-bootstrap-tools.nix | 409 | ||||
-rw-r--r-- | pkgs/stdenv/darwin/patch-bootstrap-tools-next.sh | 38 | ||||
-rw-r--r-- | pkgs/stdenv/darwin/unpack-bootstrap-tools-aarch64.sh | 5 | ||||
-rw-r--r-- | pkgs/stdenv/generic/default.nix | 2 | ||||
-rw-r--r-- | pkgs/stdenv/generic/make-derivation.nix | 314 |
7 files changed, 455 insertions, 418 deletions
diff --git a/pkgs/stdenv/adapters.nix b/pkgs/stdenv/adapters.nix index 84d3258949eb..c6b0aece4530 100644 --- a/pkgs/stdenv/adapters.nix +++ b/pkgs/stdenv/adapters.nix @@ -6,7 +6,7 @@ let # N.B. Keep in sync with default arg for stdenv/generic. - defaultMkDerivationFromStdenv = import ./generic/make-derivation.nix { inherit lib config; }; + defaultMkDerivationFromStdenv = stdenv: (import ./generic/make-derivation.nix { inherit lib config; } stdenv).mkDerivation; # Low level function to help with overriding `mkDerivationFromStdenv`. One # gives it the old stdenv arguments and a "continuation" function, and @@ -50,19 +50,18 @@ rec { # because older compilers may not be able to parse the headers from the default stdenv’s libc++. overrideLibcxx = stdenv: assert stdenv.cc.libcxx != null; + assert pkgs.stdenv.cc.libcxx != null; + # only unified libcxx / libcxxabi stdenv's are supported + assert lib.versionAtLeast pkgs.stdenv.cc.libcxx.version "12"; + assert lib.versionAtLeast stdenv.cc.libcxx.version "12"; let llvmLibcxxVersion = lib.getVersion llvmLibcxx; - stdenvLibcxxVersion = lib.getVersion stdenvLibcxx; stdenvLibcxx = pkgs.stdenv.cc.libcxx; - stdenvCxxabi = pkgs.stdenv.cc.libcxx.cxxabi; - llvmLibcxx = stdenv.cc.libcxx; - llvmCxxabi = stdenv.cc.libcxx.cxxabi; libcxx = pkgs.runCommand "${stdenvLibcxx.name}-${llvmLibcxxVersion}" { outputs = [ "out" "dev" ]; - inherit cxxabi; isLLVM = true; } '' mkdir -p "$dev/nix-support" @@ -70,21 +69,10 @@ rec { echo '${stdenvLibcxx}' > "$dev/nix-support/propagated-build-inputs" ln -s '${lib.getDev llvmLibcxx}/include' "$dev/include" ''; - - cxxabi = pkgs.runCommand "${stdenvCxxabi.name}-${llvmLibcxxVersion}" { - outputs = [ "out" "dev" ]; - inherit (stdenvCxxabi) libName; - } '' - mkdir -p "$dev/nix-support" - ln -s '${stdenvCxxabi}' "$out" - echo '${stdenvCxxabi}' > "$dev/nix-support/propagated-build-inputs" - ln -s '${lib.getDev llvmCxxabi}/include' "$dev/include" - ''; in overrideCC stdenv (stdenv.cc.override { inherit libcxx; extraPackages = [ - cxxabi pkgs.buildPackages.targetPackages."llvmPackages_${lib.versions.major llvmLibcxxVersion}".compiler-rt ]; }); @@ -144,10 +132,10 @@ rec { # extraBuildInputs are dropped in cross.nix, but darwin still needs them extraBuildInputs = [ pkgs.buildPackages.darwin.CF ]; mkDerivationFromStdenv = withOldMkDerivation old (stdenv: mkDerivationSuper: args: - (mkDerivationSuper args).overrideAttrs (finalAttrs: { - NIX_CFLAGS_LINK = toString (finalAttrs.NIX_CFLAGS_LINK or "") + (mkDerivationSuper args).overrideAttrs (prevAttrs: { + NIX_CFLAGS_LINK = toString (prevAttrs.NIX_CFLAGS_LINK or "") + lib.optionalString (stdenv.cc.isGNU or false) " -static-libgcc"; - nativeBuildInputs = (finalAttrs.nativeBuildInputs or []) + nativeBuildInputs = (prevAttrs.nativeBuildInputs or []) ++ lib.optionals stdenv.hasCC [ (pkgs.buildPackages.makeSetupHook { name = "darwin-portable-libSystem-hook"; @@ -237,14 +225,18 @@ rec { }); }); + /* Copy the libstdc++ from the model stdenv to the target stdenv. + * + * TODO(@connorbaker): + * This interface provides behavior which should be revisited prior to the + * release of 24.05. For a more detailed explanation and discussion, see + * https://github.com/NixOS/nixpkgs/issues/283517. */ useLibsFrom = modelStdenv: targetStdenv: let ccForLibs = modelStdenv.cc.cc; - cc = pkgs.wrapCCWith { - /* NOTE: cc.cc is the unwrapped compiler. Should we respect the old - * wrapper instead? */ - cc = targetStdenv.cc.cc; - + /* NOTE(@connorbaker): + * This assumes targetStdenv.cc is a cc-wrapper. */ + cc = targetStdenv.cc.override { /* NOTE(originally by rrbutani): * Normally the `useCcForLibs`/`gccForLibs` mechanism is used to get a * clang based `cc` to use `libstdc++` (from gcc). diff --git a/pkgs/stdenv/darwin/default.nix b/pkgs/stdenv/darwin/default.nix index 1433369c3252..e2ebe4d6bbb5 100644 --- a/pkgs/stdenv/darwin/default.nix +++ b/pkgs/stdenv/darwin/default.nix @@ -81,7 +81,6 @@ let }; extraPackages = [ - prevStage.llvmPackages.libcxxabi prevStage.llvmPackages.compiler-rt ]; @@ -196,7 +195,6 @@ in clang-unwrapped = null; libllvm = null; libcxx = null; - libcxxabi = null; compiler-rt = null; }; }) @@ -346,18 +344,6 @@ in ''; passthru = { isLLVM = true; - cxxabi = self.llvmPackages.libcxxabi; - isFromBootstrapFiles = true; - }; - }; - libcxxabi = self.stdenv.mkDerivation { - name = "bootstrap-stage0-libcxxabi"; - buildCommand = '' - mkdir -p $out/lib - ln -s ${bootstrapTools}/lib/libc++abi.dylib $out/lib - ''; - passthru = { - libName = "c++abi"; isFromBootstrapFiles = true; }; }; @@ -413,7 +399,7 @@ in assert (with prevStage.darwin; (! useAppleSDKLibs) -> CF == null); assert lib.all isFromBootstrapFiles (with prevStage.llvmPackages; [ - clang-unwrapped libclang libllvm llvm compiler-rt libcxx libcxxabi + clang-unwrapped libclang libllvm llvm compiler-rt libcxx ]); stageFun prevStage { @@ -480,7 +466,7 @@ in inherit (prevStage.llvmPackages) clang-unwrapped libclang libllvm llvm; }); libraries = super.llvmPackages.libraries.extend (_: _: { - inherit (prevStage.llvmPackages) compiler-rt libcxx libcxxabi; + inherit (prevStage.llvmPackages) compiler-rt libcxx; }); in { inherit tools libraries; inherit (prevStage.llvmPackages) release_version; } // tools // libraries @@ -526,7 +512,7 @@ in assert lib.all isFromNixpkgs (with prevStage.darwin; [ dyld launchd xnu ]); assert lib.all isFromBootstrapFiles (with prevStage.llvmPackages; [ - clang-unwrapped libclang libllvm llvm compiler-rt libcxx libcxxabi + clang-unwrapped libclang libllvm llvm compiler-rt libcxx ]); assert lib.getVersion prevStage.stdenv.cc.bintools.bintools == "boot"; @@ -580,7 +566,7 @@ in clang = prevStage.stdenv.cc; }); libraries = super.llvmPackages.libraries.extend (_: _: { - inherit (prevStage.llvmPackages) compiler-rt libcxx libcxxabi; + inherit (prevStage.llvmPackages) compiler-rt libcxx; }); in { inherit tools libraries; inherit (prevStage.llvmPackages) release_version; } // tools // libraries @@ -626,7 +612,7 @@ in assert lib.all isFromNixpkgs (with prevStage.darwin; [ dyld launchd xnu ]); assert lib.all isFromBootstrapFiles (with prevStage.llvmPackages; [ - clang-unwrapped libclang libllvm llvm compiler-rt libcxx libcxxabi + clang-unwrapped libclang libllvm llvm compiler-rt libcxx ]); assert lib.getVersion prevStage.stdenv.cc.bintools.bintools == lib.getVersion prevStage.darwin.cctools-port; @@ -670,17 +656,8 @@ in libraries = super.llvmPackages.libraries.extend (selfLib: superLib: { compiler-rt = null; libcxx = superLib.libcxx.override ({ - inherit (selfLib) libcxxabi; stdenv = libcxxBootstrapStdenv; }); - libcxxabi = superLib.libcxxabi.override { - stdenv = libcxxBootstrapStdenv; - } - # Setting `standalone = true` is only needed with older verions of LLVM. Newer ones - # automatically do what is necessary to bootstrap lib++abi. - // lib.optionalAttrs (builtins.any (v: llvmMajor == v) [ "7" "11" "12" "13" ]) { - standalone = true; - }; }); in { inherit libraries; } // libraries @@ -726,7 +703,7 @@ in assert lib.all isBuiltByBootstrapFilesCompiler (with prevStage.llvmPackages; [ clang-unwrapped libclang libllvm llvm ]); - assert lib.all isBuiltByNixpkgsCompiler (with prevStage.llvmPackages; [ libcxx libcxxabi ]); + assert lib.all isBuiltByNixpkgsCompiler (with prevStage.llvmPackages; [ libcxx ]); assert prevStage.llvmPackages.compiler-rt == null; assert lib.getVersion prevStage.stdenv.cc.bintools.bintools == lib.getVersion prevStage.darwin.cctools-port; @@ -763,7 +740,7 @@ in }); libraries = super.llvmPackages.libraries.extend (selfLib: superLib: { - inherit (prevStage.llvmPackages) compiler-rt libcxx libcxxabi; + inherit (prevStage.llvmPackages) compiler-rt libcxx; }); in { inherit tools libraries; inherit (prevStage.llvmPackages) release_version; } // tools // libraries @@ -779,7 +756,6 @@ in in self.overrideCC stdenvNoCF (self.llvmPackages.clangNoCompilerRtWithLibc.override { inherit (self.llvmPackages) libcxx; - extraPackages = [ self.llvmPackages.libcxxabi ]; }); }; @@ -827,7 +803,7 @@ in assert lib.all isBuiltByBootstrapFilesCompiler (with prevStage.llvmPackages; [ clang-unwrapped libclang libllvm llvm ]); - assert lib.all isBuiltByNixpkgsCompiler (with prevStage.llvmPackages; [ libcxx libcxxabi ]); + assert lib.all isBuiltByNixpkgsCompiler (with prevStage.llvmPackages; [ libcxx ]); assert prevStage.llvmPackages.compiler-rt == null; assert lib.getVersion prevStage.stdenv.cc.bintools.bintools == lib.getVersion prevStage.darwin.cctools-llvm; @@ -874,12 +850,11 @@ in }); libraries = super.llvmPackages.libraries.extend (selfLib: superLib: { - inherit (prevStage.llvmPackages) libcxx libcxxabi; + inherit (prevStage.llvmPackages) libcxx; # Make sure compiler-rt is linked against the CF from this stage, which can be # propagated to the final stdenv. CF is required by ASAN. compiler-rt = superLib.compiler-rt.override ({ - inherit (selfLib) libcxxabi; inherit (self.llvmPackages) libllvm; stdenv = self.stdenv.override { extraBuildInputs = [ self.darwin.CF ]; @@ -907,8 +882,6 @@ in bintools = self.llvmPackages.clangNoCompilerRtWithLibc.bintools.override { libc = self.darwin.Libsystem; }; - - extraPackages = [ self.llvmPackages.libcxxabi ]; }); }; @@ -924,7 +897,7 @@ in # Rebuild LLVM with LLVM. This stage also rebuilds certain dependencies needed by LLVM. # - # LLVM requires: libcxx libcxxabi libffi libiconv libxml2 ncurses zlib + # LLVM requires: libcxx libffi libiconv libxml2 ncurses zlib (prevStage: # previous stage2-CF stdenv: assert lib.all isBuiltByBootstrapFilesCompiler (with prevStage; [ @@ -954,7 +927,7 @@ in assert lib.all isBuiltByBootstrapFilesCompiler (with prevStage.llvmPackages; [ clang-unwrapped libclang libllvm llvm ]); - assert lib.all isBuiltByNixpkgsCompiler (with prevStage.llvmPackages; [ libcxx libcxxabi ]); + assert lib.all isBuiltByNixpkgsCompiler (with prevStage.llvmPackages; [ libcxx ]); assert lib.getVersion prevStage.stdenv.cc.bintools.bintools == lib.getVersion prevStage.darwin.cctools-llvm; @@ -986,7 +959,7 @@ in llvmPackages = super.llvmPackages // ( let libraries = super.llvmPackages.libraries.extend (_: _: { - inherit (prevStage.llvmPackages) compiler-rt libcxx libcxxabi; + inherit (prevStage.llvmPackages) compiler-rt libcxx; }); in { inherit libraries; } // libraries @@ -1033,7 +1006,7 @@ in assert lib.all isFromNixpkgs (with prevStage.darwin; [ dyld launchd libclosure libdispatch xnu ]); assert lib.all isBuiltByNixpkgsCompiler (with prevStage.llvmPackages; [ - clang-unwrapped libclang libllvm llvm compiler-rt libcxx libcxxabi + clang-unwrapped libclang libllvm llvm compiler-rt libcxx ]); assert lib.getVersion prevStage.stdenv.cc.bintools.bintools == lib.getVersion prevStage.darwin.cctools-llvm; @@ -1117,7 +1090,6 @@ in }; extraPackages = [ - self.llvmPackages.libcxxabi self.llvmPackages.compiler-rt ]; @@ -1158,7 +1130,7 @@ in }; }); libraries = super.llvmPackages.libraries.extend (_: _:{ - inherit (prevStage.llvmPackages) compiler-rt libcxx libcxxabi; + inherit (prevStage.llvmPackages) compiler-rt libcxx; }); in { inherit tools libraries; } // tools // libraries @@ -1200,7 +1172,7 @@ in assert lib.all isFromNixpkgs (with prevStage.darwin; [ dyld launchd libclosure libdispatch xnu ]); assert lib.all isBuiltByNixpkgsCompiler (with prevStage.llvmPackages; [ - clang-unwrapped libclang libllvm llvm compiler-rt libcxx libcxxabi + clang-unwrapped libclang libllvm llvm compiler-rt libcxx ]); assert lib.all isBuiltByBootstrapFilesCompiler (with prevStage; [ @@ -1312,8 +1284,6 @@ in compiler-rt.dev libcxx libcxx.dev - libcxxabi - libcxxabi.dev lld llvm llvm.lib @@ -1356,7 +1326,7 @@ in inherit (prevStage.llvmPackages) clang clang-unwrapped libclang libllvm llvm; }); libraries = super.llvmPackages.libraries.extend (_: _: { - inherit (prevStage.llvmPackages) compiler-rt libcxx libcxxabi; + inherit (prevStage.llvmPackages) compiler-rt libcxx; }); in { inherit tools libraries; } // tools // libraries @@ -1382,7 +1352,6 @@ in assert isBuiltByNixpkgsCompiler prevStage.llvmPackages.clang-unwrapped; assert isBuiltByNixpkgsCompiler prevStage.llvmPackages.libllvm; assert isBuiltByNixpkgsCompiler prevStage.llvmPackages.libcxx; - assert isBuiltByNixpkgsCompiler prevStage.llvmPackages.libcxxabi; assert isBuiltByNixpkgsCompiler prevStage.llvmPackages.compiler-rt; { inherit (prevStage) config overlays stdenv; }) ] diff --git a/pkgs/stdenv/darwin/make-bootstrap-tools.nix b/pkgs/stdenv/darwin/make-bootstrap-tools.nix index 384567739d0e..836a938b84ae 100644 --- a/pkgs/stdenv/darwin/make-bootstrap-tools.nix +++ b/pkgs/stdenv/darwin/make-bootstrap-tools.nix @@ -1,21 +1,5 @@ { pkgspath ? ../../.., test-pkgspath ? pkgspath , localSystem ? { system = builtins.currentSystem; } -# Specify the desired LLVM version in an overlay to avoid the use of -# mismatching versions. -# -# The llvmPackages that we take things (clang, libc++ and such) from -# is specified explicitly to be llvmPackages_11 to keep the -# bootstrap-tools stable. However, tools like otool, -# install_name_tool and strip are taken straight from stdenv.cc, -# which, after the bump, is a different LLVM version altogether. -# -# The original intent was that bootstrap-tools specified LLVM 11 -# exhaustively but it didn't. That should be rectified with this -# PR. As to why stick with 11? That's just to keep the -# bootstrap-tools unchanged. -# -# https://github.com/NixOS/nixpkgs/pull/267058/files#r1390889848 -, overlays ? [(self: super: { llvmPackages = super.llvmPackages_11; })] , crossSystem ? null , bootstrapFiles ? null }: @@ -29,184 +13,280 @@ let cross = if crossSystem != null in (import "${pkgspath}/pkgs/stdenv/darwin" args'); } else {}; -in with import pkgspath ({ inherit localSystem overlays; } // cross // custom-bootstrap); +in with import pkgspath ({ inherit localSystem; } // cross // custom-bootstrap); rec { - coreutils_ = (coreutils.override (args: { - # We want coreutils without ACL support. - aclSupport = false; - # Cannot use a single binary build, or it gets dynamically linked against gmp. - singleBinary = false; - })).overrideAttrs (oa: { - # Increase header size to be able to inject extra RPATHs. Otherwise - # x86_64-darwin build fails as: - # https://cache.nixos.org/log/g5wyq9xqshan6m3kl21bjn1z88hx48rh-stdenv-bootstrap-tools.drv - NIX_LDFLAGS = (oa.NIX_LDFLAGS or "") + " -headerpad_max_install_names"; - }); - - cctools_ = darwin.cctools; - - # Avoid debugging larger changes for now. - bzip2_ = bzip2.override (args: { enableStatic = true; enableShared = false; }); - - # Avoid messing with libkrb5 and libnghttp2. - curl_ = curlMinimal.override (args: { gssSupport = false; http2Support = false; }); - build = stdenv.mkDerivation { name = "stdenv-bootstrap-tools"; - nativeBuildInputs = [ nukeReferences dumpnar ]; + nativeBuildInputs = [ dumpnar nukeReferences ]; + + buildCommand = let + inherit (lib) + getBin + getDev + getLib + ; + + coreutils_ = (coreutils.override (args: { + # We want coreutils without ACL support. + aclSupport = false; + # Cannot use a single binary build, or it gets dynamically linked against gmp. + singleBinary = false; + })).overrideAttrs (oa: { + # Increase header size to be able to inject extra RPATHs. Otherwise + # x86_64-darwin build fails as: + # https://cache.nixos.org/log/g5wyq9xqshan6m3kl21bjn1z88hx48rh-stdenv-bootstrap-tools.drv + NIX_LDFLAGS = (oa.NIX_LDFLAGS or "") + " -headerpad_max_install_names"; + }); + + cctools_ = darwin.cctools; + + # Avoid messing with libkrb5 and libnghttp2. + curl_ = curlMinimal.override (args: { + gssSupport = false; + http2Support = false; + scpSupport = false; + }); + + gnutar_ = (gnutar.override { libintl = null; }).overrideAttrs (old: { + configureFlags = [ + "--disable-nls" + ] ++ old.configureFlags or []; + }); + + xz_ = xz.override { enableStatic = true; }; + + unpackScript = writeText "bootstrap-tools-unpack.sh" '' + set -euo pipefail + + echo Unpacking the bootstrap tools... >&2 + mkdir $out + tar xf "$1" -C $out + + updateInstallName() { + local path="$1" + + cp "$path" "$path.new" + install_name_tool -id "$path" "$path.new" + codesign -f -i "$(basename "$path")" -s - "$path.new" + mv -f "$path.new" "$path" + } + + find $out/lib -type f -name '*.dylib' -print0 | while IFS= read -r -d $'\0' lib; do + updateInstallName "$lib" + done - buildCommand = '' + # Provide a gunzip script. + cat > $out/bin/gunzip <<EOF + #!$out/bin/sh + exec $out/bin/gzip -d "\$@" + EOF + chmod +x $out/bin/gunzip + + # Provide fgrep/egrep. + echo "#! $out/bin/sh" > $out/bin/egrep + echo "exec $out/bin/grep -E \"\$@\"" >> $out/bin/egrep + echo "#! $out/bin/sh" > $out/bin/fgrep + echo "exec $out/bin/grep -F \"\$@\"" >> $out/bin/fgrep + + cat >$out/bin/dsymutil << EOF + #!$out/bin/sh + EOF + + chmod +x $out/bin/egrep $out/bin/fgrep $out/bin/dsymutil + ''; + + in + '' mkdir -p $out/bin $out/lib $out/lib/system $out/lib/darwin ${lib.optionalString stdenv.targetPlatform.isx86_64 '' # Copy libSystem's .o files for various low-level boot stuff. - cp -d ${lib.getLib darwin.Libsystem}/lib/*.o $out/lib + cp -d ${getLib darwin.Libsystem}/lib/*.o $out/lib # Resolv is actually a link to another package, so let's copy it properly - cp -L ${lib.getLib darwin.Libsystem}/lib/libresolv.9.dylib $out/lib + cp -L ${getLib darwin.Libsystem}/lib/libresolv.9.dylib $out/lib ''} - cp -rL ${darwin.Libsystem}/include $out + cp -rL ${getDev darwin.Libsystem}/include $out chmod -R u+w $out/include - cp -rL ${darwin.ICU}/include* $out/include - cp -rL ${libiconv}/include/* $out/include - cp -rL ${lib.getDev gnugrep.pcre2}/include/* $out/include + cp -rL ${getDev libiconv}/include/* $out/include + cp -rL ${getDev gnugrep.pcre2}/include/* $out/include mv $out/include $out/include-Libsystem # Copy coreutils, bash, etc. - cp ${coreutils_}/bin/* $out/bin + cp ${getBin coreutils_}/bin/* $out/bin (cd $out/bin && rm vdir dir sha*sum pinky factor pathchk runcon shuf who whoami shred users) - cp ${bash}/bin/bash $out/bin + cp ${getBin bash}/bin/bash $out/bin ln -s bash $out/bin/sh - cp ${findutils}/bin/find $out/bin - cp ${findutils}/bin/xargs $out/bin - cp -d ${diffutils}/bin/* $out/bin - cp -d ${gnused}/bin/* $out/bin - cp -d ${gnugrep}/bin/grep $out/bin - cp ${gawk}/bin/gawk $out/bin - cp -d ${gawk}/bin/awk $out/bin - cp ${gnutar}/bin/tar $out/bin - cp ${gzip}/bin/.gzip-wrapped $out/bin/gzip - cp ${bzip2_.bin}/bin/bzip2 $out/bin + cp ${getBin findutils}/bin/find $out/bin + cp ${getBin findutils}/bin/xargs $out/bin + cp -d ${getBin diffutils}/bin/* $out/bin + cp -d ${getBin gnused}/bin/* $out/bin + cp -d ${getBin gnugrep}/bin/grep $out/bin + cp ${getBin gawk}/bin/gawk $out/bin + cp -d ${getBin gawk}/bin/awk $out/bin + cp ${getBin gnutar}/bin/tar $out/bin + cp ${getBin gzip}/bin/.gzip-wrapped $out/bin/gzip + cp ${getBin bzip2}/bin/bzip2 $out/bin ln -s bzip2 $out/bin/bunzip2 - cp -d ${gnumake}/bin/* $out/bin - cp -d ${patch}/bin/* $out/bin - cp -d ${xz.bin}/bin/xz $out/bin - cp ${cpio}/bin/cpio $out/bin + cp -d ${getBin gnumake}/bin/* $out/bin + cp -d ${getBin patch}/bin/* $out/bin + cp -d ${getBin xz}/bin/xz $out/bin + cp ${getBin cpio}/bin/cpio $out/bin # This used to be in-nixpkgs, but now is in the bundle # because I can't be bothered to make it partially static - cp ${curl_.bin}/bin/curl $out/bin - cp -d ${curl_.out}/lib/libcurl*.dylib $out/lib - cp -d ${libssh2.out}/lib/libssh*.dylib $out/lib - cp -d ${lib.getLib openssl}/lib/*.dylib $out/lib - - cp -d ${gnugrep.pcre2.out}/lib/libpcre2*.dylib $out/lib - cp -d ${lib.getLib libiconv}/lib/lib*.dylib $out/lib - cp -d ${lib.getLib gettext}/lib/libintl*.dylib $out/lib + cp ${getBin curl_}/bin/curl $out/bin + cp -d ${getLib curl_}/lib/libcurl*.dylib $out/lib + cp -d ${getLib openssl}/lib/*.dylib $out/lib + + cp -d ${getLib gnugrep.pcre2}/lib/libpcre2*.dylib $out/lib + cp -d ${getLib libiconv}/lib/lib*.dylib $out/lib + cp -d ${getLib gettext}/lib/libintl*.dylib $out/lib chmod +x $out/lib/libintl*.dylib - cp -d ${ncurses.out}/lib/libncurses*.dylib $out/lib - cp -d ${libxml2.out}/lib/libxml2*.dylib $out/lib + cp -d ${getLib ncurses}/lib/libncurses*.dylib $out/lib + cp -d ${getLib libxml2}/lib/libxml2*.dylib $out/lib # Copy what we need of clang - cp -d ${llvmPackages.clang-unwrapped}/bin/clang* $out/bin - cp -rd ${lib.getLib llvmPackages.clang-unwrapped}/lib/* $out/lib + cp -d ${getBin llvmPackages.clang-unwrapped}/bin/clang{,++,-cl,-cpp,-[0-9]*} $out/bin + cp -d ${getLib llvmPackages.clang-unwrapped}/lib/libclang-cpp*.dylib $out/lib + cp -rd ${getLib llvmPackages.clang-unwrapped}/lib/clang $out/lib - cp -d ${lib.getLib llvmPackages.libcxx}/lib/libc++*.dylib $out/lib - cp -d ${lib.getLib llvmPackages.libcxxabi}/lib/libc++abi*.dylib $out/lib - cp -d ${lib.getLib llvmPackages.compiler-rt}/lib/darwin/libclang_rt* $out/lib/darwin - cp -d ${lib.getLib llvmPackages.compiler-rt}/lib/libclang_rt* $out/lib - cp -d ${lib.getLib llvmPackages.llvm.lib}/lib/libLLVM.dylib $out/lib - cp -d ${lib.getLib libffi}/lib/libffi*.dylib $out/lib + cp -d ${getLib llvmPackages.libcxx}/lib/libc++*.dylib $out/lib + mkdir -p $out/lib/darwin + cp -d ${getLib llvmPackages.compiler-rt}/lib/darwin/libclang_rt.{,profile_}osx.a $out/lib/darwin + cp -d ${getLib llvmPackages.compiler-rt}/lib/libclang_rt.{,profile_}osx.a $out/lib + cp -d ${getLib llvmPackages.llvm}/lib/libLLVM.dylib $out/lib + cp -d ${getLib libffi}/lib/libffi*.dylib $out/lib mkdir $out/include - cp -rd ${llvmPackages.libcxx.dev}/include/c++ $out/include + cp -rd ${getDev llvmPackages.libcxx}/include/c++ $out/include # copy .tbd assembly utils - cp -d ${pkgs.darwin.rewrite-tbd}/bin/rewrite-tbd $out/bin - cp -d ${lib.getLib pkgs.libyaml}/lib/libyaml*.dylib $out/lib + cp -d ${getBin pkgs.darwin.rewrite-tbd}/bin/rewrite-tbd $out/bin + cp -d ${getLib pkgs.libyaml}/lib/libyaml*.dylib $out/lib # copy package extraction tools - cp -d ${pkgs.pbzx}/bin/pbzx $out/bin - cp -d ${lib.getLib pkgs.xar}/lib/libxar*.dylib $out/lib - cp -d ${pkgs.bzip2.out}/lib/libbz2*.dylib $out/lib + cp -d ${getBin pkgs.pbzx}/bin/pbzx $out/bin + cp -d ${getLib pkgs.xar}/lib/libxar*.dylib $out/lib + cp -d ${getLib pkgs.bzip2}/lib/libbz2*.dylib $out/lib # copy sigtool - cp -d ${pkgs.darwin.sigtool}/bin/sigtool $out/bin - cp -d ${pkgs.darwin.sigtool}/bin/codesign $out/bin + cp -d ${getBin pkgs.darwin.sigtool}/bin/sigtool $out/bin + cp -d ${getBin pkgs.darwin.sigtool}/bin/codesign $out/bin - cp -d ${lib.getLib darwin.ICU}/lib/libicu*.dylib $out/lib - cp -d ${zlib.out}/lib/libz.* $out/lib - cp -d ${gmpxx.out}/lib/libgmp*.* $out/lib - cp -d ${xz.out}/lib/liblzma*.* $out/lib + cp -d ${getLib zlib}/lib/libz.* $out/lib + cp -d ${getLib gmpxx}/lib/libgmp*.* $out/lib + cp -d ${getLib xz}/lib/liblzma*.* $out/lib # Copy binutils. for i in as ld ar ranlib nm strip otool install_name_tool lipo codesign_allocate; do - cp ${cctools_}/bin/$i $out/bin + cp ${getBin cctools_}/bin/$i $out/bin done - cp -d ${lib.getLib darwin.libtapi}/lib/libtapi* $out/lib + cp -d ${getLib darwin.libtapi}/lib/libtapi* $out/lib - cp -rd ${pkgs.darwin.CF}/Library $out - ${lib.optionalString stdenv.targetPlatform.isAarch64 '' - cp -rd ${pkgs.darwin.libobjc}/lib/* $out/lib/ - ''} + # tools needed to unpack bootstrap archive. they should not contain any + # external references. we will process them like the other tools but + # perform some additional checks and will not pack them into the archive. + mkdir -p unpack/bin + cp ${getBin bash}/bin/bash unpack/bin + ln -s bash unpack/bin/sh + cp ${getBin coreutils_}/bin/mkdir unpack/bin + cp ${getBin gnutar_}/bin/tar unpack/bin + cp ${getBin xz_}/bin/xz unpack/bin + cp ${unpackScript} unpack/bootstrap-tools-unpack.sh - chmod -R u+w $out + # + # All files copied. Perform processing to update references to point into + # the archive + # - nuke-refs $out/bin/* + chmod -R u+w $out unpack + # - change nix store library paths to use @rpath/library + # - if needed add an rpath containing lib/ + # - strip executable rpathify() { - local libs=$(${stdenv.cc.targetPrefix}otool -L "$1" | tail -n +2 | grep -o "$NIX_STORE.*-\S*") || true - local newlib + local libs=$(${stdenv.cc.targetPrefix}otool -L "$1" | tail -n +2 | grep -o "$NIX_STORE.*-\S*" || true) + local lib rpath for lib in $libs; do ${stdenv.cc.targetPrefix}install_name_tool -change $lib "@rpath/$(basename "$lib")" "$1" done - } - # Strip executables even further - for i in $out/bin/*; do - if [[ ! -L $i ]] && isMachO "$i"; then - chmod +w $i - ${stdenv.cc.targetPrefix}strip $i || true + case "$(dirname "$1")" in + */bin) + # Strip executables even further + ${stdenv.cc.targetPrefix}strip "$i" + rpath='@executable_path/../lib' + ;; + */lib) + # the '/.' suffix is required + rpath='@loader_path/.' + ;; + */lib/darwin) + rpath='@loader_path/..' + ;; + *) + echo unkown executable $1 >&2 + exit 1 + ;; + esac + + # if shared object contains references add an rpath to lib/ + if ${stdenv.cc.targetPrefix}otool -l "$1"| grep -q '@rpath/'; then + ${stdenv.cc.targetPrefix}install_name_tool -add_rpath "$rpath" "$1" fi - done + } - for i in $out/bin/* $out/lib/*.dylib $out/lib/darwin/*.dylib; do - if [[ ! -L "$i" ]]; then - rpathify $i - fi - done + # check that linked library paths exist in $out/lib + # must be run after rpathify is performed + checkDeps() { + local deps=$(${stdenv.cc.targetPrefix}otool -l "$1"| grep -o '@rpath/[^ ]*' || true) + local lib + for lib in $deps; do + if [[ ! -e $out/''${lib/@rpath/lib} ]]; then + echo "error: $1 missing lib for $lib" >&2 + exit 1 + fi + done + } - for i in $out/bin/*; do - if [[ ! -L "$i" ]] && isMachO "$i"; then - ${stdenv.cc.targetPrefix}install_name_tool -add_rpath '@executable_path/../lib' $i + for i in $out/bin/* unpack/bin/* $out/lib{,/darwin}/*.dylib; do + if [[ ! -L $i ]] && isMachO "$i"; then + rpathify "$i" + checkDeps "$i" fi done - ${if stdenv.targetPlatform.isx86_64 then '' - rpathify $out/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation - '' else '' - sed -i -e 's|/nix/store/.*/libobjc.A.dylib|@executable_path/../libobjc.A.dylib|g' \ - $out/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation.tbd - ''} - + nuke-refs $out/bin/* nuke-refs $out/lib/* - nuke-refs $out/lib/system/* nuke-refs $out/lib/darwin/* - ${lib.optionalString stdenv.targetPlatform.isx86_64 '' - nuke-refs $out/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation - ''} + nuke-refs $out/lib/system/* + nuke-refs unpack/bin/* mkdir $out/.pack mv $out/* $out/.pack mv $out/.pack $out/pack + # validate that tools contain no references into the archive + for tool in unpack/bin/*; do + deps=$(${stdenv.cc.targetPrefix}otool -l "$tool"| grep '@rpath/' || true) + if [[ -n "$deps" ]]; then + printf "error: $tool is not self contained\n$deps\n" >&2 + exit 1 + fi + done + mkdir $out/on-server - dumpnar $out/pack | ${xz}/bin/xz > $out/on-server/bootstrap-tools.nar.xz + cp -r unpack $out + + XZ_OPT="-9 -T $NIX_BUILD_CORES" tar cvJf $out/on-server/bootstrap-tools.tar.xz \ + --hard-dereference --sort=name --numeric-owner --owner=0 --group=0 --mtime=@1 -C $out/pack . + dumpnar $out/unpack | xz -9 -T $NIX_BUILD_CORES > $out/on-server/unpack.nar.xz ''; allowedReferences = []; @@ -216,44 +296,49 @@ rec { }; }; - dist = stdenv.mkDerivation { - name = "stdenv-bootstrap-tools"; - - buildCommand = '' - mkdir -p $out/nix-support - echo "file tools ${build}/on-server/bootstrap-tools.nar.xz" >> $out/nix-support/hydra-build-products - ''; - }; + dist = runCommand "stdenv-bootstrap-tools" {} '' + mkdir -p $out/nix-support + echo "file tarball ${build}/on-server/*.tar.xz" >> $out/nix-support/hydra-build-products + echo "file unpack ${build}/on-server/unpack.* " >> $out/nix-support/hydra-build-products + ''; bootstrapFiles = { - tools = "${build}/pack"; + bootstrapTools = "${build}/on-server/bootstrap-tools.tar.xz"; + unpack = runCommand "unpack" { allowedReferences = []; } '' + cp -r ${build}/unpack $out + ''; }; bootstrapTools = derivation { inherit (stdenv.hostPlatform) system; name = "bootstrap-tools"; - builder = "${bootstrapFiles.tools}/bin/bash"; + builder = "${bootstrapFiles.unpack}/bin/bash"; - # This is by necessity a near-duplicate of patch-bootstrap-tools.sh. If we refer to it directly, - # we can't make any changes to it due to our testing stdenv depending on it. Think of this as the - # patch-bootstrap-tools.sh for the next round of bootstrap tools. - args = [ ./patch-bootstrap-tools-next.sh ]; + args = [ + "${bootstrapFiles.unpack}/bootstrap-tools-unpack.sh" + bootstrapFiles.bootstrapTools + ]; - inherit (bootstrapFiles) tools; + PATH = lib.makeBinPath [ + (placeholder "out") + bootstrapFiles.unpack + ]; allowedReferences = [ "out" ]; }; - test = stdenv.mkDerivation { - name = "test"; - - realBuilder = "${bootstrapTools}/bin/bash"; - + test = derivation { + name = "test-bootstrap-tools"; + inherit (stdenv.hostPlatform) system; + builder = "${bootstrapTools}/bin/bash"; + args = [ "-euo" "pipefail" "-c" "eval \"$buildCommand\"" ]; + PATH = lib.makeBinPath [ bootstrapTools ]; tools = bootstrapTools; + "${stdenv.cc.darwinMinVersionVariable}" = stdenv.cc.darwinMinVersion; + + # Create a pure environment where we use just what's in the bootstrap tools. buildCommand = '' - # Create a pure environment where we use just what's in the bootstrap tools. - export PATH=$tools/bin ls -l mkdir $out @@ -280,16 +365,15 @@ rec { ${stdenv.cc.libc_dev}/lib/system \ libSystem-boot - substituteInPlace libSystem-boot/libSystem.B.tbd \ - --replace "/usr/lib/system/" "$PWD/libSystem-boot/system/" + sed -i "s|/usr/lib/system/|$PWD/libSystem-boot/system/|g" libSystem-boot/libSystem.B.tbd ln -s libSystem.B.tbd libSystem-boot/libSystem.tbd # End of bootstrap libSystem export flags="-idirafter $tools/include-Libsystem --sysroot=$tools -L$tools/lib -L$PWD/libSystem-boot" export CPP="clang -E $flags" - export CC="clang $flags -rpath $tools/lib" - export CXX="clang++ $flags --stdlib=libc++ -lc++abi -isystem$tools/include/c++/v1 -rpath $tools/lib" + export CC="clang $flags" + export CXX="clang++ $flags --stdlib=libc++ -isystem$tools/include/c++/v1" # NOTE: These tests do a separate 'install' step (using cp), because # having clang write directly to the final location apparently will make @@ -306,22 +390,23 @@ rec { cp hello1 $out/bin/ $out/bin/hello1 - echo '#include <CoreFoundation/CoreFoundation.h>' >> hello2.c - echo 'int main() { CFShow(CFSTR("Hullo")); return 0; }' >> hello2.c - $CC -F$tools/Library/Frameworks -framework CoreFoundation -o hello2 hello2.c - cp hello2 $out/bin/ - $out/bin/hello2 - echo '#include <iostream>' >> hello3.cc echo 'int main() { std::cout << "Hello World\n"; }' >> hello3.cc $CXX -v -o hello3 hello3.cc cp hello3 $out/bin/ $out/bin/hello3 + # test that libc++.dylib rpaths are correct so it can reference libc++abi.dylib when linked. + # using -Wl,-flat_namespace is required to generate an error + mkdir libtest/ + ln -s $tools/lib/libc++.dylib libtest/ + clang++ -Wl,-flat_namespace -idirafter $tools/include-Libsystem -isystem$tools/include/c++/v1 \ + --sysroot=$tools -L./libtest -L$PWD/libSystem-boot hello3.cc + tar xvf ${hello.src} cd hello-* - # stdenv bootstrap tools ship a broken libiconv.dylib https://github.com/NixOS/nixpkgs/issues/158331 - am_cv_func_iconv=no ./configure --prefix=$out + # hello configure detects -liconv is needed but doesn't add to the link step + LDFLAGS=-liconv ./configure --prefix=$out make make install $out/bin/hello diff --git a/pkgs/stdenv/darwin/patch-bootstrap-tools-next.sh b/pkgs/stdenv/darwin/patch-bootstrap-tools-next.sh deleted file mode 100644 index a5b9edff7cd5..000000000000 --- a/pkgs/stdenv/darwin/patch-bootstrap-tools-next.sh +++ /dev/null @@ -1,38 +0,0 @@ -set -euo pipefail - -export PATH=$tools/bin - -cp -R $tools $out -chmod -R u+w $out - -updateInstallName() { - local path="$1" - - cp "$path" "$path.new" - install_name_tool -id "$path" "$path.new" - codesign -f -i "$(basename "$path")" -s - "$path.new" - mv -f "$path.new" "$path" -} - -find $out/lib -type f -name '*.dylib' -print0 | while IFS= read -r -d $'\0' lib; do - updateInstallName "$lib" -done - -# Provide a gunzip script. -cat > $out/bin/gunzip <<EOF -#!$out/bin/sh -exec $out/bin/gzip -d "\$@" -EOF -chmod +x $out/bin/gunzip - -# Provide fgrep/egrep. -echo "#! $out/bin/sh" > $out/bin/egrep -echo "exec $out/bin/grep -E \"\$@\"" >> $out/bin/egrep -echo "#! $out/bin/sh" > $out/bin/fgrep -echo "exec $out/bin/grep -F \"\$@\"" >> $out/bin/fgrep - -cat >$out/bin/dsymutil << EOF -#!$out/bin/sh -EOF - -chmod +x $out/bin/egrep $out/bin/fgrep $out/bin/dsymutil diff --git a/pkgs/stdenv/darwin/unpack-bootstrap-tools-aarch64.sh b/pkgs/stdenv/darwin/unpack-bootstrap-tools-aarch64.sh index 63b72972d717..4bb84f6409cb 100644 --- a/pkgs/stdenv/darwin/unpack-bootstrap-tools-aarch64.sh +++ b/pkgs/stdenv/darwin/unpack-bootstrap-tools-aarch64.sh @@ -19,6 +19,11 @@ updateInstallName() { cp "$path" "$path.new" install_name_tool -id "$path" "$path.new" + # workaround for https://github.com/NixOS/nixpkgs/issues/294518 + # libc++.1.0.dylib contains wrong LC_RPATH + if [[ ${path} == *libc++.1.0.dylib ]]; then + install_name_tool -add_rpath @loader_path/.. "${path}.new" + fi codesign -f -i "$(basename "$path")" -s - "$path.new" mv -f "$path.new" "$path" } diff --git a/pkgs/stdenv/generic/default.nix b/pkgs/stdenv/generic/default.nix index e764571869db..2cda43d5632f 100644 --- a/pkgs/stdenv/generic/default.nix +++ b/pkgs/stdenv/generic/default.nix @@ -52,7 +52,7 @@ argsStdenv@{ name ? "stdenv", preHook ? "", initialPath , # The implementation of `mkDerivation`, parameterized with the final stdenv so we can tie the knot. # This is convient to have as a parameter so the stdenv "adapters" work better - mkDerivationFromStdenv ? import ./make-derivation.nix { inherit lib config; } + mkDerivationFromStdenv ? stdenv: (import ./make-derivation.nix { inherit lib config; } stdenv).mkDerivation }: let diff --git a/pkgs/stdenv/generic/make-derivation.nix b/pkgs/stdenv/generic/make-derivation.nix index 6a53d519045c..08cded664254 100644 --- a/pkgs/stdenv/generic/make-derivation.nix +++ b/pkgs/stdenv/generic/make-derivation.nix @@ -9,7 +9,6 @@ let assertMsg attrNames boolToString - chooseDevOutputs concatLists concatMap concatMapStrings @@ -19,7 +18,7 @@ let extendDerivation filter findFirst - flip + getDev head imap1 isAttrs @@ -40,6 +39,15 @@ let unique ; + inherit (import ../../build-support/lib/cmake.nix { inherit lib stdenv; }) makeCMakeFlags; + inherit (import ../../build-support/lib/meson.nix { inherit lib stdenv; }) makeMesonFlags; + + mkDerivation = + fnOrAttrs: + if builtins.isFunction fnOrAttrs + then makeDerivationExtensible fnOrAttrs + else makeDerivationExtensibleConst fnOrAttrs; + checkMeta = import ./check-meta.nix { inherit lib config; # Nix itself uses the `system` field of a derivation to decide where @@ -102,11 +110,42 @@ let makeDerivationExtensible (self: attrs // (if builtins.isFunction f0 || f0?__functor then f self attrs else f0))) attrs; - mkDerivationSimple = overrideAttrs: + knownHardeningFlags = [ + "bindnow" + "format" + "fortify" + "fortify3" + "pic" + "pie" + "relro" + "stackprotector" + "strictoverflow" + "trivialautovarinit" + "zerocallusedregs" + ]; + removedOrReplacedAttrNames = [ + "checkInputs" "installCheckInputs" + "nativeCheckInputs" "nativeInstallCheckInputs" + "__contentAddressed" + "__darwinAllowLocalNetworking" + "__impureHostDeps" "__propagatedImpureHostDeps" + "sandboxProfile" "propagatedSandboxProfile" + ]; -# `mkDerivation` wraps the builtin `derivation` function to -# produce derivations that use this stdenv and its shell. + # Turn a derivation into its outPath without a string context attached. + # See the comment at the usage site. + unsafeDerivationToUntrackedOutpath = drv: + if isDerivation drv + then builtins.unsafeDiscardStringContext drv.outPath + else drv; + + makeDerivationArgument = + + +# `makeDerivationArgument` is responsible for the `mkDerivation` arguments that +# affect the actual derivation, excluding a few behaviors that are not +# essential, and specific to `mkDerivation`: `env`, `cmakeFlags`, `mesonFlags`. # # See also: # @@ -146,8 +185,6 @@ let # Configure Phase , configureFlags ? [] -, cmakeFlags ? [] -, mesonFlags ? [] , # Target is not included by default because most programs don't care. # Including it then would cause needless mass rebuilds. # @@ -169,14 +206,6 @@ let , enableParallelBuilding ? config.enableParallelBuildingByDefault -, meta ? {} -, passthru ? {} -, pos ? # position used in error messages and for meta.position - (if attrs.meta.description or null != null - then builtins.unsafeGetAttrPos "description" attrs.meta - else if attrs.version or null != null - then builtins.unsafeGetAttrPos "version" attrs - else builtins.unsafeGetAttrPos "name" attrs) , separateDebugInfo ? false , outputs ? [ "out" ] , __darwinAllowLocalNetworking ? false @@ -198,8 +227,6 @@ let # but for anything complex, be prepared to debug if enabling. , __structuredAttrs ? config.structuredAttrsByDefault or false -, env ? { } - , ... } @ attrs: # Policy on acceptable hash types in nixpkgs @@ -222,13 +249,6 @@ let separateDebugInfo' = separateDebugInfo && stdenv.hostPlatform.isLinux; outputs' = outputs ++ optional separateDebugInfo' "debug"; - # Turn a derivation into its outPath without a string context attached. - # See the comment at the usage site. - unsafeDerivationToUntrackedOutpath = drv: - if isDerivation drv - then builtins.unsafeDiscardStringContext drv.outPath - else drv; - noNonNativeDeps = builtins.length (depsBuildTarget ++ depsBuildTargetPropagated ++ depsHostHost ++ depsHostHostPropagated ++ buildInputs ++ propagatedBuildInputs @@ -239,19 +259,6 @@ let # disabling fortify implies fortify3 should also be disabled then unique (hardeningDisable ++ [ "fortify3" ]) else hardeningDisable; - knownHardeningFlags = [ - "bindnow" - "format" - "fortify" - "fortify3" - "pic" - "pie" - "relro" - "stackprotector" - "strictoverflow" - "trivialautovarinit" - "zerocallusedregs" - ]; defaultHardeningFlags = (if stdenv.hasCC then stdenv.cc else {}).defaultHardeningFlags or # fallback safe-ish set of flags @@ -264,10 +271,13 @@ let erroneousHardeningFlags = subtractLists knownHardeningFlags (hardeningEnable ++ remove "all" hardeningDisable); checkDependencyList = checkDependencyList' []; - checkDependencyList' = positions: name: deps: flip imap1 deps (index: dep: - if isDerivation dep || dep == null || builtins.isString dep || builtins.isPath dep then dep - else if isList dep then checkDependencyList' ([index] ++ positions) name dep - else throw "Dependency is not of a valid type: ${concatMapStrings (ix: "element ${toString ix} of ") ([index] ++ positions)}${name} for ${attrs.name or attrs.pname}"); + checkDependencyList' = positions: name: deps: + imap1 + (index: dep: + if isDerivation dep || dep == null || builtins.isString dep || builtins.isPath dep then dep + else if isList dep then checkDependencyList' ([index] ++ positions) name dep + else throw "Dependency is not of a valid type: ${concatMapStrings (ix: "element ${toString ix} of ") ([index] ++ positions)}${name} for ${attrs.name or attrs.pname}") + deps; in if builtins.length erroneousHardeningFlags != 0 then abort ("mkDerivation was called with unsupported hardening flags: " + lib.generators.toPretty {} { inherit erroneousHardeningFlags hardeningDisable hardeningEnable knownHardeningFlags; @@ -286,70 +296,37 @@ else let outputs = outputs'; - references = nativeBuildInputs ++ buildInputs - ++ propagatedNativeBuildInputs ++ propagatedBuildInputs; - - dependencies = map (map chooseDevOutputs) [ + dependencies = [ [ - (map (drv: drv.__spliced.buildBuild or drv) (checkDependencyList "depsBuildBuild" depsBuildBuild)) - (map (drv: drv.__spliced.buildHost or drv) (checkDependencyList "nativeBuildInputs" nativeBuildInputs')) - (map (drv: drv.__spliced.buildTarget or drv) (checkDependencyList "depsBuildTarget" depsBuildTarget)) + (map (drv: getDev drv.__spliced.buildBuild or drv) (checkDependencyList "depsBuildBuild" depsBuildBuild)) + (map (drv: getDev drv.__spliced.buildHost or drv) (checkDependencyList "nativeBuildInputs" nativeBuildInputs')) + (map (drv: getDev drv.__spliced.buildTarget or drv) (checkDependencyList "depsBuildTarget" depsBuildTarget)) ] [ - (map (drv: drv.__spliced.hostHost or drv) (checkDependencyList "depsHostHost" depsHostHost)) - (map (drv: drv.__spliced.hostTarget or drv) (checkDependencyList "buildInputs" buildInputs')) + (map (drv: getDev drv.__spliced.hostHost or drv) (checkDependencyList "depsHostHost" depsHostHost)) + (map (drv: getDev drv.__spliced.hostTarget or drv) (checkDependencyList "buildInputs" buildInputs')) ] [ - (map (drv: drv.__spliced.targetTarget or drv) (checkDependencyList "depsTargetTarget" depsTargetTarget)) + (map (drv: getDev drv.__spliced.targetTarget or drv) (checkDependencyList "depsTargetTarget" depsTargetTarget)) ] ]; - propagatedDependencies = map (map chooseDevOutputs) [ + propagatedDependencies = [ [ - (map (drv: drv.__spliced.buildBuild or drv) (checkDependencyList "depsBuildBuildPropagated" depsBuildBuildPropagated)) - (map (drv: drv.__spliced.buildHost or drv) (checkDependencyList "propagatedNativeBuildInputs" propagatedNativeBuildInputs)) - (map (drv: drv.__spliced.buildTarget or drv) (checkDependencyList "depsBuildTargetPropagated" depsBuildTargetPropagated)) + (map (drv: getDev drv.__spliced.buildBuild or drv) (checkDependencyList "depsBuildBuildPropagated" depsBuildBuildPropagated)) + (map (drv: getDev drv.__spliced.buildHost or drv) (checkDependencyList "propagatedNativeBuildInputs" propagatedNativeBuildInputs)) + (map (drv: getDev drv.__spliced.buildTarget or drv) (checkDependencyList "depsBuildTargetPropagated" depsBuildTargetPropagated)) ] [ - (map (drv: drv.__spliced.hostHost or drv) (checkDependencyList "depsHostHostPropagated" depsHostHostPropagated)) - (map (drv: drv.__spliced.hostTarget or drv) (checkDependencyList "propagatedBuildInputs" propagatedBuildInputs)) + (map (drv: getDev drv.__spliced.hostHost or drv) (checkDependencyList "depsHostHostPropagated" depsHostHostPropagated)) + (map (drv: getDev drv.__spliced.hostTarget or drv) (checkDependencyList "propagatedBuildInputs" propagatedBuildInputs)) ] [ - (map (drv: drv.__spliced.targetTarget or drv) (checkDependencyList "depsTargetTargetPropagated" depsTargetTargetPropagated)) + (map (drv: getDev drv.__spliced.targetTarget or drv) (checkDependencyList "depsTargetTargetPropagated" depsTargetTargetPropagated)) ] ]; - computedSandboxProfile = - concatMap (input: input.__propagatedSandboxProfile or []) - (stdenv.extraNativeBuildInputs - ++ stdenv.extraBuildInputs - ++ concatLists dependencies); - - computedPropagatedSandboxProfile = - concatMap (input: input.__propagatedSandboxProfile or []) - (concatLists propagatedDependencies); - - computedImpureHostDeps = - unique (concatMap (input: input.__propagatedImpureHostDeps or []) - (stdenv.extraNativeBuildInputs - ++ stdenv.extraBuildInputs - ++ concatLists dependencies)); - - computedPropagatedImpureHostDeps = - unique (concatMap (input: input.__propagatedImpureHostDeps or []) - (concatLists propagatedDependencies)); - - envIsExportable = isAttrs env && !isDerivation env; - derivationArg = - (removeAttrs attrs - (["meta" "passthru" "pos" - "checkInputs" "installCheckInputs" - "nativeCheckInputs" "nativeInstallCheckInputs" - "__contentAddressed" - "__darwinAllowLocalNetworking" - "__impureHostDeps" "__propagatedImpureHostDeps" - "sandboxProfile" "propagatedSandboxProfile"] - ++ optional (__structuredAttrs || envIsExportable) "env")) + removeAttrs attrs removedOrReplacedAttrNames // (optionalAttrs (attrs ? name || (attrs ? pname && attrs ? version)) { name = let @@ -377,7 +354,7 @@ else let assert assertMsg (attrs ? version && attrs.version != null) "The ‘version’ attribute cannot be null."; "${attrs.pname}${staticMarker}${hostSuffix}-${attrs.version}" ); - }) // optionalAttrs __structuredAttrs { env = checkedEnv; } // { + }) // { builder = attrs.realBuilder or stdenv.shell; args = attrs.args or ["-e" (attrs.builder or ./default-builder.sh)]; inherit stdenv; @@ -415,54 +392,6 @@ else let ++ optional (elem "host" configurePlatforms) "--host=${stdenv.hostPlatform.config}" ++ optional (elem "target" configurePlatforms) "--target=${stdenv.targetPlatform.config}"; - cmakeFlags = - cmakeFlags - ++ optionals (stdenv.hostPlatform != stdenv.buildPlatform) ([ - "-DCMAKE_SYSTEM_NAME=${findFirst isString "Generic" (optional (!stdenv.hostPlatform.isRedox) stdenv.hostPlatform.uname.system)}" - ] ++ optionals (stdenv.hostPlatform.uname.processor != null) [ - "-DCMAKE_SYSTEM_PROCESSOR=${stdenv.hostPlatform.uname.processor}" - ] ++ optionals (stdenv.hostPlatform.uname.release != null) [ - "-DCMAKE_SYSTEM_VERSION=${stdenv.hostPlatform.uname.release}" - ] ++ optionals (stdenv.hostPlatform.isDarwin) [ - "-DCMAKE_OSX_ARCHITECTURES=${stdenv.hostPlatform.darwinArch}" - ] ++ optionals (stdenv.buildPlatform.uname.system != null) [ - "-DCMAKE_HOST_SYSTEM_NAME=${stdenv.buildPlatform.uname.system}" - ] ++ optionals (stdenv.buildPlatform.uname.processor != null) [ - "-DCMAKE_HOST_SYSTEM_PROCESSOR=${stdenv.buildPlatform.uname.processor}" - ] ++ optionals (stdenv.buildPlatform.uname.release != null) [ - "-DCMAKE_HOST_SYSTEM_VERSION=${stdenv.buildPlatform.uname.release}" - ] ++ optionals (stdenv.buildPlatform.canExecute stdenv.hostPlatform) [ - "-DCMAKE_CROSSCOMPILING_EMULATOR=env" - ] ++ lib.optionals stdenv.hostPlatform.isStatic [ - "-DCMAKE_LINK_SEARCH_START_STATIC=ON" - ]); - - mesonFlags = - let - # See https://mesonbuild.com/Reference-tables.html#cpu-families - cpuFamily = platform: with platform; - /**/ if isAarch32 then "arm" - else if isx86_32 then "x86" - else platform.uname.processor; - - crossFile = builtins.toFile "cross-file.conf" '' - [properties] - bindgen_clang_arguments = ['-target', '${stdenv.targetPlatform.config}'] - needs_exe_wrapper = ${boolToString (!stdenv.buildPlatform.canExecute stdenv.hostPlatform)} - - [host_machine] - system = '${stdenv.targetPlatform.parsed.kernel.name}' - cpu_family = '${cpuFamily stdenv.targetPlatform}' - cpu = '${stdenv.targetPlatform.parsed.cpu.name}' - endian = ${if stdenv.targetPlatform.isLittleEndian then "'little'" else "'big'"} - - [binaries] - llvm-config = 'llvm-config-native' - rust = ['rustc', '--target', '${stdenv.targetPlatform.rust.rustcTargetSpec}'] - ''; - crossFlags = optionals (stdenv.hostPlatform != stdenv.buildPlatform) [ "--cross-file=${crossFile}" ]; - in crossFlags ++ mesonFlags; - inherit patches; inherit doCheck doInstallCheck; @@ -482,7 +411,28 @@ else let NIX_HARDENING_ENABLE = enabledHardeningOptions; } // optionalAttrs (stdenv.hostPlatform.isx86_64 && stdenv.hostPlatform ? gcc.arch) { requiredSystemFeatures = attrs.requiredSystemFeatures or [] ++ [ "gccarch-${stdenv.hostPlatform.gcc.arch}" ]; - } // optionalAttrs (stdenv.buildPlatform.isDarwin) { + } // optionalAttrs (stdenv.buildPlatform.isDarwin) ( + let + computedSandboxProfile = + concatMap (input: input.__propagatedSandboxProfile or []) + (stdenv.extraNativeBuildInputs + ++ stdenv.extraBuildInputs + ++ concatLists dependencies); + + computedPropagatedSandboxProfile = + concatMap (input: input.__propagatedSandboxProfile or []) + (concatLists propagatedDependencies); + + computedImpureHostDeps = + unique (concatMap (input: input.__propagatedImpureHostDeps or []) + (stdenv.extraNativeBuildInputs + ++ stdenv.extraBuildInputs + ++ concatLists dependencies)); + + computedPropagatedImpureHostDeps = + unique (concatMap (input: input.__propagatedImpureHostDeps or []) + (concatLists propagatedDependencies)); + in { inherit __darwinAllowLocalNetworking; # TODO: remove `unique` once nix has a list canonicalization primitive __sandboxProfile = @@ -497,7 +447,7 @@ else let "/bin/sh" ]; __propagatedImpureHostDeps = computedPropagatedImpureHostDeps ++ __propagatedImpureHostDeps; - } // + }) // # If we use derivations directly here, they end up as build-time dependencies. # This is especially problematic in the case of disallowed*, since the disallowed # derivations will be built by nix as build-time dependencies, while those @@ -533,7 +483,82 @@ else let mapNullable unsafeDerivationToUntrackedOutpath attrs.allowedRequisites; }; - meta = checkMeta.commonMeta { inherit validity attrs pos references; }; +in + derivationArg; + +mkDerivationSimple = overrideAttrs: + +# `mkDerivation` wraps the builtin `derivation` function to +# produce derivations that use this stdenv and its shell. +# +# Internally, it delegates most of its behavior to `makeDerivationArgument`, +# except for the `env`, `cmakeFlags`, and `mesonFlags` attributes, as well +# as the attributes `meta` and `passthru` that affect [package attributes], +# and not the derivation itself. +# +# See also: +# +# * https://nixos.org/nixpkgs/manual/#sec-using-stdenv +# Details on how to use this mkDerivation function +# +# * https://nixos.org/manual/nix/stable/expressions/derivations.html#derivations +# Explanation about derivations in general +# +# * [package attributes]: https://nixos.org/manual/nix/stable/glossary#package-attribute-set +{ + +# Configure Phase + cmakeFlags ? [] +, mesonFlags ? [] + +, meta ? {} +, passthru ? {} +, pos ? # position used in error messages and for meta.position + (if attrs.meta.description or null != null + then builtins.unsafeGetAttrPos "description" attrs.meta + else if attrs.version or null != null + then builtins.unsafeGetAttrPos "version" attrs + else builtins.unsafeGetAttrPos "name" attrs) + +# Experimental. For simple packages mostly just works, +# but for anything complex, be prepared to debug if enabling. +, __structuredAttrs ? config.structuredAttrsByDefault or false + +, env ? { } + +, ... } @ attrs: + +# Policy on acceptable hash types in nixpkgs +assert attrs ? outputHash -> ( + let algo = + attrs.outputHashAlgo or (head (splitString "-" attrs.outputHash)); + in + if algo == "md5" then + throw "Rejected insecure ${algo} hash '${attrs.outputHash}'" + else + true +); + +let + envIsExportable = isAttrs env && !isDerivation env; + + derivationArg = makeDerivationArgument + (removeAttrs + attrs + (["meta" "passthru" "pos"] + ++ optional (__structuredAttrs || envIsExportable) "env" + ) + // optionalAttrs __structuredAttrs { env = checkedEnv; } + // { + cmakeFlags = makeCMakeFlags attrs; + mesonFlags = makeMesonFlags attrs; + }); + + meta = checkMeta.commonMeta { + inherit validity attrs pos; + references = attrs.nativeBuildInputs or [] ++ attrs.buildInputs or [] + ++ attrs.propagatedNativeBuildInputs or [] ++ attrs.propagatedBuildInputs or []; + }; validity = checkMeta.assertValidity { inherit meta attrs; }; checkedEnv = @@ -603,7 +628,6 @@ extendDerivation (derivation (derivationArg // optionalAttrs envIsExportable checkedEnv)); in - fnOrAttrs: - if builtins.isFunction fnOrAttrs - then makeDerivationExtensible fnOrAttrs - else makeDerivationExtensibleConst fnOrAttrs +{ + inherit mkDerivation; +} |