uboot: (firmwareOdroidC2/C4) don't invoke patch tool, use patches = [] instead

https://github.com/NixOS/nixpkgs/blob/master/pkgs/stdenv/generic/setup.sh#L948
this can do it nicely.

Signed-off-by: Anton Arapov <anton@deadbeef.mx>
This commit is contained in:
Anton Arapov 2021-04-03 12:58:10 +02:00 committed by Alan Daniels
commit 56de2bcd43
30691 changed files with 3076956 additions and 0 deletions

271
pkgs/stdenv/adapters.nix Normal file
View file

@ -0,0 +1,271 @@
/* This file contains various functions that take a stdenv and return
a new stdenv with different behaviour, e.g. using a different C
compiler. */
{ lib, pkgs, config }:
let
# N.B. Keep in sync with default arg for stdenv/generic.
defaultMkDerivationFromStdenv = import ./generic/make-derivation.nix { inherit lib config; };
# Low level function to help with overriding `mkDerivationFromStdenv`. One
# gives it the old stdenv arguments and a "continuation" function, and
# underneath the final stdenv argument it yields to the continuation to do
# whatever it wants with old `mkDerivation` (old `mkDerivationFromStdenv`
# applied to the *new, final* stdenv) provided for convenience.
withOldMkDerivation = stdenvSuperArgs: k: stdenvSelf: let
mkDerivationFromStdenv-super = stdenvSuperArgs.mkDerivationFromStdenv or defaultMkDerivationFromStdenv;
mkDerivationSuper = mkDerivationFromStdenv-super stdenvSelf;
in
k stdenvSelf mkDerivationSuper;
# Wrap the original `mkDerivation` providing extra args to it.
extendMkDerivationArgs = old: f: withOldMkDerivation old (_: mkDerivationSuper: args:
(mkDerivationSuper args).overrideAttrs f);
# Wrap the original `mkDerivation` transforming the result.
overrideMkDerivationResult = old: f: withOldMkDerivation old (_: mkDerivationSuper: args:
f (mkDerivationSuper args));
in
rec {
# Override the compiler in stdenv for specific packages.
overrideCC = stdenv: cc: stdenv.override { allowedRequisites = null; cc = cc; };
# Add some arbitrary packages to buildInputs for specific packages.
# Used to override packages in stdenv like Make. Should not be used
# for other dependencies.
overrideInStdenv = stdenv: pkgs:
stdenv.override (prev: { allowedRequisites = null; extraBuildInputs = (prev.extraBuildInputs or []) ++ pkgs; });
# Override the setup script of stdenv. Useful for testing new
# versions of the setup script without causing a rebuild of
# everything.
#
# Example:
# randomPkg = import ../bla { ...
# stdenv = overrideSetup stdenv ../stdenv/generic/setup-latest.sh;
# };
overrideSetup = stdenv: setupScript: stdenv.override { inherit setupScript; };
# Return a modified stdenv that tries to build statically linked
# binaries.
makeStaticBinaries = stdenv0:
stdenv0.override (old: {
mkDerivationFromStdenv = withOldMkDerivation old (stdenv: mkDerivationSuper: args:
if stdenv.hostPlatform.isDarwin
then throw "Cannot build fully static binaries on Darwin/macOS"
else (mkDerivationSuper args).overrideAttrs(finalAttrs: {
NIX_CFLAGS_LINK = toString (finalAttrs.NIX_CFLAGS_LINK or "") + " -static";
} // lib.optionalAttrs (!(finalAttrs.dontAddStaticConfigureFlags or false)) {
configureFlags = (finalAttrs.configureFlags or []) ++ [
"--disable-shared" # brrr...
];
}));
} // lib.optionalAttrs (stdenv0.hostPlatform.libc == "libc") {
extraBuildInputs = (old.extraBuildInputs or []) ++ [
pkgs.glibc.static
];
});
# Return a modified stdenv that builds static libraries instead of
# shared libraries.
makeStaticLibraries = stdenv:
stdenv.override (old: {
mkDerivationFromStdenv = extendMkDerivationArgs old (args: {
dontDisableStatic = true;
} // lib.optionalAttrs (!(args.dontAddStaticConfigureFlags or false)) {
configureFlags = (args.configureFlags or []) ++ [
"--enable-static"
"--disable-shared"
];
cmakeFlags = (args.cmakeFlags or []) ++ [ "-DBUILD_SHARED_LIBS:BOOL=OFF" ];
mesonFlags = (args.mesonFlags or []) ++ [ "-Ddefault_library=static" ];
});
});
# Best effort static binaries. Will still be linked to libSystem,
# but more portable than Nix store binaries.
makeStaticDarwin = stdenv: stdenv.override (old: {
# extraBuildInputs are dropped in cross.nix, but darwin still needs them
extraBuildInputs = [ pkgs.buildPackages.darwin.CF ];
mkDerivationFromStdenv = extendMkDerivationArgs old (args: {
NIX_CFLAGS_LINK = toString (args.NIX_CFLAGS_LINK or "")
+ lib.optionalString (stdenv.cc.isGNU or false) " -static-libgcc";
nativeBuildInputs = (args.nativeBuildInputs or []) ++ [
(pkgs.buildPackages.makeSetupHook {
substitutions = {
libsystem = "${stdenv.cc.libc}/lib/libSystem.B.dylib";
};
} ./darwin/portable-libsystem.sh)
];
});
});
# Puts all the other ones together
makeStatic = stdenv: lib.foldl (lib.flip lib.id) stdenv (
lib.optional stdenv.hostPlatform.isDarwin makeStaticDarwin
++ [ makeStaticLibraries propagateBuildInputs ]
# Apple does not provide a static version of libSystem or crt0.o
# So we cant build static binaries without extensive hacks.
++ lib.optional (!stdenv.hostPlatform.isDarwin) makeStaticBinaries
# Glibc doesnt come with static runtimes by default.
# ++ lib.optional (stdenv.hostPlatform.libc == "glibc") ((lib.flip overrideInStdenv) [ self.glibc.static ])
);
/* Modify a stdenv so that all buildInputs are implicitly propagated to
consuming derivations
*/
propagateBuildInputs = stdenv:
stdenv.override (old: {
mkDerivationFromStdenv = extendMkDerivationArgs old (args: {
propagatedBuildInputs = (args.propagatedBuildInputs or []) ++ (args.buildInputs or []);
buildInputs = [];
});
});
/* Modify a stdenv so that the specified attributes are added to
every derivation returned by its mkDerivation function.
Example:
stdenvNoOptimise =
addAttrsToDerivation
{ NIX_CFLAGS_COMPILE = "-O0"; }
stdenv;
*/
addAttrsToDerivation = extraAttrs: stdenv: stdenv.override (old: {
mkDerivationFromStdenv = extendMkDerivationArgs old (_: extraAttrs);
});
# remove after 22.05 and before 22.11
addCoverageInstrumentation = stdenv:
builtins.trace "'addCoverageInstrumentation' adapter is deprecated and will be removed before 22.11"
overrideInStdenv stdenv [ pkgs.enableGCOVInstrumentation pkgs.keepBuildTree ];
# remove after 22.05 and before 22.11
replaceMaintainersField = stdenv: pkgs: maintainers:
builtins.trace "'replaceMaintainersField' adapter is deprecated and will be removed before 22.11"
stdenv.override (old: {
mkDerivationFromStdenv = overrideMkDerivationResult (pkg:
lib.recursiveUpdate pkg { meta.maintainers = maintainers; });
});
/* Use the trace output to report all processed derivations with their
license name.
*/
traceDrvLicenses = stdenv:
stdenv.override (old: {
mkDerivationFromStdenv = overrideMkDerivationResult (pkg:
let
printDrvPath = val: let
drvPath = builtins.unsafeDiscardStringContext pkg.drvPath;
license = pkg.meta.license or null;
in
builtins.trace "@:drv:${toString drvPath}:${builtins.toString license}:@" val;
in pkg // {
outPath = printDrvPath pkg.outPath;
drvPath = printDrvPath pkg.drvPath;
});
});
# remove after 22.05 and before 22.11
validateLicenses = licensePred: stdenv:
builtins.trace "'validateLicenses' adapter is deprecated and will be removed before 22.11"
stdenv.override (old: {
mkDerivationFromStdenv = overrideMkDerivationResult (pkg:
let
drv = builtins.unsafeDiscardStringContext pkg.drvPath;
license =
pkg.meta.license or
# Fixed-output derivations such as source tarballs usually
# don't have licensing information, but that's OK.
(pkg.outputHash or
(builtins.trace
"warning: ${drv} lacks licensing information" null));
validate = arg:
if licensePred license then arg
else abort ''
while building ${drv}:
license `${builtins.toString license}' does not pass the predicate.
'';
in pkg // {
outPath = validate pkg.outPath;
drvPath = validate pkg.drvPath;
});
});
/* Modify a stdenv so that it produces debug builds; that is,
binaries have debug info, and compiler optimisations are
disabled. */
keepDebugInfo = stdenv:
stdenv.override (old: {
mkDerivationFromStdenv = extendMkDerivationArgs old (args: {
dontStrip = true;
NIX_CFLAGS_COMPILE = toString (args.NIX_CFLAGS_COMPILE or "") + " -ggdb -Og";
});
});
/* Modify a stdenv so that it uses the Gold linker. */
useGoldLinker = stdenv:
stdenv.override (old: {
mkDerivationFromStdenv = extendMkDerivationArgs old (args: {
NIX_CFLAGS_LINK = toString (args.NIX_CFLAGS_LINK or "") + " -fuse-ld=gold";
});
});
/* Modify a stdenv so that it builds binaries optimized specifically
for the machine they are built on.
WARNING: this breaks purity! */
impureUseNativeOptimizations = stdenv:
stdenv.override (old: {
mkDerivationFromStdenv = extendMkDerivationArgs old (args: {
NIX_CFLAGS_COMPILE = toString (args.NIX_CFLAGS_COMPILE or "") + " -march=native";
NIX_ENFORCE_NO_NATIVE = false;
preferLocalBuild = true;
allowSubstitutes = false;
});
});
/* Modify a stdenv so that it builds binaries with the specified list of
compilerFlags appended and passed to the compiler.
This example would recompile every derivation on the system with
-funroll-loops and -O3 passed to each gcc invocation.
Example:
nixpkgs.overlays = [
(self: super: {
stdenv = super.withCFlags [ "-funroll-loops" "-O3" ] super.stdenv;
})
];
*/
withCFlags = compilerFlags: stdenv:
stdenv.override (old: {
mkDerivationFromStdenv = extendMkDerivationArgs old (args: {
NIX_CFLAGS_COMPILE = toString (args.NIX_CFLAGS_COMPILE or "") + " ${toString compilerFlags}";
});
});
}

142
pkgs/stdenv/booter.nix Normal file
View file

@ -0,0 +1,142 @@
# This file defines a single function for booting a package set from a list of
# stages. The exact mechanics of that function are defined below; here I
# (@Ericson2314) wish to describe the purpose of the abstraction.
#
# The first goal is consistency across stdenvs. Regardless of what this function
# does, by making every stdenv use it for bootstrapping we ensure that they all
# work in a similar way. [Before this abstraction, each stdenv was its own
# special snowflake due to different authors writing in different times.]
#
# The second goal is consistency across each stdenv's stage functions. By
# writing each stage it terms of the previous stage, commonalities between them
# are more easily observable. [Before, there usually was a big attribute set
# with each stage, and stages would access the previous stage by name.]
#
# The third goal is composition. Because each stage is written in terms of the
# previous, the list can be reordered or, more practically, extended with new
# stages. The latter is used for cross compiling and custom
# stdenvs. Additionally, certain options should by default apply only to the
# last stage, whatever it may be. By delaying the creation of stage package sets
# until the final fold, we prevent these options from inhibiting composition.
#
# The fourth and final goal is debugging. Normal packages should only source
# their dependencies from the current stage. But for the sake of debugging, it
# is nice that all packages still remain accessible. We make sure previous
# stages are kept around with a `stdenv.__bootPackges` attribute referring the
# previous stage. It is idiomatic that attributes prefixed with `__` come with
# special restrictions and should not be used under normal circumstances.
{ lib, allPackages }:
# Type:
# [ pkgset -> (args to stage/default.nix) or ({ __raw = true; } // pkgs) ]
# -> pkgset
#
# In english: This takes a list of function from the previous stage pkgset and
# returns the final pkgset. Each of those functions returns, if `__raw` is
# undefined or false, args for this stage's pkgset (the most complex and
# important arg is the stdenv), or, if `__raw = true`, simply this stage's
# pkgset itself.
#
# The list takes stages in order, so the final stage is last in the list. In
# other words, this does a foldr not foldl.
stageFuns: let
/* "dfold" a ternary function `op' between successive elements of `list' as if
it was a doubly-linked list with `lnul' and `rnul` base cases at either
end. In precise terms, `dfold op lnul rnul [x_0 x_1 x_2 ... x_n-1]` is the
same as
let
f_-1 = lnul f_0;
f_0 = op f_-1 x_0 f_1;
f_1 = op f_0 x_1 f_2;
f_2 = op f_1 x_2 f_3;
...
f_n = op f_n-1 x_n f_n+1;
f_n+1 = rnul f_n;
in
f_0
*/
dfold = op: lnul: rnul: list:
let
len = builtins.length list;
go = pred: n:
if n == len
then rnul pred
else let
# Note the cycle -- call-by-need ensures finite fold.
cur = op pred (builtins.elemAt list n) succ;
succ = go cur (n + 1);
in cur;
lapp = lnul cur;
cur = go lapp 0;
in cur;
# Take the list and disallow custom overrides in all but the final stage,
# and allow it in the final flag. Only defaults this boolean field if it
# isn't already set.
withAllowCustomOverrides = lib.lists.imap1
(index: stageFun: prevStage:
# So true by default for only the first element because one
# 1-indexing. Since we reverse the list, this means this is true
# for the final stage.
{ allowCustomOverrides = index == 1; }
// (stageFun prevStage))
(lib.lists.reverseList stageFuns);
# Adds the stdenv to the arguments, and sticks in it the previous stage for
# debugging purposes.
folder = nextStage: stageFun: prevStage: let
args = stageFun prevStage;
args' = args // {
stdenv = args.stdenv // {
# For debugging
__bootPackages = prevStage;
__hatPackages = nextStage;
};
};
thisStage =
if args.__raw or false
then args'
else allPackages ((builtins.removeAttrs args' ["selfBuild"]) // {
adjacentPackages = if args.selfBuild or true then null else rec {
pkgsBuildBuild = prevStage.buildPackages;
pkgsBuildHost = prevStage;
pkgsBuildTarget =
if args.stdenv.targetPlatform == args.stdenv.hostPlatform
then pkgsBuildHost
else assert args.stdenv.hostPlatform == args.stdenv.buildPlatform; thisStage;
pkgsHostHost =
if args.stdenv.hostPlatform == args.stdenv.targetPlatform
then thisStage
else assert args.stdenv.buildPlatform == args.stdenv.hostPlatform; pkgsBuildHost;
pkgsTargetTarget = nextStage;
};
});
in thisStage;
# This is a hack for resolving cross-compiled compilers' run-time
# deps. (That is, compilers that are themselves cross-compiled, as
# opposed to used to cross-compile packages.)
postStage = buildPackages: {
__raw = true;
stdenv.cc =
if buildPackages.stdenv.hasCC
then
if buildPackages.stdenv.cc.isClang or false
# buildPackages.clang checks targetPackages.stdenv.cc (i. e. this
# attribute) to get a sense of the its set's default compiler and
# chooses between libc++ and libstdc++ based on that. If we hit this
# code here, we'll cause an infinite recursion. Since a set with
# clang as its default compiler always means libc++, we can infer this
# decision statically.
then buildPackages.llvmPackages.libcxxClang
else buildPackages.gcc
else
# This will blow up if anything uses it, but that's OK. The `if
# buildPackages.stdenv.cc.isClang then ... else ...` would blow up
# everything, so we make sure to avoid that.
buildPackages.stdenv.cc;
};
in dfold folder postStage (_: {}) withAllowCustomOverrides

View file

@ -0,0 +1,15 @@
{pkgs}: [
pkgs.coreutils
pkgs.findutils
pkgs.diffutils
pkgs.gnused
pkgs.gnugrep
pkgs.gawk
pkgs.gnutar
pkgs.gzip
pkgs.bzip2.bin
pkgs.gnumake
pkgs.bash
pkgs.patch
pkgs.xz.bin
]

View file

@ -0,0 +1,93 @@
{ lib
, localSystem, crossSystem, config, overlays, crossOverlays ? []
}:
let
bootStages = import ../. {
inherit lib localSystem overlays;
crossSystem = localSystem;
crossOverlays = [];
# Ignore custom stdenvs when cross compiling for compatability
config = builtins.removeAttrs config [ "replaceStdenv" ];
};
in lib.init bootStages ++ [
# Regular native packages
(somePrevStage: lib.last bootStages somePrevStage // {
# It's OK to change the built-time dependencies
allowCustomOverrides = true;
})
# Build tool Packages
(vanillaPackages: {
inherit config overlays;
selfBuild = false;
stdenv =
assert vanillaPackages.stdenv.buildPlatform == localSystem;
assert vanillaPackages.stdenv.hostPlatform == localSystem;
assert vanillaPackages.stdenv.targetPlatform == localSystem;
vanillaPackages.stdenv.override { targetPlatform = crossSystem; };
# It's OK to change the built-time dependencies
allowCustomOverrides = true;
})
# Run Packages
(buildPackages: let
adaptStdenv =
if crossSystem.isStatic
then buildPackages.stdenvAdapters.makeStatic
else lib.id;
in {
inherit config;
overlays = overlays ++ crossOverlays;
selfBuild = false;
stdenv = adaptStdenv (buildPackages.stdenv.override (old: rec {
buildPlatform = localSystem;
hostPlatform = crossSystem;
targetPlatform = crossSystem;
# Prior overrides are surely not valid as packages built with this run on
# a different platform, and so are disabled.
overrides = _: _: {};
extraBuildInputs = [ ] # Old ones run on wrong platform
++ lib.optionals hostPlatform.isDarwin [ buildPackages.targetPackages.darwin.apple_sdk.frameworks.CoreFoundation ]
;
allowedRequisites = null;
hasCC = !targetPlatform.isGhcjs;
cc = if crossSystem.useiOSPrebuilt or false
then buildPackages.darwin.iosSdkPkgs.clang
else if crossSystem.useAndroidPrebuilt or false
then buildPackages."androidndkPkgs_${crossSystem.ndkVer}".clang
else if targetPlatform.isGhcjs
# Need to use `throw` so tryEval for splicing works, ugh. Using
# `null` or skipping the attribute would cause an eval failure
# `tryEval` wouldn't catch, wrecking accessing previous stages
# when there is a C compiler and everything should be fine.
then throw "no C compiler provided for this platform"
else if crossSystem.isDarwin
then buildPackages.llvmPackages.libcxxClang
else if crossSystem.useLLVM or false
then buildPackages.llvmPackages.clangUseLLVM
else buildPackages.gcc;
extraNativeBuildInputs = old.extraNativeBuildInputs
++ lib.optionals
(hostPlatform.isLinux && !buildPlatform.isLinux)
[ buildPackages.patchelf ]
++ lib.optional
(let f = p: !p.isx86 || builtins.elem p.libc [ "musl" "wasilibc" "relibc" ] || p.isiOS || p.isGenode;
in f hostPlatform && !(f buildPlatform) )
buildPackages.updateAutotoolsGnuConfigScriptsHook
# without proper `file` command, libtool sometimes fails
# to recognize 64-bit DLLs
++ lib.optional (hostPlatform.config == "x86_64-w64-mingw32") buildPackages.file
;
}));
})
]

View file

@ -0,0 +1,25 @@
{ lib
, localSystem, crossSystem, config, overlays, crossOverlays ? []
}:
assert crossSystem == localSystem;
let
bootStages = import ../. {
inherit lib localSystem crossSystem overlays;
# Remove config.replaceStdenv to ensure termination.
config = builtins.removeAttrs config [ "replaceStdenv" ];
};
in bootStages ++ [
# Additional stage, built using custom stdenv
(vanillaPackages: {
inherit config overlays;
stdenv =
assert vanillaPackages.hostPlatform == localSystem;
assert vanillaPackages.targetPlatform == localSystem;
config.replaceStdenv { pkgs = vanillaPackages; };
})
]

View file

@ -0,0 +1,16 @@
# On cygwin, automatic runtime dependency detection does not work
# because the binaries do not contain absolute references to store
# locations (yet)
postFixupHooks+=(_cygwinAllBuildInputsAsRuntimeDep)
_cygwinAllBuildInputsAsRuntimeDep() {
if [ -n "$buildInputs" ]; then
mkdir -p "$out/nix-support"
echo "$buildInputs" >> "$out/nix-support/cygwin-buildinputs-as-runtime-deps"
fi
if [ -n "$nativeBuildInputs" ]; then
mkdir -p "$out/nix-support"
echo "$nativeBuildInputs" >> "$out/nix-support/cygwin-buildinputs-as-runtime-deps"
fi
}

View file

@ -0,0 +1,24 @@
fixupOutputHooks+=(_cygwinFixAutoImageBase)
_cygwinFixAutoImageBase() {
if [ "${dontRebase-}" == 1 ] || [ ! -d "$prefix" ]; then
return
fi
find "$prefix" -name "*.dll" -type f | while read DLL; do
if [ -f /etc/rebasenix.nextbase ]; then
NEXTBASE="$(</etc/rebasenix.nextbase)"
fi
NEXTBASE=${NEXTBASE:-0x62000000}
REBASE=(`/bin/rebase -i $DLL`)
BASE=${REBASE[2]}
SIZE=${REBASE[4]}
SKIP=$(((($SIZE>>16)+1)<<16))
echo "REBASE FIX: $DLL $BASE -> $NEXTBASE"
/bin/rebase -b $NEXTBASE $DLL
NEXTBASE="0x`printf %x $(($NEXTBASE+$SKIP))`"
echo $NEXTBASE > /etc/rebasenix.nextbase
done
}

View file

@ -0,0 +1,24 @@
fixupOutputHooks+=(_cygwinFixAutoImageBase)
_cygwinFixAutoImageBase() {
if [ "${dontRebase-}" == 1 ] || [ ! -d "$prefix" ]; then
return
fi
find "$prefix" -name "*.dll" -type f | while read DLL; do
if [ -f /etc/rebasenix.nextbase ]; then
NEXTBASE="$(</etc/rebasenix.nextbase)"
fi
NEXTBASE=${NEXTBASE:-0x200000001}
REBASE=(`/bin/rebase -i $DLL`)
BASE=${REBASE[2]}
SIZE=${REBASE[4]}
SKIP=$(((($SIZE>>16)+1)<<16))
echo "REBASE FIX: $DLL $BASE -> $NEXTBASE"
/bin/rebase -b $NEXTBASE $DLL
NEXTBASE="0x`printf %x $(($NEXTBASE+$SKIP))`"
echo $NEXTBASE > /etc/rebasenix.nextbase
done
}

View file

@ -0,0 +1,74 @@
postFixupHooks+=(_cygwinWrapExesToFindDlls)
_cygwinWrapExesToFindDlls() {
find $out -type l | while read LINK; do
TARGET="$(readlink "${LINK}")"
# fix all non .exe links that link explicitly to a .exe
if [[ ${TARGET} == *.exe ]] && [[ ${LINK} != *.exe ]]; then
mv "${LINK}" "${LINK}.exe"
LINK="${LINK}.exe"
fi
# generate complementary filenames
if [[ ${LINK} == *.exe ]]; then
_LINK="${LINK%.exe}"
_TARGET="${TARGET%.exe}"
else
_LINK="${LINK}.exe"
_TARGET="${TARGET}.exe"
fi
# check if sould create complementary link
DOLINK=1
if [[ ${_TARGET} == *.exe ]]; then
# the canonical target has to be a .exe
CTARGET="$(readlink -f "${LINK}")"
if [[ ${CTARGET} != *.exe ]]; then
CTARGET="${CTARGET}.exe"
fi
if [ ! -e "${CTARGET}" ]; then
unset DOLINK
fi
fi
if [ -e "${_LINK}" ]; then
# complementary link seems to exist
# but could be cygwin smoke and mirrors
INO=$(stat -c%i "${LINK}")
_INO=$(stat -c%i "${_LINK}")
if [ "${INO}" -ne "${_INO}" ]; then
unset DOLINK
fi
fi
# create complementary link
if [ -n "${DOLINK}" ]; then
ln -s "${_TARGET}" "${_LINK}.tmp"
mv "${_LINK}.tmp" "${_LINK}"
fi
done
find $out -type f -name "*.exe" | while read EXE; do
WRAPPER="${EXE%.exe}"
if [ -e "${WRAPPER}" ]; then
# check if really exists or cygwin smoke and mirrors
INO=$(stat -c%i "${EXE}")
_INO=$(stat -c%i "${WRAPPER}")
if [ "${INO}" -ne "${_INO}" ]; then
continue
fi
fi
mv "${EXE}" "${EXE}.tmp"
cat >"${WRAPPER}" <<EOF
#!/bin/sh
export PATH=$_PATH${_PATH:+:}\${PATH}
exec "\$0.exe" "\$@"
EOF
chmod +x "${WRAPPER}"
mv "${EXE}.tmp" "${EXE}"
done
}

View file

@ -0,0 +1,793 @@
{ lib
, localSystem
, crossSystem
, config
, overlays
, crossOverlays ? [ ]
, bootstrapLlvmVersion ? "11.1.0"
# Allow passing in bootstrap files directly so we can test the stdenv bootstrap process when changing the bootstrap tools
, bootstrapFiles ? if localSystem.isAarch64 then
let
fetch = { file, sha256, executable ? true }: import <nix/fetchurl.nix> {
url = "http://tarballs.nixos.org/stdenv-darwin/aarch64/20acd4c4f14040485f40e55c0a76c186aa8ca4f3/${file}";
inherit (localSystem) system;
inherit sha256 executable;
}; in
{
sh = fetch { file = "sh"; sha256 = "17m3xrlbl99j3vm7rzz3ghb47094dyddrbvs2a6jalczvmx7spnj"; };
bzip2 = fetch { file = "bzip2"; sha256 = "1khs8s5klf76plhlvlc1ma838r8pc1qigk9f5bdycwgbn0nx240q"; };
mkdir = fetch { file = "mkdir"; sha256 = "1m9nk90paazl93v43myv2ay68c1arz39pqr7lk5ddbgb177hgg8a"; };
cpio = fetch { file = "cpio"; sha256 = "17pxq61yjjvyd738fy9f392hc9cfzkl612sdr9rxr3v0dgvm8y09"; };
tarball = fetch { file = "bootstrap-tools.cpio.bz2"; sha256 = "1v2332k33akm6mrm4bj749rxnnmc2pkbgcslmd0bbkf76bz2ildy"; executable = false; };
}
else
let
fetch = { file, sha256, executable ? true }: import <nix/fetchurl.nix> {
url = "http://tarballs.nixos.org/stdenv-darwin/x86_64/c253216595572930316f2be737dc288a1da22558/${file}";
inherit (localSystem) system;
inherit sha256 executable;
}; in
{
sh = fetch { file = "sh"; sha256 = "sha256-igMAVEfumFv/LUNTGfNi2nSehgTNIP4Sg+f3L7u6SMA="; };
bzip2 = fetch { file = "bzip2"; sha256 = "sha256-K3rhkJZipudT1Jgh+l41Y/fNsMkrPtiAsNRDha/lpZI="; };
mkdir = fetch { file = "mkdir"; sha256 = "sha256-VddFELwLDJGNADKB1fWwWPBtIAlEUgJv2hXRmC4NEeM="; };
cpio = fetch { file = "cpio"; sha256 = "sha256-SWkwvLaFyV44kLKL2nx720SvcL4ej/p2V/bX3uqAGO0="; };
tarball = fetch { file = "bootstrap-tools.cpio.bz2"; sha256 = "sha256-kRC/bhCmlD4L7KAvJQgcukk7AinkMz4IwmG1rqlh5tA="; executable = false; };
}
}:
assert crossSystem == localSystem;
let
inherit (localSystem) system;
useAppleSDKLibs = localSystem.isAarch64;
haveKRB5 = localSystem.isx86_64;
# final toolchain is injected into llvmPackages_${finalLlvmVersion}
finalLlvmVersion = lib.versions.major bootstrapLlvmVersion;
finalLlvmPackages = "llvmPackages_${finalLlvmVersion}";
commonImpureHostDeps = [
"/bin/sh"
"/usr/lib/libSystem.B.dylib"
"/usr/lib/system/libunc.dylib" # This dependency is "hidden", so our scanning code doesn't pick it up
];
in
rec {
commonPreHook = ''
export NIX_ENFORCE_NO_NATIVE=''${NIX_ENFORCE_NO_NATIVE-1}
export NIX_ENFORCE_PURITY=''${NIX_ENFORCE_PURITY-1}
export NIX_IGNORE_LD_THROUGH_GCC=1
unset SDKROOT
stripAllFlags=" " # the Darwin "strip" command doesn't know "-s"
'';
bootstrapTools = derivation ({
inherit system;
name = "bootstrap-tools";
builder = bootstrapFiles.sh; # Not a filename! Attribute 'sh' on bootstrapFiles
args = if localSystem.isAarch64 then [ ./unpack-bootstrap-tools-aarch64.sh ] else [ ./unpack-bootstrap-tools.sh ];
inherit (bootstrapFiles) mkdir bzip2 cpio tarball;
__impureHostDeps = commonImpureHostDeps;
} // lib.optionalAttrs config.contentAddressedByDefault {
__contentAddressed = true;
outputHashAlgo = "sha256";
outputHashMode = "recursive";
});
stageFun = step: last: { shell ? "${bootstrapTools}/bin/bash"
, overrides ? (self: super: { })
, extraPreHook ? ""
, extraNativeBuildInputs
, extraBuildInputs
, libcxx
, allowedRequisites ? null
}:
let
name = "bootstrap-stage${toString step}";
buildPackages = lib.optionalAttrs (last ? stdenv) {
inherit (last) stdenv;
};
doSign = localSystem.isAarch64 && last != null;
doUpdateAutoTools = localSystem.isAarch64 && last != null;
inherit (last.pkgs) runCommandLocal;
mkExtraBuildCommands = cc: ''
rsrc="$out/resource-root"
mkdir "$rsrc"
ln -s "${cc.lib or cc}/lib/clang/${cc.version}/include" "$rsrc"
ln -s "${last.pkgs."${finalLlvmPackages}".compiler-rt.out}/lib" "$rsrc/lib"
echo "-resource-dir=$rsrc" >> $out/nix-support/cc-cflags
'';
mkCC = overrides: import ../../build-support/cc-wrapper (
let args = {
inherit lib shell;
inherit (last) stdenvNoCC;
nativeTools = false;
nativeLibc = false;
inherit buildPackages libcxx;
inherit (last.pkgs) coreutils gnugrep;
bintools = last.pkgs.darwin.binutils;
libc = last.pkgs.darwin.Libsystem;
isClang = true;
cc = last.pkgs."${finalLlvmPackages}".clang-unwrapped;
}; in args // (overrides args)
);
cc = if last == null then "/dev/null" else
mkCC ({ cc, ... }: {
extraPackages = [
last.pkgs."${finalLlvmPackages}".libcxxabi
last.pkgs."${finalLlvmPackages}".compiler-rt
];
extraBuildCommands = mkExtraBuildCommands cc;
});
ccNoLibcxx = if last == null then "/dev/null" else
mkCC ({ cc, ... }: {
libcxx = null;
extraPackages = [
last.pkgs."${finalLlvmPackages}".compiler-rt
];
extraBuildCommands = ''
echo "-rtlib=compiler-rt" >> $out/nix-support/cc-cflags
echo "-B${last.pkgs."${finalLlvmPackages}".compiler-rt}/lib" >> $out/nix-support/cc-cflags
echo "-nostdlib++" >> $out/nix-support/cc-cflags
'' + mkExtraBuildCommands cc;
});
thisStdenv = import ../generic {
name = "${name}-stdenv-darwin";
inherit config shell extraBuildInputs;
extraNativeBuildInputs = extraNativeBuildInputs ++ lib.optionals doUpdateAutoTools [
last.pkgs.updateAutotoolsGnuConfigScriptsHook
last.pkgs.gnu-config
];
allowedRequisites = if allowedRequisites == null then null else allowedRequisites ++ [
cc.expand-response-params
cc.bintools
] ++ lib.optionals doUpdateAutoTools [
last.pkgs.updateAutotoolsGnuConfigScriptsHook
last.pkgs.gnu-config
] ++ lib.optionals doSign [
last.pkgs.darwin.postLinkSignHook
last.pkgs.darwin.sigtool
last.pkgs.darwin.signingUtils
];
buildPlatform = localSystem;
hostPlatform = localSystem;
targetPlatform = localSystem;
inherit cc;
preHook = lib.optionalString (shell == "${bootstrapTools}/bin/bash") ''
# Don't patch #!/interpreter because it leads to retained
# dependencies on the bootstrapTools in the final stdenv.
dontPatchShebangs=1
'' + ''
${commonPreHook}
${extraPreHook}
'';
initialPath = [ bootstrapTools ];
fetchurlBoot = import ../../build-support/fetchurl {
inherit lib;
stdenvNoCC = stage0.stdenv;
curl = bootstrapTools;
};
# The stdenvs themselves don't use mkDerivation, so I need to specify this here
__stdenvImpureHostDeps = commonImpureHostDeps;
__extraImpureHostDeps = commonImpureHostDeps;
overrides = self: super: (overrides self super) // {
inherit ccNoLibcxx;
fetchurl = thisStdenv.fetchurlBoot;
};
};
in
{
inherit config overlays;
stdenv = thisStdenv;
};
stage0 = stageFun 0 null {
overrides = self: super: with stage0; {
coreutils = stdenv.mkDerivation {
name = "bootstrap-stage0-coreutils";
buildCommand = ''
mkdir -p $out
ln -s ${bootstrapTools}/bin $out/bin
'';
};
gnugrep = stdenv.mkDerivation {
name = "bootstrap-stage0-gnugrep";
buildCommand = ''
mkdir -p $out
ln -s ${bootstrapTools}/bin $out/bin
'';
};
pbzx = self.runCommandLocal "bootstrap-stage0-pbzx" { } ''
mkdir -p $out/bin
ln -s ${bootstrapTools}/bin/pbzx $out/bin
'';
cpio = self.runCommandLocal "bootstrap-stage0-cpio" { } ''
mkdir -p $out/bin
ln -s ${bootstrapFiles.cpio} $out/bin/cpio
'';
darwin = super.darwin.overrideScope (selfDarwin: superDarwin: {
darwin-stubs = superDarwin.darwin-stubs.override { inherit (self) stdenvNoCC fetchurl; };
dyld = {
name = "bootstrap-stage0-dyld";
buildCommand = ''
mkdir -p $out
ln -s ${bootstrapTools}/lib $out/lib
ln -s ${bootstrapTools}/include $out/include
'';
};
sigtool = self.runCommandLocal "bootstrap-stage0-sigtool" { } ''
mkdir -p $out/bin
ln -s ${bootstrapTools}/bin/sigtool $out/bin
ln -s ${bootstrapTools}/bin/codesign $out/bin
'';
print-reexports = self.runCommandLocal "bootstrap-stage0-print-reexports" { } ''
mkdir -p $out/bin
ln -s ${bootstrapTools}/bin/print-reexports $out/bin
'';
rewrite-tbd = self.runCommandLocal "bootstrap-stage0-rewrite-tbd" { } ''
mkdir -p $out/bin
ln -s ${bootstrapTools}/bin/rewrite-tbd $out/bin
'';
binutils-unwrapped = { name = "bootstrap-stage0-binutils"; outPath = bootstrapTools; };
cctools = {
name = "bootstrap-stage0-cctools";
outPath = bootstrapTools;
targetPrefix = "";
};
binutils = lib.makeOverridable (import ../../build-support/bintools-wrapper) {
shell = "${bootstrapTools}/bin/bash";
inherit lib;
inherit (self) stdenvNoCC;
nativeTools = false;
nativeLibc = false;
inherit (self) buildPackages coreutils gnugrep;
libc = selfDarwin.Libsystem;
bintools = selfDarwin.binutils-unwrapped;
inherit (selfDarwin) postLinkSignHook signingUtils;
};
} // lib.optionalAttrs (! useAppleSDKLibs) {
CF = stdenv.mkDerivation {
name = "bootstrap-stage0-CF";
buildCommand = ''
mkdir -p $out/Library/Frameworks
ln -s ${bootstrapTools}/Library/Frameworks/CoreFoundation.framework $out/Library/Frameworks
'';
};
Libsystem = stdenv.mkDerivation {
name = "bootstrap-stage0-Libsystem";
buildCommand = ''
mkdir -p $out
cp -r ${selfDarwin.darwin-stubs}/usr/lib $out/lib
chmod -R +w $out/lib
substituteInPlace $out/lib/libSystem.B.tbd --replace /usr/lib/system $out/lib/system
ln -s libSystem.B.tbd $out/lib/libSystem.tbd
for name in c dbm dl info m mx poll proc pthread rpcsvc util gcc_s.10.4 gcc_s.10.5; do
ln -s libSystem.tbd $out/lib/lib$name.tbd
done
ln -s ${bootstrapTools}/lib/*.o $out/lib
ln -s ${bootstrapTools}/lib/libresolv.9.dylib $out/lib
ln -s libresolv.9.dylib $out/lib/libresolv.dylib
ln -s ${bootstrapTools}/include-Libsystem $out/include
'';
};
});
"${finalLlvmPackages}" = {
clang-unwrapped = stdenv.mkDerivation {
name = "bootstrap-stage0-clang";
version = bootstrapLlvmVersion;
buildCommand = ''
mkdir -p $out/lib
ln -s ${bootstrapTools}/bin $out/bin
ln -s ${bootstrapTools}/lib/clang $out/lib/clang
ln -s ${bootstrapTools}/include $out/include
'';
};
libcxx = stdenv.mkDerivation {
name = "bootstrap-stage0-libcxx";
dontUnpack = true;
installPhase = ''
mkdir -p $out/lib $out/include
ln -s ${bootstrapTools}/lib/libc++.dylib $out/lib/libc++.dylib
ln -s ${bootstrapTools}/include/c++ $out/include/c++
'';
passthru = {
isLLVM = true;
};
};
libcxxabi = stdenv.mkDerivation {
name = "bootstrap-stage0-libcxxabi";
buildCommand = ''
mkdir -p $out/lib
ln -s ${bootstrapTools}/lib/libc++abi.dylib $out/lib/libc++abi.dylib
'';
};
compiler-rt = stdenv.mkDerivation {
name = "bootstrap-stage0-compiler-rt";
buildCommand = ''
mkdir -p $out/lib
ln -s ${bootstrapTools}/lib/libclang_rt* $out/lib
ln -s ${bootstrapTools}/lib/darwin $out/lib/darwin
'';
};
};
};
extraNativeBuildInputs = [ ];
extraBuildInputs = [ ];
libcxx = null;
};
stage1 = prevStage:
let
persistent = self: super: with prevStage; {
cmake = super.cmakeMinimal;
curl = super.curlMinimal;
inherit pbzx cpio;
python3 = super.python3Minimal;
ninja = super.ninja.override { buildDocs = false; };
"${finalLlvmPackages}" = super."${finalLlvmPackages}" // (
let
tools = super."${finalLlvmPackages}".tools.extend (_: _: {
inherit (pkgs."${finalLlvmPackages}") clang-unwrapped;
});
libraries = super."${finalLlvmPackages}".libraries.extend (_: _: {
inherit (pkgs."${finalLlvmPackages}") compiler-rt libcxx libcxxabi;
});
in
{ inherit tools libraries; } // tools // libraries
);
darwin = super.darwin.overrideScope (selfDarwin: _: {
inherit (darwin) rewrite-tbd binutils-unwrapped;
signingUtils = darwin.signingUtils.override {
inherit (selfDarwin) sigtool;
};
binutils = darwin.binutils.override {
coreutils = self.coreutils;
libc = selfDarwin.Libsystem;
inherit (selfDarwin) postLinkSignHook signingUtils;
};
});
};
in
with prevStage; stageFun 1 prevStage {
extraPreHook = "export NIX_CFLAGS_COMPILE+=\" -F${bootstrapTools}/Library/Frameworks\"";
extraNativeBuildInputs = [ ];
extraBuildInputs = [ pkgs.darwin.CF ];
libcxx = pkgs."${finalLlvmPackages}".libcxx;
allowedRequisites =
[ bootstrapTools ] ++
(with pkgs; [ coreutils gnugrep ]) ++
(with pkgs."${finalLlvmPackages}"; [ libcxx libcxxabi compiler-rt clang-unwrapped ]) ++
(with pkgs.darwin; [ Libsystem CF ] ++ lib.optional useAppleSDKLibs objc4);
overrides = persistent;
};
stage2 = prevStage:
let
persistent = self: super: with prevStage; {
inherit
zlib patchutils m4 scons flex perl bison unifdef unzip openssl python3
libxml2 gettext sharutils gmp libarchive ncurses pkg-config libedit groff
openssh sqlite sed serf openldap db cyrus-sasl expat apr-util subversion xz
findfreetype libssh curl cmake autoconf automake libtool ed cpio coreutils
libssh2 nghttp2 libkrb5 ninja brotli libiconv;
"${finalLlvmPackages}" = super."${finalLlvmPackages}" // (
let
tools = super."${finalLlvmPackages}".tools.extend (_: _: {
inherit (pkgs."${finalLlvmPackages}") clang-unwrapped;
});
libraries = super."${finalLlvmPackages}".libraries.extend (_: libSuper: {
inherit (pkgs."${finalLlvmPackages}") compiler-rt;
libcxx = libSuper.libcxx.override {
stdenv = overrideCC self.stdenv self.ccNoLibcxx;
};
libcxxabi = libSuper.libcxxabi.override ({
stdenv = overrideCC self.stdenv self.ccNoLibcxx;
} // lib.optionalAttrs (builtins.any (v: finalLlvmVersion == v) [ 7 11 12 13 ]) {
# TODO: the bootstrapping of llvm packages isn't consistent.
# `standalone` may be redundant if darwin behaves like useLLVM (or
# has useLLVM = true).
standalone = true;
});
});
in
{ inherit tools libraries; } // tools // libraries
);
darwin = super.darwin.overrideScope (_: _: {
inherit (darwin)
binutils dyld Libsystem xnu configd ICU libdispatch libclosure
launchd CF objc4 darwin-stubs sigtool postLinkSignHook signingUtils;
});
};
in
with prevStage; stageFun 2 prevStage {
extraPreHook = ''
export PATH_LOCALE=${pkgs.darwin.locale}/share/locale
'';
extraNativeBuildInputs = [ pkgs.xz ];
extraBuildInputs = [ pkgs.darwin.CF ];
libcxx = pkgs."${finalLlvmPackages}".libcxx;
allowedRequisites =
[ bootstrapTools ] ++
(with pkgs; [
xz.bin
xz.out
zlib
libxml2.out
curl.out
openssl.out
libssh2.out
nghttp2.lib
coreutils
gnugrep
pcre.out
gmp
libiconv
brotli.lib
] ++ lib.optional haveKRB5 libkrb5) ++
(with pkgs."${finalLlvmPackages}"; [
libcxx
libcxxabi
compiler-rt
clang-unwrapped
]) ++
(with pkgs.darwin; [ dyld Libsystem CF ICU locale ] ++ lib.optional useAppleSDKLibs objc4);
overrides = persistent;
};
stage3 = prevStage:
let
persistent = self: super: with prevStage; {
inherit
patchutils m4 scons flex perl bison unifdef unzip openssl python3
gettext sharutils libarchive pkg-config groff bash subversion
openssh sqlite sed serf openldap db cyrus-sasl expat apr-util
findfreetype libssh curl cmake autoconf automake libtool cpio
libssh2 nghttp2 libkrb5 ninja;
# Avoid pulling in a full python and its extra dependencies for the llvm/clang builds.
libxml2 = super.libxml2.override { pythonSupport = false; };
"${finalLlvmPackages}" = super."${finalLlvmPackages}" // (
let
libraries = super."${finalLlvmPackages}".libraries.extend (_: _: {
inherit (pkgs."${finalLlvmPackages}") libcxx libcxxabi;
});
in
{ inherit libraries; } // libraries
);
darwin = super.darwin.overrideScope (_: _: {
inherit (darwin)
dyld Libsystem xnu configd libdispatch libclosure launchd libiconv
locale darwin-stubs sigtool;
});
};
in
with prevStage; stageFun 3 prevStage {
shell = "${pkgs.bash}/bin/bash";
# We have a valid shell here (this one has no bootstrap-tools runtime deps) so stageFun
# enables patchShebangs above. Unfortunately, patchShebangs ignores our $SHELL setting
# and instead goes by $PATH, which happens to contain bootstrapTools. So it goes and
# patches our shebangs back to point at bootstrapTools. This makes sure bash comes first.
extraNativeBuildInputs = with pkgs; [ xz ];
extraBuildInputs = [ pkgs.darwin.CF pkgs.bash ];
libcxx = pkgs."${finalLlvmPackages}".libcxx;
extraPreHook = ''
export PATH=${pkgs.bash}/bin:$PATH
export PATH_LOCALE=${pkgs.darwin.locale}/share/locale
'';
allowedRequisites =
[ bootstrapTools ] ++
(with pkgs; [
xz.bin
xz.out
bash
zlib
libxml2.out
curl.out
openssl.out
libssh2.out
nghttp2.lib
coreutils
gnugrep
pcre.out
gmp
libiconv
brotli.lib
] ++ lib.optional haveKRB5 libkrb5) ++
(with pkgs."${finalLlvmPackages}"; [
libcxx
libcxx.dev
libcxxabi
libcxxabi.dev
compiler-rt
clang-unwrapped
]) ++
(with pkgs.darwin; [ dyld ICU Libsystem locale ] ++ lib.optional useAppleSDKLibs objc4);
overrides = persistent;
};
stage4 = prevStage:
let
persistent = self: super: with prevStage; {
inherit
gnumake gzip gnused bzip2 gawk ed xz patch bash python3
ncurses libffi zlib gmp pcre gnugrep cmake
coreutils findutils diffutils patchutils ninja libxml2;
# Hack to make sure we don't link ncurses in bootstrap tools. The proper
# solution is to avoid passing -L/nix-store/...-bootstrap-tools/lib,
# quite a sledgehammer just to get the C runtime.
gettext = super.gettext.overrideAttrs (drv: {
configureFlags = drv.configureFlags ++ [
"--disable-curses"
];
});
"${finalLlvmPackages}" = super."${finalLlvmPackages}" // (
let
tools = super."${finalLlvmPackages}".tools.extend (llvmSelf: _: {
clang-unwrapped-all-outputs = pkgs."${finalLlvmPackages}".clang-unwrapped-all-outputs.override { llvm = llvmSelf.llvm; };
libllvm = pkgs."${finalLlvmPackages}".libllvm.override { inherit libxml2; };
});
libraries = super."${finalLlvmPackages}".libraries.extend (llvmSelf: _: {
inherit (pkgs."${finalLlvmPackages}") libcxx libcxxabi compiler-rt;
});
in
{ inherit tools libraries; } // tools // libraries
);
darwin = super.darwin.overrideScope (_: superDarwin: {
inherit (darwin) dyld Libsystem libiconv locale darwin-stubs;
# See useAppleSDKLibs in darwin-packages.nix
CF = if useAppleSDKLibs then super.darwin.CF else
superDarwin.CF.override {
inherit libxml2;
python3 = prevStage.python3;
};
});
};
in
with prevStage; stageFun 4 prevStage {
shell = "${pkgs.bash}/bin/bash";
extraNativeBuildInputs = with pkgs; [ xz ];
extraBuildInputs = [ pkgs.darwin.CF pkgs.bash ];
libcxx = pkgs."${finalLlvmPackages}".libcxx;
extraPreHook = ''
export PATH_LOCALE=${pkgs.darwin.locale}/share/locale
'';
overrides = persistent;
};
stdenvDarwin = prevStage:
let
doSign = localSystem.isAarch64;
pkgs = prevStage;
persistent = self: super: with prevStage; {
inherit
gnumake gzip gnused bzip2 gawk ed xz patch bash
ncurses libffi zlib gmp pcre gnugrep
coreutils findutils diffutils patchutils pbzx;
darwin = super.darwin.overrideScope (_: _: {
inherit (darwin) dyld ICU Libsystem Csu libiconv rewrite-tbd;
} // lib.optionalAttrs (super.stdenv.targetPlatform == localSystem) {
inherit (darwin) binutils binutils-unwrapped cctools;
});
} // lib.optionalAttrs (super.stdenv.targetPlatform == localSystem) {
inherit llvm;
# Need to get rid of these when cross-compiling.
"${finalLlvmPackages}" = super."${finalLlvmPackages}" // (
let
tools = super."${finalLlvmPackages}".tools.extend (_: super: {
inherit (pkgs."${finalLlvmPackages}") llvm clang-unwrapped;
});
libraries = super."${finalLlvmPackages}".libraries.extend (_: _: {
inherit (pkgs."${finalLlvmPackages}") compiler-rt libcxx libcxxabi;
});
in
{ inherit tools libraries; } // tools // libraries
);
inherit binutils binutils-unwrapped;
};
in
import ../generic rec {
name = "stdenv-darwin";
inherit config;
inherit (pkgs.stdenv) fetchurlBoot;
buildPlatform = localSystem;
hostPlatform = localSystem;
targetPlatform = localSystem;
preHook = commonPreHook + ''
export NIX_COREFOUNDATION_RPATH=${pkgs.darwin.CF}/Library/Frameworks
export PATH_LOCALE=${pkgs.darwin.locale}/share/locale
'';
__stdenvImpureHostDeps = commonImpureHostDeps;
__extraImpureHostDeps = commonImpureHostDeps;
initialPath = import ../common-path.nix { inherit pkgs; };
shell = "${pkgs.bash}/bin/bash";
cc = pkgs."${finalLlvmPackages}".libcxxClang;
extraNativeBuildInputs = lib.optionals localSystem.isAarch64 [
pkgs.updateAutotoolsGnuConfigScriptsHook
];
extraBuildInputs = [ pkgs.darwin.CF ];
extraAttrs = {
libc = pkgs.darwin.Libsystem;
shellPackage = pkgs.bash;
inherit bootstrapTools;
};
allowedRequisites = (with pkgs; [
xz.out
xz.bin
gmp.out
gnumake
findutils
bzip2.out
bzip2.bin
zlib.out
zlib.dev
libffi.out
coreutils
ed
diffutils
gnutar
gzip
ncurses.out
ncurses.dev
ncurses.man
gnused
bash
gawk
gnugrep
patch
pcre.out
gettext
binutils.bintools
darwin.binutils
darwin.binutils.bintools
curl.out
zstd.out
libidn2.out
libunistring.out
openssl.out
libssh2.out
nghttp2.lib
brotli.lib
cc.expand-response-params
libxml2.out
] ++ lib.optional haveKRB5 libkrb5
++ lib.optionals localSystem.isAarch64 [
pkgs.updateAutotoolsGnuConfigScriptsHook
pkgs.gnu-config
])
++ (with pkgs."${finalLlvmPackages}"; [
libcxx
libcxx.dev
libcxxabi
libcxxabi.dev
llvm
llvm.lib
compiler-rt
compiler-rt.dev
clang-unwrapped
libclang.dev
libclang.lib
])
++ (with pkgs.darwin; [
dyld
Libsystem
CF
cctools
ICU
libiconv
locale
libtapi
] ++ lib.optional useAppleSDKLibs objc4
++ lib.optionals doSign [ postLinkSignHook sigtool signingUtils ]);
overrides = lib.composeExtensions persistent (self: super: {
darwin = super.darwin.overrideScope (_: superDarwin: {
inherit (prevStage.darwin) CF darwin-stubs;
xnu = superDarwin.xnu.override { inherit (prevStage) python3; };
});
} // lib.optionalAttrs (super.stdenv.targetPlatform == localSystem) {
clang = cc;
llvmPackages = super.llvmPackages // { clang = cc; };
inherit cc;
});
};
stagesDarwin = [
({}: stage0)
stage1
stage2
stage3
stage4
(prevStage: {
inherit config overlays;
stdenv = stdenvDarwin prevStage;
})
];
}

View file

@ -0,0 +1,41 @@
diff --git a/bsd/kern/makekdebugevents.py b/bsd/kern/makekdebugevents.py
index 73b2db4..d354ba0 100755
--- a/bsd/kern/makekdebugevents.py
+++ b/bsd/kern/makekdebugevents.py
@@ -5,7 +5,7 @@
# named kd_events[] or these mappings.
# Required to generate a header file used by DEVELOPMENT and DEBUG kernels.
#
-
+
import sys
import re
@@ -21,18 +21,18 @@ code_table = []
# scan file to generate internal table
with open(trace_code_file, 'rt') as codes:
for line in codes:
- m = id_name_pattern.match(line)
- if m:
+ m = id_name_pattern.match(line)
+ if m:
code_table += [(int(m.group(1),base=16), m.group(2))]
# emit typedef:
-print "typedef struct {"
-print " uint32_t id;"
-print " const char *name;"
-print "} kd_event_t;"
+print("typedef struct {")
+print(" uint32_t id;")
+print(" const char *name;")
+print("} kd_event_t;")
# emit structure declaration and sorted initialization:
-print "kd_event_t kd_events[] = {"
+print("kd_event_t kd_events[] = {")
for mapping in sorted(code_table, key=lambda x: x[0]):
- print " {0x%x, \"%s\"}," % mapping
-print "};"
+ print(" {0x%x, \"%s\"}," % mapping)
+print("};")

View file

@ -0,0 +1,375 @@
{ pkgspath ? ../../.., test-pkgspath ? pkgspath
, localSystem ? { system = builtins.currentSystem; }
, crossSystem ? null
, bootstrapFiles ? null
}:
let cross = if crossSystem != null
then { inherit crossSystem; }
else {};
custom-bootstrap = if bootstrapFiles != null
then { stdenvStages = args:
let args' = args // { bootstrapFiles = bootstrapFiles; };
in (import "${pkgspath}/pkgs/stdenv/darwin" args').stagesDarwin;
}
else {};
in with import pkgspath ({ inherit localSystem; } // cross // custom-bootstrap);
let
llvmPackages = llvmPackages_11;
storePrefixLen = builtins.stringLength builtins.storeDir;
in 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;
});
cctools_ = darwin.cctools;
# Avoid debugging larger changes for now.
bzip2_ = bzip2.override (args: { linkStatic = true; });
# Avoid messing with libkrb5 and libnghttp2.
curl_ = curlMinimal.override (args: { gssSupport = false; http2Support = false; });
build = stdenv.mkDerivation {
name = "stdenv-bootstrap-tools";
nativeBuildInputs = [ buildPackages.nukeReferences buildPackages.cpio ]
++ lib.optionals targetPlatform.isAarch64 [ buildPackages.darwin.sigtool ];
buildCommand = ''
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
# 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 -rL ${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 ${gnugrep.pcre.dev}/include/* $out/include
mv $out/include $out/include-Libsystem
''}
# Copy coreutils, bash, etc.
cp ${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 ${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 $out/bin
cp ${bzip2_.bin}/bin/bzip2 $out/bin
cp -d ${gnumake}/bin/* $out/bin
cp -d ${patch}/bin/* $out/bin
cp -d ${xz.bin}/bin/xz $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.pcre.out}/lib/libpcre*.dylib $out/lib
cp -d ${lib.getLib libiconv}/lib/lib*.dylib $out/lib
cp -d ${lib.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
# 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 ${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
mkdir $out/include
cp -rd ${llvmPackages.libcxx.dev}/include/c++ $out/include
${lib.optionalString targetPlatform.isAarch64 ''
# 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
# 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
# copy sigtool
cp -d ${pkgs.darwin.sigtool}/bin/sigtool $out/bin
cp -d ${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
# 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
done
cp -d ${lib.getLib darwin.libtapi}/lib/libtapi* $out/lib
${lib.optionalString targetPlatform.isx86_64 ''
cp -rd ${pkgs.darwin.CF}/Library $out
''}
chmod -R u+w $out
nuke-refs $out/bin/*
rpathify() {
local libs=$(${stdenv.cc.targetPrefix}otool -L "$1" | tail -n +2 | grep -o "$NIX_STORE.*-\S*") || true
local newlib
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 test -x $i -a ! -L $i; then
chmod +w $i
${stdenv.cc.targetPrefix}strip $i || true
fi
done
for i in $out/bin/* $out/lib/*.dylib $out/lib/darwin/*.dylib $out/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation; do
if test -x "$i" -a ! -L "$i"; then
echo "Adding rpath to $i"
rpathify $i
fi
done
for i in $out/bin/*; do
if test -x "$i" -a ! -L "$i"; then
echo "Adding @executable_path to rpath in $i"
${stdenv.cc.targetPrefix}install_name_tool -add_rpath '@executable_path/../lib' $i
fi
done
nuke-refs $out/lib/*
nuke-refs $out/lib/system/*
nuke-refs $out/lib/darwin/*
nuke-refs $out/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation
mkdir $out/.pack
mv $out/* $out/.pack
mv $out/.pack $out/pack
mkdir $out/on-server
cp ${stdenv.shell} $out/on-server/sh
cp ${cpio}/bin/cpio $out/on-server
cp ${coreutils_}/bin/mkdir $out/on-server
cp ${bzip2_.bin}/bin/bzip2 $out/on-server
chmod u+w $out/on-server/*
${stdenv.cc.targetPrefix}strip $out/on-server/*
nuke-refs $out/on-server/*
(cd $out/pack && (find | cpio -o -H newc)) | bzip2 > $out/on-server/bootstrap-tools.cpio.bz2
'';
allowedReferences = [];
meta = {
maintainers = [ lib.maintainers.copumpkin ];
};
};
dist = stdenv.mkDerivation {
name = "stdenv-bootstrap-tools";
buildCommand = ''
mkdir -p $out/nix-support
echo "file tarball ${build}/on-server/bootstrap-tools.cpio.bz2" >> $out/nix-support/hydra-build-products
echo "file sh ${build}/on-server/sh" >> $out/nix-support/hydra-build-products
echo "file cpio ${build}/on-server/cpio" >> $out/nix-support/hydra-build-products
echo "file mkdir ${build}/on-server/mkdir" >> $out/nix-support/hydra-build-products
echo "file bzip2 ${build}/on-server/bzip2" >> $out/nix-support/hydra-build-products
'';
};
bootstrapLlvmVersion = llvmPackages.llvm.version;
bootstrapFiles = {
sh = "${build}/on-server/sh";
bzip2 = "${build}/on-server/bzip2";
mkdir = "${build}/on-server/mkdir";
cpio = "${build}/on-server/cpio";
tarball = "${build}/on-server/bootstrap-tools.cpio.bz2";
};
unpack = stdenv.mkDerivation (bootstrapFiles // {
name = "unpack";
# This is by necessity a near-duplicate of unpack-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
# unpack-bootstrap-tools.sh for the next round of bootstrap tools.
# TODO: think through alternate designs, such as hosting this script as an output of the process.
buildCommand = ''
# Unpack the bootstrap tools tarball.
echo Unpacking the bootstrap tools...
$mkdir $out
$bzip2 -d < $tarball | (cd $out && $cpio -i)
# Set the ELF interpreter / RPATH in the bootstrap binaries.
echo Patching the tools...
export PATH=$out/bin
for i in $out/bin/*; do
if ! test -L $i; then
echo patching $i
install_name_tool -add_rpath $out/lib $i || true
fi
done
ln -s libresolv.9.dylib $out/lib/libresolv.dylib
for i in $out/lib/*.dylib $out/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation; do
if test ! -L "$i" -a "$i" != "$out/lib/libSystem*.dylib"; then
echo "Patching $i"
id=$(otool -D "$i" | tail -n 1)
install_name_tool -id "$(dirname $i)/$(basename $id)" $i
libs=$(otool -L "$i" | tail -n +2 | grep -v libSystem | cat)
if [ -n "$libs" ]; then
install_name_tool -add_rpath $out/lib $i
fi
fi
done
ln -s bash $out/bin/sh
ln -s bzip2 $out/bin/bunzip2
# 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
'';
allowedReferences = [ "out" ];
});
test = stdenv.mkDerivation {
name = "test";
realBuilder = "${unpack}/bin/bash";
buildCommand = ''
export PATH=${unpack}/bin
ls -l
mkdir $out
mkdir $out/bin
sed --version
find --version
diff --version
patch --version
make --version
awk --version
grep --version
clang --version
xz --version
# The grep will return a nonzero exit code if there is no match, and we want to assert that we have
# an SSL-capable curl
curl --version | grep SSL
${build}/on-server/sh -c 'echo Hello World'
# This approximates a bootstrap version of libSystem can that be
# assembled via fetchurl. Adapted from main libSystem expression.
mkdir libSystem-boot
cp -vr \
${darwin.darwin-stubs}/usr/lib/libSystem.B.tbd \
${darwin.darwin-stubs}/usr/lib/system \
libSystem-boot
substituteInPlace libSystem-boot/libSystem.B.tbd \
--replace "/usr/lib/system/" "$PWD/libSystem-boot/system/"
ln -s libSystem.B.tbd libSystem-boot/libSystem.tbd
# End of bootstrap libSystem
export flags="-idirafter ${unpack}/include-Libsystem --sysroot=${unpack} -L${unpack}/lib -L$PWD/libSystem-boot"
export CPP="clang -E $flags"
export CC="clang $flags -Wl,-rpath,${unpack}/lib -Wl,-v -Wl,-sdk_version,10.10"
export CXX="clang++ $flags --stdlib=libc++ -lc++abi -isystem${unpack}/include/c++/v1 -Wl,-rpath,${unpack}/lib -Wl,-v -Wl,-sdk_version,10.10"
echo '#include <stdio.h>' >> foo.c
echo '#include <float.h>' >> foo.c
echo '#include <limits.h>' >> foo.c
echo 'int main() { printf("Hello World\n"); return 0; }' >> foo.c
$CC -o $out/bin/foo foo.c
$out/bin/foo
echo '#include <CoreFoundation/CoreFoundation.h>' >> bar.c
echo 'int main() { CFShow(CFSTR("Hullo")); return 0; }' >> bar.c
$CC -F${unpack}/Library/Frameworks -framework CoreFoundation -o $out/bin/bar bar.c
$out/bin/bar
echo '#include <iostream>' >> bar.cc
echo 'int main() { std::cout << "Hello World\n"; }' >> bar.cc
$CXX -v -o $out/bin/bar bar.cc
$out/bin/bar
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
make
make install
$out/bin/hello
'';
};
# The ultimate test: bootstrap a whole stdenv from the tools specified above and get a package set out of it
test-pkgs = import test-pkgspath {
# if the bootstrap tools are for another platform, we should be testing
# that platform.
localSystem = if crossSystem != null then crossSystem else localSystem;
stdenvStages = args: let
args' = args // { inherit bootstrapLlvmVersion bootstrapFiles; };
in (import (test-pkgspath + "/pkgs/stdenv/darwin") args').stagesDarwin;
};
}

View file

@ -0,0 +1,12 @@
# Make /nix/store/...-libSystem “portable” for static built binaries.
# This just rewrites everything in $1/bin to use the
# /usr/lib/libSystem.B.dylib that is provided on every macOS system.
fixupOutputHooks+=('fixLibsystemRefs $prefix')
fixLibsystemRefs() {
if [ -d "$1/bin" ]; then
find "$1/bin" -exec \
install_name_tool -change @libsystem@ /usr/lib/libSystem.B.dylib {} \;
fi
}

View file

@ -0,0 +1,52 @@
set -euo pipefail
# Unpack the bootstrap tools tarball.
echo Unpacking the bootstrap tools...
$mkdir $out
$bzip2 -d < $tarball | (cd $out && $cpio -i)
export PATH=$out/bin
# Fix codesign wrapper paths
sed -i \
-e "1c\
#!$out/bin/bash" \
-e "s|[^( ]*\bsigtool\b|$out/bin/sigtool|g" \
$out/bin/codesign
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
ln -s bash $out/bin/sh
ln -s bzip2 $out/bin/bunzip2
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

View file

@ -0,0 +1,54 @@
set -e
# Unpack the bootstrap tools tarball.
echo Unpacking the bootstrap tools...
$mkdir $out
$bzip2 -d < $tarball | (cd $out && $cpio -i)
# Set the ELF interpreter / RPATH in the bootstrap binaries.
echo Patching the tools...
export PATH=$out/bin
for i in $out/bin/*; do
if ! test -L $i; then
echo patching $i
install_name_tool -add_rpath $out/lib $i || true
fi
done
for i in $out/lib/*.dylib $out/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation; do
if test ! -L "$i" -a "$i" != "$out/lib/libSystem*.dylib"; then
echo "Patching $i"
id=$(otool -D "$i" | tail -n 1)
install_name_tool -id "$(dirname $i)/$(basename $id)" $i
libs=$(otool -L "$i" | tail -n +2 | grep -v libSystem | cat)
if [ -n "$libs" ]; then
install_name_tool -add_rpath $out/lib $i
fi
fi
done
ln -s bash $out/bin/sh
ln -s bzip2 $out/bin/bunzip2
# 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

67
pkgs/stdenv/default.nix Normal file
View file

@ -0,0 +1,67 @@
# This file chooses a sane default stdenv given the system, platform, etc.
#
# Rather than returning a stdenv, this returns a list of functions---one per
# each bootstrapping stage. See `./booter.nix` for exactly what this list should
# contain.
{ # Args just for stdenvs' usage
lib
# Args to pass on to the pkgset builder, too
, localSystem, crossSystem, config, overlays, crossOverlays ? []
} @ args:
let
# The native (i.e., impure) build environment. This one uses the
# tools installed on the system outside of the Nix environment,
# i.e., the stuff in /bin, /usr/bin, etc. This environment should
# be used with care, since many Nix packages will not build properly
# with it (e.g., because they require GNU Make).
stagesNative = import ./native args;
# The Nix build environment.
stagesNix = import ./nix (args // { bootStages = stagesNative; });
stagesFreeBSD = import ./freebsd args;
# On Linux systems, the standard build environment consists of Nix-built
# instances glibc and the `standard' Unix tools, i.e., the Posix utilities,
# the GNU C compiler, and so on.
stagesLinux = import ./linux args;
inherit (import ./darwin args) stagesDarwin;
stagesCross = import ./cross args;
stagesCustom = import ./custom args;
# Select the appropriate stages for the platform `system'.
in
if crossSystem != localSystem || crossOverlays != [] then stagesCross
else if config ? replaceStdenv then stagesCustom
else { # switch
i686-linux = stagesLinux;
x86_64-linux = stagesLinux;
armv5tel-linux = stagesLinux;
armv6l-linux = stagesLinux;
armv6m-linux = stagesLinux;
armv7a-linux = stagesLinux;
armv7l-linux = stagesLinux;
armv7r-linux = stagesLinux;
armv7m-linux = stagesLinux;
armv8a-linux = stagesLinux;
armv8r-linux = stagesLinux;
armv8m-linux = stagesLinux;
aarch64-linux = stagesLinux;
mipsel-linux = stagesLinux;
mips64el-linux = stagesLinux;
powerpc-linux = /* stagesLinux */ stagesNative;
powerpc64-linux = stagesLinux;
powerpc64le-linux = stagesLinux;
riscv64-linux = stagesLinux;
x86_64-darwin = stagesDarwin;
aarch64-darwin = stagesDarwin;
x86_64-solaris = stagesNix;
i686-cygwin = stagesNative;
x86_64-cygwin = stagesNative;
x86_64-freebsd = stagesFreeBSD;
}.${localSystem.system} or stagesNative

View file

@ -0,0 +1,276 @@
{ lib
, localSystem, crossSystem, config, overlays, crossOverlays ? []
}:
assert crossSystem == localSystem;
let inherit (localSystem) system;
fetchURL = import <nix/fetchurl.nix>;
trivialBuilder = (import ./trivial-builder.nix);
make = trivialBuilder rec {
inherit (localSystem) system;
name = "make";
ver = "4.3";
url = "https://ftp.gnu.org/gnu/${name}/${name}-${ver}.tar.gz";
sha256 = "06cfqzpqsvdnsxbysl5p2fgdgxgl9y4p7scpnrfa8z2zgkjdspz0";
configureArgs = [ "--disable-nls"
"--without-libintl-prefix"
"--without-libiconv-prefix"
];
};
bash = trivialBuilder rec {
inherit (localSystem) system;
name = "bash";
ver = "4.4.18";
url = "https://ftp.gnu.org/gnu/${name}/${name}-${ver}.tar.gz";
sha256 = "08vz660768mnnax7n8d4d85jxafwdmsxsi7fh0hzvmafbvn9wkb0";
configureArgs = [ "--disable-nls"
"--without-libintl-prefix"
"--without-libiconv-prefix"
];
};
coreutils = trivialBuilder rec {
inherit (localSystem) system;
name = "coreutils";
ver = "8.31";
url = "https://ftp.gnu.org/gnu/${name}/${name}-${ver}.tar.xz";
sha256 = "1zg9m79x1i2nifj4kb0waf9x3i5h6ydkypkjnbsb9rnwis8rqypz";
configureArgs = [ "--disable-nls"
"--without-libintl-prefix"
"--without-libiconv-prefix"
"--without-gmp"
"--without-libpth-prefix"
];
};
findutils = trivialBuilder rec {
inherit (localSystem) system;
name = "findutils";
ver = "4.7.0";
url = "https://ftp.gnu.org/gnu/${name}/${name}-${ver}.tar.xz";
sha256 = "16kqz9yz98dasmj70jwf5py7jk558w96w0vgp3zf9xsqk3gzpzn5";
configureArgs = [ "--disable-nls"
"--without-libintl-prefix"
"--without-libiconv-prefix"
"--without-gmp"
"--without-libpth-prefix"
];
};
diffutils = trivialBuilder rec {
inherit (localSystem) system;
name = "diffutils";
ver = "3.7";
url = "https://ftp.gnu.org/gnu/${name}/${name}-${ver}.tar.xz";
sha256 = "09isrg0isjinv8c535nxsi1s86wfdfzml80dbw41dj9x3hiad9xk";
configureArgs = [ "--disable-nls"
"--without-libintl-prefix"
"--without-libiconv-prefix"
"--without-libsigsegv-prefix"
];
};
grep = trivialBuilder rec {
inherit (localSystem) system;
name = "grep";
ver = "3.4";
url = "https://ftp.gnu.org/gnu/${name}/${name}-${ver}.tar.xz";
sha256 = "1yy33kiwrxrwj2nxa4fg15bvmwyghqbs8qwkdvy5phm784f7brjq";
configureArgs = [ "--disable-nls"
"--without-libintl-prefix"
"--without-libiconv-prefix"
"--disable-perl-regexp"
"--without-libsegsegv-prefix"
];
};
patch = trivialBuilder rec {
inherit (localSystem) system;
name = "patch";
ver = "2.7.6";
url = "https://ftp.gnu.org/gnu/${name}/${name}-${ver}.tar.xz";
sha256 = "1zfqy4rdcy279vwn2z1kbv19dcfw25d2aqy9nzvdkq5bjzd0nqdc";
};
gawk = trivialBuilder rec {
inherit (localSystem) system;
name = "gawk";
ver = "5.0.1";
url = "https://ftp.gnu.org/gnu/${name}/${name}-${ver}.tar.xz";
sha256 = "15570p7g2x54asvr2fsc56sxzmm08fbk4mzpcs5n92fp9vq8cklf";
configureArgs = [ "--disable-nls"
"--disable-mpfr"
"--without-libintl-prefix"
"--without-libiconv-prefix"
"--without-libsegsegv-prefix"
];
};
cpio = trivialBuilder rec {
inherit (localSystem) system;
name = "cpio";
ver = "2.13";
url = "https://ftp.gnu.org/gnu/${name}/${name}-${ver}.tar.gz";
sha256 = "126vyg4a8wcdwh6npgvxy6gq433bzgz3ph37hmjpycc4r7cp0x78";
configureArgs = [ "--disable-nls"
"--without-libintl-prefix"
"--without-libiconv-prefix"
];
};
sed = trivialBuilder rec {
inherit (localSystem) system;
name = "sed";
ver = "4.8";
url = "https://ftp.gnu.org/gnu/${name}/${name}-${ver}.tar.xz";
sha256 = "0cznxw73fzv1n3nj2zsq6nf73rvsbxndp444xkpahdqvlzz0r6zp";
configureArgs = [ "--disable-nls"
"--without-libintl-prefix"
"--without-libiconv-prefix"
];
};
cacert = fetchURL rec {
url = "https://curl.haxx.se/ca/cacert-2020-01-01.pem";
sha256 = "07q808n307gzaga93abpf6an7c3rd35p18psdc1dd83lspgp1xxd";
executable = false;
};
curl = trivialBuilder rec {
inherit (localSystem) system;
name = "curl";
ver = "7.68.0";
url = "https://curl.haxx.se/download/${name}-${ver}.tar.xz";
sha256 = "0nh3j90w6b97wqcgxjfq55qhkz9s38955fbhwzv2fsi7483j895p";
configureArgs = [ "--disable-nls"
"--disable-ares"
"--disable-debug"
"--disable-ldap"
"--disable-ldaps"
"--disable-rtsp"
"--disable-dict"
"--disable-telnet"
"--disable-tftp"
"--disable-pop3"
"--disable-imap"
"--disable-smb"
"--disable-smtp"
"--disable-gopher"
"--disable-manual"
"--disable-verbose"
"--disable-sspi"
"--disable-tls-srp"
"--disable-unix-sockets"
"--without-brotli"
"--without-gnutls"
"--without-mbedtls"
"--without-wolfssl"
"--without-bearssl"
"--without-libidn2"
"--without-librtmp"
"--without-nghttp2"
"--with-ssl=/usr"
"--with-ca-bundle=${cacert}"
];
};
bashExe = "${bash}/bin/bash";
in
[
({}: {
__raw = true;
bootstrapTools = derivation ({
inherit system;
inherit make bash coreutils findutils
diffutils grep patch gawk cpio sed
curl;
name = "trivial-bootstrap-tools";
builder = bashExe;
args = [ ./trivial-bootstrap.sh ];
buildInputs = [ make ];
mkdir = "/bin/mkdir";
ln = "/bin/ln";
} // lib.optionalAttrs config.contentAddressedByDefault {
__contentAddressed = true;
outputHashAlgo = "sha256";
outputHashMode = "recursive";
});
})
({ bootstrapTools, ... }: rec {
__raw = true;
inherit bootstrapTools;
fetchurl = import ../../build-support/fetchurl {
inherit lib;
stdenvNoCC = stdenv;
curl = bootstrapTools;
};
stdenv = import ../generic {
name = "stdenv-freebsd-boot-1";
buildPlatform = localSystem;
hostPlatform = localSystem;
targetPlatform = localSystem;
inherit config;
initialPath = [ "/" "/usr" ];
shell = "${bootstrapTools}/bin/bash";
fetchurlBoot = null;
cc = null;
overrides = self: super: {
};
};
})
(prevStage: {
__raw = true;
inherit (prevStage) bootstrapTools;
stdenv = import ../generic {
name = "stdenv-freebsd-boot-0";
inherit config;
initialPath = [ prevStage.bootstrapTools ];
inherit (prevStage.stdenv)
buildPlatform hostPlatform targetPlatform
shell;
fetchurlBoot = prevStage.fetchurl;
cc = null;
};
})
(prevStage: {
inherit config overlays;
stdenv = import ../generic rec {
name = "stdenv-freebsd-boot-3";
inherit config;
inherit (prevStage.stdenv)
buildPlatform hostPlatform targetPlatform
initialPath shell fetchurlBoot;
cc = lib.makeOverridable (import ../../build-support/cc-wrapper) {
inherit lib;
nativeTools = true;
nativePrefix = "/usr";
nativeLibc = true;
stdenvNoCC = prevStage.stdenv;
buildPackages = {
inherit (prevStage) stdenv;
};
cc = {
name = "clang-9.9.9";
cc = "/usr";
outPath = prevStage.bootstrapTools;
};
isClang = true;
bintools = import ../../build-support/bintools-wrapper {
inherit lib;
stdenvNoCC = prevStage.stdenv;
nativeTools = true;
nativeLibc = true;
propagateDoc = false;
nativePrefix = "/usr";
bintools = { name = "${name}-binutils";
outPath = prevStage.bootstrapTools; };
};
};
preHook = "export NIX_NO_SELF_RPATH=1";
};
})
]

View file

@ -0,0 +1,118 @@
set -e
set -o nounset
set -o pipefail
echo Building the trivial bootstrap environment...
#echo
#echo Needed FreeBSD packages:
#echo findutils gcpio gawk gnugrep coreutils bash gsed gtar gmake xar binutils gpatch lbzip2 diffutils
$mkdir -p $out/bin
ln () {
if [ ! -z "${2:-}" ]; then
if [ -f "$out/bin/$2" ]; then
echo "$2 exists"
exit 1
fi
fi
if test ! -f "$1"; then
echo Target "$2" does not exist
exit 1
fi
# TODO: check that destination directory exists
if [ ! -z "${2:-}" ]; then
$ln -s "$1" "$out/bin/$2"
else
$ln -s "$1" "$out/bin/"
fi
}
ln $bash/bin/bash
ln $make/bin/make
ln /bin/sh
for i in b2sum base32 base64 basename basenc cat chcon chgrp chmod \
chown chroot cksum comm cp csplit cut date dd df dir dircolors \
dirname du echo env expand expr factor false fmt fold install \
groups head hostid id join kill link ln logname ls md5sum mkdir \
mkfifo mknod mktemp mv nice nl nohup nproc numfmt od paste pathchk \
pinky pr printenv printf ptx pwd readlink realpath rm rmdir runcon \
seq sha1sum sha224sum sha256sum sha384sum sha512sum shred shuf \
sleep sort split stat stdbuf stty sum sync tac tee test timeout \
touch tr true truncate tsort tty uname unexpand uniq unlink uptime \
users vdir wc who whoami yes
do
ln "$coreutils/bin/$i" "$i"
done
for i in find xargs; do
ln "$findutils/bin/$i" "$i"
done
for i in diff diff3 sdiff; do
ln "$diffutils/bin/$i" "$i"
done
for i in grep egrep fgrep; do
ln "$grep/bin/$i" "$i"
done
ln /usr/bin/locale
ln /usr/bin/more
ln /usr/bin/hexdump # for bitcoin
ln /usr/bin/bzip2
ln /usr/bin/bunzip2
ln /usr/bin/bzip2recover
ln /usr/bin/xz
ln /usr/bin/unxz
ln /usr/bin/lzma
ln /usr/bin/unlzma
ln /bin/ps
ln /bin/hostname
ln /usr/bin/cmp
ln $sed/bin/sed
ln /usr/bin/tar tar
ln $gawk/bin/gawk
ln $gawk/bin/gawk awk
ln $cpio/bin/cpio
ln $curl/bin/curl curl
ln /usr/bin/gzip
ln /usr/bin/gunzip
ln /usr/bin/tail tail # note that we are not using gtail!!!
ln /usr/bin/less less
ln $patch/bin/patch patch
ln /usr/bin/which which
## binutils
# pkg info -l binutils | grep usr/local/bin
ln /usr/bin/addr2line
ln /usr/bin/ar
ln /usr/bin/as
ln /usr/bin/c++filt
#ln /usr/bin/dwp
#ln /usr/bin/elfedit
ln /usr/bin/gprof
ln /usr/bin/ld
#ln /usr/bin/ld.bfd
#ln /usr/bin/ld.gold
ln /usr/bin/nm
ln /usr/bin/objcopy
ln /usr/bin/objdump
ln /usr/bin/ranlib
ln /usr/bin/readelf
ln /usr/bin/size
ln /usr/bin/strings
ln /usr/bin/strip
ln /usr/bin/cc
ln /usr/bin/cpp
ln /usr/bin/c++
#pkg info -l llvm37 | grep usr/local/bin

View file

@ -0,0 +1,13 @@
{ system, name, ver, url, sha256, configureArgs ? [], executable ? false } :
let fetchURL = import <nix/fetchurl.nix>;
in derivation {
inherit system configureArgs;
name = "trivial-bootstrap-${name}-${ver}";
dname = "${name}-${ver}";
src = fetchURL {
inherit url sha256 executable;
};
builder = ./trivial-builder.sh;
}

View file

@ -0,0 +1,10 @@
#!/bin/sh
export PATH=/bin:/sbin:/usr/bin:/usr/sbin
tar -zxvf $src
cd $dname
mkdir -p $out/bin
./configure --prefix=$out $configureArgs
make
make install

View file

@ -0,0 +1,23 @@
export PATH=
for i in $initialPath; do
if [ "$i" = / ]; then i=; fi
PATH=$PATH${PATH:+:}$i/bin
done
mkdir $out
{
echo "export SHELL=$shell"
echo "initialPath=\"$initialPath\""
echo "defaultNativeBuildInputs=\"$defaultNativeBuildInputs\""
echo "defaultBuildInputs=\"$defaultBuildInputs\""
echo "$preHook"
cat "$setup"
} > "$out/setup"
# Allow the user to install stdenv using nix-env and get the packages
# in stdenv.
mkdir $out/nix-support
if [ "$propagatedUserEnvPkgs" ]; then
printf '%s ' $propagatedUserEnvPkgs > $out/nix-support/propagated-user-env-packages
fi

View file

@ -0,0 +1,365 @@
# Checks derivation meta and attrs for problems (like brokenness,
# licenses, etc).
{ lib, config, hostPlatform }:
let
# If we're in hydra, we can dispense with the more verbose error
# messages and make problems easier to spot.
inHydra = config.inHydra or false;
# Allow the user to opt-into additional warnings, e.g.
# import <nixpkgs> { config = { showDerivationWarnings = [ "maintainerless" ]; }; }
showWarnings = config.showDerivationWarnings;
getName = attrs: attrs.name or ("${attrs.pname or "«name-missing»"}-${attrs.version or "«version-missing»"}");
# See discussion at https://github.com/NixOS/nixpkgs/pull/25304#issuecomment-298385426
# for why this defaults to false, but I (@copumpkin) want to default it to true soon.
shouldCheckMeta = config.checkMeta or false;
allowUnfree = config.allowUnfree
|| builtins.getEnv "NIXPKGS_ALLOW_UNFREE" == "1";
allowNonSource = config.allowNonSource or true
|| builtins.getEnv "NIXPKGS_ALLOW_NONSOURCE" == "1";
allowlist = config.allowlistedLicenses or config.whitelistedLicenses or [];
blocklist = config.blocklistedLicenses or config.blacklistedLicenses or [];
areLicenseListsValid =
if lib.mutuallyExclusive allowlist blocklist then
true
else
throw "allowlistedLicenses and blocklistedLicenses are not mutually exclusive.";
hasLicense = attrs:
attrs ? meta.license;
hasAllowlistedLicense = assert areLicenseListsValid; attrs:
hasLicense attrs && lib.lists.any (l: builtins.elem l allowlist) (lib.lists.toList attrs.meta.license);
hasBlocklistedLicense = assert areLicenseListsValid; attrs:
hasLicense attrs && lib.lists.any (l: builtins.elem l blocklist) (lib.lists.toList attrs.meta.license);
allowBroken = config.allowBroken
|| builtins.getEnv "NIXPKGS_ALLOW_BROKEN" == "1";
allowUnsupportedSystem = config.allowUnsupportedSystem
|| builtins.getEnv "NIXPKGS_ALLOW_UNSUPPORTED_SYSTEM" == "1";
isUnfree = licenses: lib.lists.any (l: !l.free or true) licenses;
hasUnfreeLicense = attrs:
hasLicense attrs &&
isUnfree (lib.lists.toList attrs.meta.license);
hasNoMaintainers = attrs:
attrs ? meta.maintainers && (lib.length attrs.meta.maintainers) == 0;
isMarkedBroken = attrs: attrs.meta.broken or false;
hasUnsupportedPlatform = attrs:
(!lib.lists.elem hostPlatform.system (attrs.meta.platforms or lib.platforms.all) ||
lib.lists.elem hostPlatform.system (attrs.meta.badPlatforms or []));
isMarkedInsecure = attrs: (attrs.meta.knownVulnerabilities or []) != [];
# Alow granular checks to allow only some unfree packages
# Example:
# {pkgs, ...}:
# {
# allowUnfree = false;
# allowUnfreePredicate = (x: pkgs.lib.hasPrefix "vscode" x.name);
# }
allowUnfreePredicate = config.allowUnfreePredicate or (x: false);
# Check whether unfree packages are allowed and if not, whether the
# package has an unfree license and is not explicitely allowed by the
# `allowUnfreePredicate` function.
hasDeniedUnfreeLicense = attrs:
hasUnfreeLicense attrs &&
!allowUnfree &&
!allowUnfreePredicate attrs;
allowInsecureDefaultPredicate = x: builtins.elem (getName x) (config.permittedInsecurePackages or []);
allowInsecurePredicate = x: (config.allowInsecurePredicate or allowInsecureDefaultPredicate) x;
hasAllowedInsecure = attrs:
!(isMarkedInsecure attrs) ||
allowInsecurePredicate attrs ||
builtins.getEnv "NIXPKGS_ALLOW_INSECURE" == "1";
isNonSource = sourceTypes: lib.lists.any (t: !t.isSource) sourceTypes;
hasNonSourceProvenance = attrs:
(attrs ? meta.sourceProvenance) &&
isNonSource (lib.lists.toList attrs.meta.sourceProvenance);
# Allow granular checks to allow only some non-source-built packages
# Example:
# { pkgs, ... }:
# {
# allowNonSource = false;
# allowNonSourcePredicate = with pkgs.lib.lists; pkg: !(any (p: !p.isSource && p != lib.sourceTypes.binaryFirmware) (toList pkg.meta.sourceProvenance));
# }
allowNonSourcePredicate = config.allowNonSourcePredicate or (x: false);
# Check whether non-source packages are allowed and if not, whether the
# package has non-source provenance and is not explicitly allowed by the
# `allowNonSourcePredicate` function.
hasDeniedNonSourceProvenance = attrs:
hasNonSourceProvenance attrs &&
!allowNonSource &&
!allowNonSourcePredicate attrs;
showLicenseOrSourceType = value: toString (map (v: v.shortName or "unknown") (lib.lists.toList value));
showLicense = showLicenseOrSourceType;
showSourceType = showLicenseOrSourceType;
pos_str = meta: meta.position or "«unknown-file»";
remediation = {
unfree = remediate_allowlist "Unfree" (remediate_predicate "allowUnfreePredicate");
non-source = remediate_allowlist "NonSource" (remediate_predicate "allowNonSourcePredicate");
broken = remediate_allowlist "Broken" (x: "");
unsupported = remediate_allowlist "UnsupportedSystem" (x: "");
blocklisted = x: "";
insecure = remediate_insecure;
broken-outputs = remediateOutputsToInstall;
unknown-meta = x: "";
maintainerless = x: "";
};
remediation_env_var = allow_attr: {
Unfree = "NIXPKGS_ALLOW_UNFREE";
Broken = "NIXPKGS_ALLOW_BROKEN";
UnsupportedSystem = "NIXPKGS_ALLOW_UNSUPPORTED_SYSTEM";
NonSource = "NIXPKGS_ALLOW_NONSOURCE";
}.${allow_attr};
remediation_phrase = allow_attr: {
Unfree = "unfree packages";
Broken = "broken packages";
UnsupportedSystem = "packages that are unsupported for this system";
NonSource = "packages not built from source";
}.${allow_attr};
remediate_predicate = predicateConfigAttr: attrs:
''
Alternatively you can configure a predicate to allow specific packages:
{ nixpkgs.config.${predicateConfigAttr} = pkg: builtins.elem (lib.getName pkg) [
"${lib.getName attrs}"
];
}
'';
# flakeNote will be printed in the remediation messages below.
flakeNote = "
Note: For `nix shell`, `nix build`, `nix develop` or any other Nix 2.4+
(Flake) command, `--impure` must be passed in order to read this
environment variable.
";
remediate_allowlist = allow_attr: rebuild_amendment: attrs:
''
a) To temporarily allow ${remediation_phrase allow_attr}, you can use an environment variable
for a single invocation of the nix tools.
$ export ${remediation_env_var allow_attr}=1
${flakeNote}
b) For `nixos-rebuild` you can set
{ nixpkgs.config.allow${allow_attr} = true; }
in configuration.nix to override this.
${rebuild_amendment attrs}
c) For `nix-env`, `nix-build`, `nix-shell` or any other Nix command you can add
{ allow${allow_attr} = true; }
to ~/.config/nixpkgs/config.nix.
'';
remediate_insecure = attrs:
''
Known issues:
'' + (lib.concatStrings (map (issue: " - ${issue}\n") attrs.meta.knownVulnerabilities)) + ''
You can install it anyway by allowing this package, using the
following methods:
a) To temporarily allow all insecure packages, you can use an environment
variable for a single invocation of the nix tools:
$ export NIXPKGS_ALLOW_INSECURE=1
${flakeNote}
b) for `nixos-rebuild` you can add ${getName attrs} to
`nixpkgs.config.permittedInsecurePackages` in the configuration.nix,
like so:
{
nixpkgs.config.permittedInsecurePackages = [
"${getName attrs}"
];
}
c) For `nix-env`, `nix-build`, `nix-shell` or any other Nix command you can add
${getName attrs} to `permittedInsecurePackages` in
~/.config/nixpkgs/config.nix, like so:
{
permittedInsecurePackages = [
"${getName attrs}"
];
}
'';
remediateOutputsToInstall = attrs: let
expectedOutputs = attrs.meta.outputsToInstall or [];
actualOutputs = attrs.outputs or [ "out" ];
missingOutputs = builtins.filter (output: ! builtins.elem output actualOutputs) expectedOutputs;
in ''
The package ${getName attrs} has set meta.outputsToInstall to: ${builtins.concatStringsSep ", " expectedOutputs}
however ${getName attrs} only has the outputs: ${builtins.concatStringsSep ", " actualOutputs}
and is missing the following ouputs:
${lib.concatStrings (builtins.map (output: " - ${output}\n") missingOutputs)}
'';
handleEvalIssue = { meta, attrs }: { reason , errormsg ? "" }:
let
msg = if inHydra
then "Failed to evaluate ${getName attrs}: «${reason}»: ${errormsg}"
else ''
Package ${getName attrs} in ${pos_str meta} ${errormsg}, refusing to evaluate.
'' + (builtins.getAttr reason remediation) attrs;
handler = if config ? handleEvalIssue
then config.handleEvalIssue reason
else throw;
in handler msg;
handleEvalWarning = { meta, attrs }: { reason , errormsg ? "" }:
let
remediationMsg = (builtins.getAttr reason remediation) attrs;
msg = if inHydra then "Warning while evaluating ${getName attrs}: «${reason}»: ${errormsg}"
else "Package ${getName attrs} in ${pos_str meta} ${errormsg}, continuing anyway."
+ (if remediationMsg != "" then "\n${remediationMsg}" else "");
isEnabled = lib.findFirst (x: x == reason) null showWarnings;
in if isEnabled != null then builtins.trace msg true else true;
metaTypes = with lib.types; rec {
# These keys are documented
description = str;
mainProgram = str;
longDescription = str;
branch = str;
homepage = either (listOf str) str;
downloadPage = str;
changelog = either (listOf str) str;
license = either (listOf lib.types.attrs) (either lib.types.attrs str);
sourceProvenance = either (listOf lib.types.attrs) lib.types.attrs;
maintainers = listOf (attrsOf str);
priority = int;
platforms = listOf str;
hydraPlatforms = listOf str;
broken = bool;
unfree = bool;
unsupported = bool;
insecure = bool;
# TODO: refactor once something like Profpatsch's types-simple will land
# This is currently dead code due to https://github.com/NixOS/nix/issues/2532
tests = attrsOf (mkOptionType {
name = "test";
check = x: x == {} || ( # Accept {} for tests that are unsupported
isDerivation x &&
x ? meta.timeout
);
merge = lib.options.mergeOneOption;
});
timeout = int;
# Weirder stuff that doesn't appear in the documentation?
maxSilent = int;
knownVulnerabilities = listOf str;
name = str;
version = str;
tag = str;
executables = listOf str;
outputsToInstall = listOf str;
position = str;
available = bool;
isBuildPythonPackage = platforms;
schedulingPriority = int;
isFcitxEngine = bool;
isIbusEngine = bool;
isGutenprint = bool;
badPlatforms = platforms;
};
checkMetaAttr = k: v:
if metaTypes?${k} then
if metaTypes.${k}.check v then null else "key '${k}' has a value ${toString v} of an invalid type ${builtins.typeOf v}; expected ${metaTypes.${k}.description}"
else "key '${k}' is unrecognized; expected one of: \n\t [${lib.concatMapStringsSep ", " (x: "'${x}'") (lib.attrNames metaTypes)}]";
checkMeta = meta: if shouldCheckMeta then lib.remove null (lib.mapAttrsToList checkMetaAttr meta) else [];
checkOutputsToInstall = attrs: let
expectedOutputs = attrs.meta.outputsToInstall or [];
actualOutputs = attrs.outputs or [ "out" ];
missingOutputs = builtins.filter (output: ! builtins.elem output actualOutputs) expectedOutputs;
in if shouldCheckMeta
then builtins.length missingOutputs > 0
else false;
# Check if a derivation is valid, that is whether it passes checks for
# e.g brokenness or license.
#
# Return { valid: Bool } and additionally
# { reason: String; errormsg: String } if it is not valid, where
# reason is one of "unfree", "blocklisted", "broken", "insecure", ...
# Along with a boolean flag for each reason
checkValidity = attrs:
{
unfree = hasUnfreeLicense attrs;
nonSource = hasNonSourceProvenance attrs;
broken = isMarkedBroken attrs;
unsupported = hasUnsupportedPlatform attrs;
insecure = isMarkedInsecure attrs;
}
// (if hasDeniedUnfreeLicense attrs && !(hasAllowlistedLicense attrs) then
{ valid = "no"; reason = "unfree"; errormsg = "has an unfree license (${showLicense attrs.meta.license})"; }
else if hasBlocklistedLicense attrs then
{ valid = "no"; reason = "blocklisted"; errormsg = "has a blocklisted license (${showLicense attrs.meta.license})"; }
else if hasDeniedNonSourceProvenance attrs then
{ valid = "no"; reason = "non-source"; errormsg = "contains elements not built from source (${showSourceType attrs.meta.sourceProvenance})"; }
else if !allowBroken && attrs.meta.broken or false then
{ valid = "no"; reason = "broken"; errormsg = "is marked as broken"; }
else if !allowUnsupportedSystem && hasUnsupportedPlatform attrs then
{ valid = "no"; reason = "unsupported"; errormsg = "is not supported on ${hostPlatform.system}"; }
else if !(hasAllowedInsecure attrs) then
{ valid = "no"; reason = "insecure"; errormsg = "is marked as insecure"; }
else if checkOutputsToInstall attrs then
{ valid = "no"; reason = "broken-outputs"; errormsg = "has invalid meta.outputsToInstall"; }
else let res = checkMeta (attrs.meta or {}); in if res != [] then
{ valid = "no"; reason = "unknown-meta"; errormsg = "has an invalid meta attrset:${lib.concatMapStrings (x: "\n\t - " + x) res}"; }
# --- warnings ---
# Please also update the type in /pkgs/top-level/config.nix alongside this.
else if hasNoMaintainers attrs then
{ valid = "warn"; reason = "maintainerless"; errormsg = "has no maintainers"; }
# -----
else { valid = "yes"; });
assertValidity = { meta, attrs }: let
validity = checkValidity attrs;
in validity // {
# Throw an error if trying to evaluate a non-valid derivation
# or, alternatively, just output a warning message.
handled =
{
no = handleEvalIssue { inherit meta attrs; } { inherit (validity) reason errormsg; };
warn = handleEvalWarning { inherit meta attrs; } { inherit (validity) reason errormsg; };
yes = true;
}.${validity.valid};
};
in assertValidity

View file

@ -0,0 +1,2 @@
source $stdenv/setup
genericBuild

View file

@ -0,0 +1,183 @@
let lib = import ../../../lib; stdenv-overridable = lib.makeOverridable (
argsStdenv@{ name ? "stdenv", preHook ? "", initialPath
, # If we don't have a C compiler, we might either have `cc = null` or `cc =
# throw ...`, but if we do have a C compiler we should definiely have `cc !=
# null`.
#
# TODO(@Ericson2314): Add assert without creating infinite recursion
hasCC ? cc != null, cc
, shell
, allowedRequisites ? null, extraAttrs ? {}, overrides ? (self: super: {}), config
, # The `fetchurl' to use for downloading curl and its dependencies
# (see all-packages.nix).
fetchurlBoot
, setupScript ? ./setup.sh
, extraNativeBuildInputs ? []
, extraBuildInputs ? []
, __stdenvImpureHostDeps ? []
, __extraImpureHostDeps ? []
, stdenvSandboxProfile ? ""
, extraSandboxProfile ? ""
## Platform parameters
##
## The "build" "host" "target" terminology below comes from GNU Autotools. See
## its documentation for more information on what those words mean. Note that
## each should always be defined, even when not cross compiling.
##
## For purposes of bootstrapping, think of each stage as a "sliding window"
## over a list of platforms. Specifically, the host platform of the previous
## stage becomes the build platform of the current one, and likewise the
## target platform of the previous stage becomes the host platform of the
## current one.
##
, # The platform on which packages are built. Consists of `system`, a
# string (e.g.,`i686-linux') identifying the most import attributes of the
# build platform, and `platform` a set of other details.
buildPlatform
, # The platform on which packages run.
hostPlatform
, # The platform which build tools (especially compilers) build for in this stage,
targetPlatform
, # 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; }
}:
let
defaultNativeBuildInputs = extraNativeBuildInputs ++
[ ../../build-support/setup-hooks/move-docs.sh
../../build-support/setup-hooks/make-symlinks-relative.sh
../../build-support/setup-hooks/compress-man-pages.sh
../../build-support/setup-hooks/strip.sh
../../build-support/setup-hooks/patch-shebangs.sh
../../build-support/setup-hooks/prune-libtool-files.sh
]
# FIXME this on Darwin; see
# https://github.com/NixOS/nixpkgs/commit/94d164dd7#commitcomment-22030369
++ lib.optionals hostPlatform.isLinux [
../../build-support/setup-hooks/audit-tmpdir.sh
../../build-support/setup-hooks/move-systemd-user-units.sh
]
++ [
../../build-support/setup-hooks/multiple-outputs.sh
../../build-support/setup-hooks/move-sbin.sh
../../build-support/setup-hooks/move-lib64.sh
../../build-support/setup-hooks/set-source-date-epoch-to-latest.sh
../../build-support/setup-hooks/reproducible-builds.sh
# TODO use lib.optional instead
(if hasCC then cc else null)
];
defaultBuildInputs = extraBuildInputs;
stdenv = (stdenv-overridable argsStdenv);
# The stdenv that we are producing.
in
derivation (
lib.optionalAttrs (allowedRequisites != null) {
allowedRequisites = allowedRequisites
++ defaultNativeBuildInputs ++ defaultBuildInputs;
}
// lib.optionalAttrs config.contentAddressedByDefault {
__contentAddressed = true;
outputHashAlgo = "sha256";
outputHashMode = "recursive";
}
// {
inherit name;
# Nix itself uses the `system` field of a derivation to decide where to
# build it. This is a bit confusing for cross compilation.
inherit (buildPlatform) system;
builder = shell;
args = ["-e" ./builder.sh];
setup = setupScript;
# We pretty much never need rpaths on Darwin, since all library path references
# are absolute unless we go out of our way to make them relative (like with CF)
# TODO: This really wants to be in stdenv/darwin but we don't have hostPlatform
# there (yet?) so it goes here until then.
preHook = preHook + lib.optionalString buildPlatform.isDarwin ''
export NIX_DONT_SET_RPATH_FOR_BUILD=1
'' + lib.optionalString (hostPlatform.isDarwin || (hostPlatform.parsed.kernel.execFormat != lib.systems.parse.execFormats.elf && hostPlatform.parsed.kernel.execFormat != lib.systems.parse.execFormats.macho)) ''
export NIX_DONT_SET_RPATH=1
export NIX_NO_SELF_RPATH=1
'' + lib.optionalString (hostPlatform.isDarwin && hostPlatform.isMacOS) ''
export MACOSX_DEPLOYMENT_TARGET=${hostPlatform.darwinMinVersion}
''
# TODO this should be uncommented, but it causes stupid mass rebuilds. I
# think the best solution would just be to fixup linux RPATHs so we don't
# need to set `-rpath` anywhere.
# + lib.optionalString targetPlatform.isDarwin ''
# export NIX_DONT_SET_RPATH_FOR_TARGET=1
# ''
;
inherit initialPath shell
defaultNativeBuildInputs defaultBuildInputs;
}
// lib.optionalAttrs buildPlatform.isDarwin {
__sandboxProfile = stdenvSandboxProfile;
__impureHostDeps = __stdenvImpureHostDeps;
})
// {
meta = {
description = "The default build environment for Unix packages in Nixpkgs";
platforms = lib.platforms.all;
};
inherit buildPlatform hostPlatform targetPlatform;
inherit extraNativeBuildInputs extraBuildInputs
__extraImpureHostDeps extraSandboxProfile;
# Utility flags to test the type of platform.
inherit (hostPlatform)
isDarwin isLinux isSunOS isCygwin isBSD isFreeBSD isOpenBSD
isi686 isx86_32 isx86_64
is32bit is64bit
isAarch32 isAarch64 isMips isBigEndian;
# Override `system` so that packages can get the system of the host
# platform through `stdenv.system`. `system` is originally set to the
# build platform within the derivation above so that Nix directs the build
# to correct type of machine.
inherit (hostPlatform) system;
mkDerivation = mkDerivationFromStdenv stdenv;
inherit fetchurlBoot;
inherit overrides;
inherit cc hasCC;
# Convenience for doing some very basic shell syntax checking by parsing a script
# without running any commands. Because this will also skip `shopt -s extglob`
# commands and extglob affects the Bash parser, we enable extglob always.
shellDryRun = "${stdenv.shell} -n -O extglob";
}
# Propagate any extra attributes. For instance, we use this to
# "lift" packages like curl from the final stdenv for Linux to
# all-packages.nix for that platform (meaning that it has a line
# like curl = if stdenv ? curl then stdenv.curl else ...).
// extraAttrs
); in stdenv-overridable

View file

@ -0,0 +1,486 @@
{ lib, config }:
stdenv:
let
checkMeta = import ./check-meta.nix {
inherit lib config;
# Nix itself uses the `system` field of a derivation to decide where
# to build it. This is a bit confusing for cross compilation.
inherit (stdenv) hostPlatform;
};
# Based off lib.makeExtensible, with modifications:
makeDerivationExtensible = rattrs:
let
# NOTE: The following is a hint that will be printed by the Nix cli when
# encountering an infinite recursion. It must not be formatted into
# separate lines, because Nix would only show the last line of the comment.
# An infinite recursion here can be caused by having the attribute names of expression `e` in `.overrideAttrs(finalAttrs: previousAttrs: e)` depend on `finalAttrs`. Only the attribute values of `e` can depend on `finalAttrs`.
args = rattrs (args // { inherit finalPackage; });
# ^^^^
finalPackage =
mkDerivationSimple
(f0:
let
f = self: super:
# Convert f0 to an overlay. Legacy is:
# overrideAttrs (super: {})
# We want to introduce self. We follow the convention of overlays:
# overrideAttrs (self: super: {})
# Which means the first parameter can be either self or super.
# This is surprising, but far better than the confusion that would
# arise from flipping an overlay's parameters in some cases.
let x = f0 super;
in
if builtins.isFunction x
then
# Can't reuse `x`, because `self` comes first.
# Looks inefficient, but `f0 super` was a cheap thunk.
f0 self super
else x;
in
makeDerivationExtensible
(self: let super = rattrs self; in super // f self super))
args;
in finalPackage;
# makeDerivationExtensibleConst == makeDerivationExtensible (_: attrs),
# but pre-evaluated for a slight improvement in performance.
makeDerivationExtensibleConst = attrs:
mkDerivationSimple
(f0:
let
f = self: super:
let x = f0 super;
in
if builtins.isFunction x
then
f0 self super
else x;
in
makeDerivationExtensible (self: attrs // f self attrs))
attrs;
mkDerivationSimple = overrideAttrs:
# `mkDerivation` wraps the builtin `derivation` function to
# produce derivations that use this stdenv and its shell.
#
# 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
{
# These types of dependencies are all exhaustively documented in
# the "Specifying Dependencies" section of the "Standard
# Environment" chapter of the Nixpkgs manual.
# TODO(@Ericson2314): Stop using legacy dep attribute names
# host offset -> target offset
depsBuildBuild ? [] # -1 -> -1
, depsBuildBuildPropagated ? [] # -1 -> -1
, nativeBuildInputs ? [] # -1 -> 0 N.B. Legacy name
, propagatedNativeBuildInputs ? [] # -1 -> 0 N.B. Legacy name
, depsBuildTarget ? [] # -1 -> 1
, depsBuildTargetPropagated ? [] # -1 -> 1
, depsHostHost ? [] # 0 -> 0
, depsHostHostPropagated ? [] # 0 -> 0
, buildInputs ? [] # 0 -> 1 N.B. Legacy name
, propagatedBuildInputs ? [] # 0 -> 1 N.B. Legacy name
, depsTargetTarget ? [] # 1 -> 1
, depsTargetTargetPropagated ? [] # 1 -> 1
, checkInputs ? []
, installCheckInputs ? []
# 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.
#
# TODO(@Ericson2314): Make [ "build" "host" ] always the default.
configurePlatforms ? lib.optionals
(stdenv.hostPlatform != stdenv.buildPlatform)
[ "build" "host" ]
# TODO(@Ericson2314): Make unconditional / resolve #33599
# Check phase
, doCheck ? config.doCheckByDefault or false
# TODO(@Ericson2314): Make unconditional / resolve #33599
# InstallCheck phase
, doInstallCheck ? config.doCheckByDefault or false
, # TODO(@Ericson2314): Make always true and remove
strictDeps ? if config.strictDepsByDefault then true else stdenv.hostPlatform != stdenv.buildPlatform
, 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
, __impureHostDeps ? []
, __propagatedImpureHostDeps ? []
, sandboxProfile ? ""
, propagatedSandboxProfile ? ""
, hardeningEnable ? []
, hardeningDisable ? []
, patches ? []
, __contentAddressed ?
(! attrs ? outputHash) # Fixed-output drvs can't be content addressed too
&& config.contentAddressedByDefault
, ... } @ attrs:
let
# TODO(@oxij, @Ericson2314): This is here to keep the old semantics, remove when
# no package has `doCheck = true`.
doCheck' = doCheck && stdenv.buildPlatform.canExecute stdenv.hostPlatform;
doInstallCheck' = doInstallCheck && stdenv.buildPlatform.canExecute stdenv.hostPlatform;
separateDebugInfo' = separateDebugInfo && stdenv.hostPlatform.isLinux && !(stdenv.hostPlatform.useLLVM or false);
outputs' = outputs ++ lib.optional separateDebugInfo' "debug";
noNonNativeDeps = builtins.length (depsBuildTarget ++ depsBuildTargetPropagated
++ depsHostHost ++ depsHostHostPropagated
++ buildInputs ++ propagatedBuildInputs
++ depsTargetTarget ++ depsTargetTargetPropagated) == 0;
dontAddHostSuffix = attrs ? outputHash && !noNonNativeDeps || !stdenv.hasCC;
supportedHardeningFlags = [ "fortify" "stackprotector" "pie" "pic" "strictoverflow" "format" "relro" "bindnow" ];
# Musl-based platforms will keep "pie", other platforms will not.
# If you change this, make sure to update section `{#sec-hardening-in-nixpkgs}`
# in the nixpkgs manual to inform users about the defaults.
defaultHardeningFlags = if stdenv.hostPlatform.isMusl &&
# Except when:
# - static aarch64, where compilation works, but produces segfaulting dynamically linked binaries.
# - static armv7l, where compilation fails.
!((stdenv.hostPlatform.isAarch64 || stdenv.hostPlatform.isAarch32) && stdenv.hostPlatform.isStatic)
then supportedHardeningFlags
else lib.remove "pie" supportedHardeningFlags;
enabledHardeningOptions =
if builtins.elem "all" hardeningDisable
then []
else lib.subtractLists hardeningDisable (defaultHardeningFlags ++ hardeningEnable);
# hardeningDisable additionally supports "all".
erroneousHardeningFlags = lib.subtractLists supportedHardeningFlags (hardeningEnable ++ lib.remove "all" hardeningDisable);
checkDependencyList = checkDependencyList' [];
checkDependencyList' = positions: name: deps: lib.flip lib.imap1 deps (index: dep:
if lib.isDerivation dep || isNull dep || builtins.typeOf dep == "string" || builtins.typeOf dep == "path" then dep
else if lib.isList dep then checkDependencyList' ([index] ++ positions) name dep
else throw "Dependency is not of a valid type: ${lib.concatMapStrings (ix: "element ${toString ix} of ") ([index] ++ positions)}${name} for ${attrs.name or attrs.pname}");
in if builtins.length erroneousHardeningFlags != 0
then abort ("mkDerivation was called with unsupported hardening flags: " + lib.generators.toPretty {} {
inherit erroneousHardeningFlags hardeningDisable hardeningEnable supportedHardeningFlags;
})
else let
doCheck = doCheck';
doInstallCheck = doInstallCheck';
outputs = outputs';
references = nativeBuildInputs ++ buildInputs
++ propagatedNativeBuildInputs ++ propagatedBuildInputs;
dependencies = map (map lib.chooseDevOutputs) [
[
(map (drv: drv.__spliced.buildBuild or drv) (checkDependencyList "depsBuildBuild" depsBuildBuild))
(map (drv: drv.nativeDrv or drv) (checkDependencyList "nativeBuildInputs" nativeBuildInputs
++ lib.optional separateDebugInfo' ../../build-support/setup-hooks/separate-debug-info.sh
++ lib.optional stdenv.hostPlatform.isWindows ../../build-support/setup-hooks/win-dll-link.sh
++ lib.optionals doCheck checkInputs
++ lib.optionals doInstallCheck' installCheckInputs))
(map (drv: drv.__spliced.buildTarget or drv) (checkDependencyList "depsBuildTarget" depsBuildTarget))
]
[
(map (drv: drv.__spliced.hostHost or drv) (checkDependencyList "depsHostHost" depsHostHost))
(map (drv: drv.crossDrv or drv) (checkDependencyList "buildInputs" buildInputs))
]
[
(map (drv: drv.__spliced.targetTarget or drv) (checkDependencyList "depsTargetTarget" depsTargetTarget))
]
];
propagatedDependencies = map (map lib.chooseDevOutputs) [
[
(map (drv: drv.__spliced.buildBuild or drv) (checkDependencyList "depsBuildBuildPropagated" depsBuildBuildPropagated))
(map (drv: drv.nativeDrv or drv) (checkDependencyList "propagatedNativeBuildInputs" propagatedNativeBuildInputs))
(map (drv: drv.__spliced.buildTarget or drv) (checkDependencyList "depsBuildTargetPropagated" depsBuildTargetPropagated))
]
[
(map (drv: drv.__spliced.hostHost or drv) (checkDependencyList "depsHostHostPropagated" depsHostHostPropagated))
(map (drv: drv.crossDrv or drv) (checkDependencyList "propagatedBuildInputs" propagatedBuildInputs))
]
[
(map (drv: drv.__spliced.targetTarget or drv) (checkDependencyList "depsTargetTargetPropagated" depsTargetTargetPropagated))
]
];
computedSandboxProfile =
lib.concatMap (input: input.__propagatedSandboxProfile or [])
(stdenv.extraNativeBuildInputs
++ stdenv.extraBuildInputs
++ lib.concatLists dependencies);
computedPropagatedSandboxProfile =
lib.concatMap (input: input.__propagatedSandboxProfile or [])
(lib.concatLists propagatedDependencies);
computedImpureHostDeps =
lib.unique (lib.concatMap (input: input.__propagatedImpureHostDeps or [])
(stdenv.extraNativeBuildInputs
++ stdenv.extraBuildInputs
++ lib.concatLists dependencies));
computedPropagatedImpureHostDeps =
lib.unique (lib.concatMap (input: input.__propagatedImpureHostDeps or [])
(lib.concatLists propagatedDependencies));
derivationArg =
(removeAttrs attrs
["meta" "passthru" "pos"
"checkInputs" "installCheckInputs"
"__darwinAllowLocalNetworking"
"__impureHostDeps" "__propagatedImpureHostDeps"
"sandboxProfile" "propagatedSandboxProfile"])
// (lib.optionalAttrs (attrs ? name || (attrs ? pname && attrs ? version)) {
name =
let
# Indicate the host platform of the derivation if cross compiling.
# Fixed-output derivations like source tarballs shouldn't get a host
# suffix. But we have some weird ones with run-time deps that are
# just used for their side-affects. Those might as well since the
# hash can't be the same. See #32986.
hostSuffix = lib.optionalString
(stdenv.hostPlatform != stdenv.buildPlatform && !dontAddHostSuffix)
"-${stdenv.hostPlatform.config}";
# Disambiguate statically built packages. This was originally
# introduce as a means to prevent nix-env to get confused between
# nix and nixStatic. This should be also achieved by moving the
# hostSuffix before the version, so we could contemplate removing
# it again.
staticMarker = lib.optionalString stdenv.hostPlatform.isStatic "-static";
in
lib.strings.sanitizeDerivationName (
if attrs ? name
then attrs.name + hostSuffix
else "${attrs.pname}${staticMarker}${hostSuffix}-${attrs.version}"
);
}) // {
builder = attrs.realBuilder or stdenv.shell;
args = attrs.args or ["-e" (attrs.builder or ./default-builder.sh)];
inherit stdenv;
# The `system` attribute of a derivation has special meaning to Nix.
# Derivations set it to choose what sort of machine could be used to
# execute the build, The build platform entirely determines this,
# indeed more finely than Nix knows or cares about. The `system`
# attribute of `buildPlatfom` matches Nix's degree of specificity.
# exactly.
inherit (stdenv.buildPlatform) system;
userHook = config.stdenv.userHook or null;
__ignoreNulls = true;
inherit strictDeps;
depsBuildBuild = lib.elemAt (lib.elemAt dependencies 0) 0;
nativeBuildInputs = lib.elemAt (lib.elemAt dependencies 0) 1;
depsBuildTarget = lib.elemAt (lib.elemAt dependencies 0) 2;
depsHostHost = lib.elemAt (lib.elemAt dependencies 1) 0;
buildInputs = lib.elemAt (lib.elemAt dependencies 1) 1;
depsTargetTarget = lib.elemAt (lib.elemAt dependencies 2) 0;
depsBuildBuildPropagated = lib.elemAt (lib.elemAt propagatedDependencies 0) 0;
propagatedNativeBuildInputs = lib.elemAt (lib.elemAt propagatedDependencies 0) 1;
depsBuildTargetPropagated = lib.elemAt (lib.elemAt propagatedDependencies 0) 2;
depsHostHostPropagated = lib.elemAt (lib.elemAt propagatedDependencies 1) 0;
propagatedBuildInputs = lib.elemAt (lib.elemAt propagatedDependencies 1) 1;
depsTargetTargetPropagated = lib.elemAt (lib.elemAt propagatedDependencies 2) 0;
# This parameter is sometimes a string, sometimes null, and sometimes a list, yuck
configureFlags = let inherit (lib) optional elem; in
(/**/ if lib.isString configureFlags then lib.warn "String 'configureFlags' is deprecated and will be removed in release 23.05. Please use a list of strings. Derivation name: ${derivationArg.name}, file: ${pos.file or "unknown file"}" [configureFlags]
else if configureFlags == null then lib.warn "Null 'configureFlags' is deprecated and will be removed in release 23.05. Please use a empty list instead '[]'. Derivation name: ${derivationArg.name}, file: ${pos.file or "unknown file"}" []
else configureFlags)
++ optional (elem "build" configurePlatforms) "--build=${stdenv.buildPlatform.config}"
++ optional (elem "host" configurePlatforms) "--host=${stdenv.hostPlatform.config}"
++ optional (elem "target" configurePlatforms) "--target=${stdenv.targetPlatform.config}";
inherit patches;
inherit doCheck doInstallCheck;
inherit outputs;
} // lib.optionalAttrs (__contentAddressed) {
inherit __contentAddressed;
# Provide default values for outputHashMode and outputHashAlgo because
# most people won't care about these anyways
outputHashAlgo = attrs.outputHashAlgo or "sha256";
outputHashMode = attrs.outputHashMode or "recursive";
} // lib.optionalAttrs (stdenv.hostPlatform != stdenv.buildPlatform) {
cmakeFlags =
(/**/ if lib.isString cmakeFlags then [cmakeFlags]
else if cmakeFlags == null then []
else cmakeFlags)
++ [ "-DCMAKE_SYSTEM_NAME=${lib.findFirst lib.isString "Generic" (
lib.optional (!stdenv.hostPlatform.isRedox) stdenv.hostPlatform.uname.system)}"]
++ lib.optional (stdenv.hostPlatform.uname.processor != null) "-DCMAKE_SYSTEM_PROCESSOR=${stdenv.hostPlatform.uname.processor}"
++ lib.optional (stdenv.hostPlatform.uname.release != null) "-DCMAKE_SYSTEM_VERSION=${stdenv.hostPlatform.uname.release}"
++ lib.optional (stdenv.hostPlatform.isDarwin) "-DCMAKE_OSX_ARCHITECTURES=${stdenv.hostPlatform.darwinArch}"
++ lib.optional (stdenv.buildPlatform.uname.system != null) "-DCMAKE_HOST_SYSTEM_NAME=${stdenv.buildPlatform.uname.system}"
++ lib.optional (stdenv.buildPlatform.uname.processor != null) "-DCMAKE_HOST_SYSTEM_PROCESSOR=${stdenv.buildPlatform.uname.processor}"
++ lib.optional (stdenv.buildPlatform.uname.release != null) "-DCMAKE_HOST_SYSTEM_VERSION=${stdenv.buildPlatform.uname.release}";
mesonFlags = if mesonFlags == null then null else let
# See https://mesonbuild.com/Reference-tables.html#cpu-families
cpuFamily = platform: with platform;
/**/ if isAarch32 then "arm"
else if isAarch64 then "aarch64"
else if isx86_32 then "x86"
else if isx86_64 then "x86_64"
else platform.parsed.cpu.family + builtins.toString platform.parsed.cpu.bits;
crossFile = builtins.toFile "cross-file.conf" ''
[properties]
needs_exe_wrapper = true
[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'
'';
in [ "--cross-file=${crossFile}" ] ++ mesonFlags;
} // lib.optionalAttrs (enableParallelBuilding) {
enableParallelChecking = attrs.enableParallelChecking or true;
} // lib.optionalAttrs (hardeningDisable != [] || hardeningEnable != [] || stdenv.hostPlatform.isMusl) {
NIX_HARDENING_ENABLE = enabledHardeningOptions;
} // lib.optionalAttrs (stdenv.hostPlatform.isx86_64 && stdenv.hostPlatform ? gcc.arch) {
requiredSystemFeatures = attrs.requiredSystemFeatures or [] ++ [ "gccarch-${stdenv.hostPlatform.gcc.arch}" ];
} // lib.optionalAttrs (stdenv.buildPlatform.isDarwin) {
inherit __darwinAllowLocalNetworking;
# TODO: remove lib.unique once nix has a list canonicalization primitive
__sandboxProfile =
let profiles = [ stdenv.extraSandboxProfile ] ++ computedSandboxProfile ++ computedPropagatedSandboxProfile ++ [ propagatedSandboxProfile sandboxProfile ];
final = lib.concatStringsSep "\n" (lib.filter (x: x != "") (lib.unique profiles));
in final;
__propagatedSandboxProfile = lib.unique (computedPropagatedSandboxProfile ++ [ propagatedSandboxProfile ]);
__impureHostDeps = computedImpureHostDeps ++ computedPropagatedImpureHostDeps ++ __propagatedImpureHostDeps ++ __impureHostDeps ++ stdenv.__extraImpureHostDeps ++ [
"/dev/zero"
"/dev/random"
"/dev/urandom"
"/bin/sh"
];
__propagatedImpureHostDeps = computedPropagatedImpureHostDeps ++ __propagatedImpureHostDeps;
};
validity = checkMeta { inherit meta attrs; };
# The meta attribute is passed in the resulting attribute set,
# but it's not part of the actual derivation, i.e., it's not
# passed to the builder and is not a dependency. But since we
# include it in the result, it *is* available to nix-env for queries.
meta = {
# `name` above includes cross-compilation cruft,
# is under assert, and is sanitized.
# Let's have a clean always accessible version here.
name = attrs.name or "${attrs.pname}-${attrs.version}";
# If the packager hasn't specified `outputsToInstall`, choose a default,
# which is the name of `p.bin or p.out or p` along with `p.man` when
# present.
#
# If the packager has specified it, it will be overridden below in
# `// meta`.
#
# Note: This default probably shouldn't be globally configurable.
# Services and users should specify outputs explicitly,
# unless they are comfortable with this default.
outputsToInstall =
let
hasOutput = out: builtins.elem out outputs;
in [( lib.findFirst hasOutput null (["bin" "out"] ++ outputs) )]
++ lib.optional (hasOutput "man") "man";
}
// attrs.meta or {}
# Fill `meta.position` to identify the source location of the package.
// lib.optionalAttrs (pos != null) {
position = pos.file + ":" + toString pos.line;
} // {
# Expose the result of the checks for everyone to see.
inherit (validity) unfree broken unsupported insecure;
available = validity.valid != "no"
&& (if config.checkMetaRecursively or false
then lib.all (d: d.meta.available or true) references
else true);
};
in
lib.extendDerivation
validity.handled
({
# A derivation that always builds successfully and whose runtime
# dependencies are the original derivations build time dependencies
# This allows easy building and distributing of all derivations
# needed to enter a nix-shell with
# nix-build shell.nix -A inputDerivation
inputDerivation = derivation (derivationArg // {
# Add a name in case the original drv didn't have one
name = derivationArg.name or "inputDerivation";
# This always only has one output
outputs = [ "out" ];
# Propagate the original builder and arguments, since we override
# them and they might contain references to build inputs
_derivation_original_builder = derivationArg.builder;
_derivation_original_args = derivationArg.args;
builder = stdenv.shell;
# The bash builtin `export` dumps all current environment variables,
# which is where all build input references end up (e.g. $PATH for
# binaries). By writing this to $out, Nix can find and register
# them as runtime dependencies (since Nix greps for store paths
# through $out to find them)
args = [ "-c" "export > $out" ];
});
inherit meta passthru overrideAttrs;
} //
# Pass through extra attributes that are not inputs, but
# should be made available to Nix expressions using the
# derivation (e.g., in assertions).
passthru)
(derivation derivationArg);
in
fnOrAttrs:
if builtins.isFunction fnOrAttrs
then makeDerivationExtensible fnOrAttrs
else makeDerivationExtensibleConst fnOrAttrs

1395
pkgs/stdenv/generic/setup.sh Normal file

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,11 @@
{
busybox = import <nix/fetchurl.nix> {
url = "https://wdtz.org/files/wjzsj9cmdkc70f78yh072483x8656nci-stdenv-bootstrap-tools-aarch64-unknown-linux-musl/on-server/busybox";
sha256 = "01s6bwq84wyrjh3rdsgxni9gkzp7ss8rghg0cmp8zd87l79y8y4g";
executable = true;
};
bootstrapTools = import <nix/fetchurl.nix> {
url = "https://wdtz.org/files/wjzsj9cmdkc70f78yh072483x8656nci-stdenv-bootstrap-tools-aarch64-unknown-linux-musl/on-server/bootstrap-tools.tar.xz";
sha256 = "0pbqrw9z4ifkijpfpx15l2dzi00rq8c5zg9ghimz5qgr5dx7f7cl";
};
}

View file

@ -0,0 +1,11 @@
{
busybox = import <nix/fetchurl.nix> {
url = "http://tarballs.nixos.org/stdenv-linux/aarch64/c7c997a0662bf88264db52cbc41e67884eb7a1ff/busybox";
sha256 = "sha256-4EN2vLvXUkelZZR2eKaAQA5kCEuHNvRZN6dcohxVY+c=";
executable = true;
};
bootstrapTools = import <nix/fetchurl.nix> {
url = "http://tarballs.nixos.org/stdenv-linux/aarch64/c7c997a0662bf88264db52cbc41e67884eb7a1ff/bootstrap-tools.tar.xz";
sha256 = "sha256-AjOvmaW8JFVZaBSRUMKufr9kJozg/tsZr7PvUEBQyi4=";
};
}

View file

@ -0,0 +1,18 @@
{
# Note: do not use Hydra as a source URL. Ask a member of the
# infrastructure team to mirror the job.
busybox = import <nix/fetchurl.nix> {
# from job: https://hydra.nixos.org/job/nixpkgs/cross-trunk/bootstrapTools.armv5tel.dist/latest
# from build: https://hydra.nixos.org/build/114203025
url = "http://tarballs.nixos.org/stdenv-linux/armv5tel/0eb0ddc4dbe3cd5415c6b6e657538eb809fc3778/busybox";
# note: the following hash is different than the above hash, due to executable = true
sha256 = "0qxp2fsvs4phbc17g9npj9bsm20ylr8myi5pivcrmxm5qqflgi8d";
executable = true;
};
bootstrapTools = import <nix/fetchurl.nix> {
# from job: https://hydra.nixos.org/job/nixpkgs/cross-trunk/bootstrapTools.armv5tel.dist/latest
# from build: https://hydra.nixos.org/build/114203025
url = "http://tarballs.nixos.org/stdenv-linux/armv5tel/0eb0ddc4dbe3cd5415c6b6e657538eb809fc3778/bootstrap-tools.tar.xz";
sha256 = "28327343db5ecc7f7811449ec69280d5867fa5d1d377cab0426beb9d4e059ed6";
};
}

View file

@ -0,0 +1,11 @@
{
busybox = import <nix/fetchurl.nix> {
url = "https://wdtz.org/files/xmz441m69qrlfdw47l2k10zf87fsya6r-stdenv-bootstrap-tools-armv6l-unknown-linux-musleabihf/on-server/busybox";
sha256 = "01d0hp1xgrriiy9w0sd9vbqzwxnpwiyah80pi4vrpcmbwji36j1i";
executable = true;
};
bootstrapTools = import <nix/fetchurl.nix> {
url = "https://wdtz.org/files/xmz441m69qrlfdw47l2k10zf87fsya6r-stdenv-bootstrap-tools-armv6l-unknown-linux-musleabihf/on-server/bootstrap-tools.tar.xz";
sha256 = "1r9mz9w8y5jd7gfwfsrvs20qarzxy7bvrp5dlm41hnx6z617if1h";
};
}

View file

@ -0,0 +1,18 @@
{
# Note: do not use Hydra as a source URL. Ask a member of the
# infrastructure team to mirror the job.
busybox = import <nix/fetchurl.nix> {
# from job: https://hydra.nixos.org/job/nixpkgs/cross-trunk/bootstrapTools.armv6l.dist/latest
# from build: https://hydra.nixos.org/build/114202834
url = "http://tarballs.nixos.org/stdenv-linux/armv6l/0eb0ddc4dbe3cd5415c6b6e657538eb809fc3778/busybox";
# note: the following hash is different than the above hash, due to executable = true
sha256 = "1q02537cq56wlaxbz3s3kj5vmh6jbm27jhvga6b4m4jycz5sxxp6";
executable = true;
};
bootstrapTools = import <nix/fetchurl.nix> {
# from job: https://hydra.nixos.org/job/nixpkgs/cross-trunk/bootstrapTools.armv6l.dist/latest
# from build: https://hydra.nixos.org/build/114202834
url = "http://tarballs.nixos.org/stdenv-linux/armv6l/0eb0ddc4dbe3cd5415c6b6e657538eb809fc3778/bootstrap-tools.tar.xz";
sha256 = "0810fe74f8cd09831f177d075bd451a66b71278d3cc8db55b07c5e38ef3fbf3f";
};
}

View file

@ -0,0 +1,18 @@
{
# Note: do not use Hydra as a source URL. Ask a member of the
# infrastructure team to mirror the job.
busybox = import <nix/fetchurl.nix> {
# from job: https://hydra.nixos.org/job/nixpkgs/cross-trunk/bootstrapTools.armv7l.dist/latest
# from build: https://hydra.nixos.org/build/114203060
url = "http://tarballs.nixos.org/stdenv-linux/armv7l/0eb0ddc4dbe3cd5415c6b6e657538eb809fc3778/busybox";
# note: the following hash is different than the above hash, due to executable = true
sha256 = "18qc6w2yykh7nvhjklsqb2zb3fjh4p9r22nvmgj32jr1mjflcsjn";
executable = true;
};
bootstrapTools = import <nix/fetchurl.nix> {
# from job: https://hydra.nixos.org/job/nixpkgs/cross-trunk/bootstrapTools.armv7l.dist/latest
# from build: https://hydra.nixos.org/build/114203060
url = "http://tarballs.nixos.org/stdenv-linux/armv7l/0eb0ddc4dbe3cd5415c6b6e657538eb809fc3778/bootstrap-tools.tar.xz";
sha256 = "cf2968e8085cd3e6b3e9359624060ad24d253800ede48c5338179f6e0082c443";
};
}

View file

@ -0,0 +1,12 @@
{
busybox = import <nix/fetchurl.nix> {
url = "http://tarballs.nixos.org/stdenv-linux/i686/4907fc9e8d0d82b28b3c56e3a478a2882f1d700f/busybox";
sha256 = "ef4c1be6c7ae57e4f654efd90ae2d2e204d6769364c46469fa9ff3761195cba1";
executable = true;
};
bootstrapTools = import <nix/fetchurl.nix> {
url = "http://tarballs.nixos.org/stdenv-linux/i686/c5aabb0d603e2c1ea05f5a93b3be82437f5ebf31/bootstrap-tools.tar.xz";
sha256 = "b9bf20315f8c5c0411679c5326084420b522046057a0850367c67d9514794f1c";
};
}

View file

@ -0,0 +1,44 @@
let
fetch = { file, sha256 }: import <nix/fetchurl.nix> {
url = "http://tarballs.nixos.org/stdenv-linux/loongson2f/r22849/${file}";
inherit sha256;
executable = true;
};
in {
sh = fetch {
file = "sh";
sha256 = "02jjl49wdq85pgh61aqf78yaknn9mi3rcspbpk7hs9c4mida2rhf";
};
bzip2 = fetch {
file = "bzip2";
sha256 = "1qn27y3amj9c6mnjk2kyb59y0d2w4yv16z9apaxx91hyq19gf29z";
};
mkdir = fetch {
file = "mkdir";
sha256 = "1vbp2bv9hkyb2fwl8hjrffpywn1wrl1kc4yrwi2lirawlnc6kymh";
};
cpio = fetch {
file = "cpio";
sha256 = "0mqxwdx0sl7skxx6049mk35l7d0fnibqsv174284kdp4p7iixwa0";
};
ln = fetch {
file = "ln";
sha256 = "05lwx8qvga3yv8xhs8bjgsfygsfrcxsfck0lxw6gsdckx25fgi7s";
};
curl = fetch {
file = "curl.bz2";
sha256 = "0iblnz4my54gryac04i64fn3ksi9g3dx96yjq93fj39z6kx6151c";
};
bootstrapTools = {
url = "http://tarballs.nixos.org/stdenv-linux/loongson2f/r22849/cross-bootstrap-tools.cpio.bz2";
sha256 = "00aavbk76qjj2gdlmpaaj66r8nzl4d7pyl8cv1gigyzgpbr5vv3j";
};
}

View file

@ -0,0 +1,25 @@
#
# Files came from this Hydra build:
#
# https://hydra.nixos.org/build/172142499
#
# Which used nixpkgs revision 49a83445c28c4ffb8a1a90a1f68e6150ea48893b
# to instantiate:
#
# /nix/store/gj272sd56gsj6qpyzh4njpfzwdhviliz-stdenv-bootstrap-tools-powerpc64le-unknown-linux-gnu.drv
#
# and then built:
#
# /nix/store/n81pljbd8m0xgypm84krc2bnvqgjrfxx-stdenv-bootstrap-tools-powerpc64le-unknown-linux-gnu
#
{
busybox = import <nix/fetchurl.nix> {
url = "http://tarballs.nixos.org/stdenv-linux/powerpc64le/49a83445c28c4ffb8a1a90a1f68e6150ea48893b/busybox";
sha256 = "sha256-UscnfGKOZAKLkPcRtwrbT5Uj8m3Kj9jhkKp9MUc1eCY=";
executable = true;
};
bootstrapTools =import <nix/fetchurl.nix> {
url = "http://tarballs.nixos.org/stdenv-linux/powerpc64le/49a83445c28c4ffb8a1a90a1f68e6150ea48893b/bootstrap-tools.tar.xz";
sha256 = "sha256-A20GKGn3rM8K2JcU0SApRp3+avUE+bIm1h632AitRzU=";
};
}

View file

@ -0,0 +1,12 @@
{
busybox = import <nix/fetchurl.nix> {
url = "http://tarballs.nixos.org/stdenv-linux/riscv64/9bd3cf0063b80428bd85a286205adab4b6ffcbd6/busybox";
sha256 = "6f61912f94bc4ef287d1ff48a9521ed16bd07d8d8ec775e471f32c64d346583d";
executable = true;
};
bootstrapTools = import <nix/fetchurl.nix> {
url = "http://tarballs.nixos.org/stdenv-linux/riscv64/9bd3cf0063b80428bd85a286205adab4b6ffcbd6/bootstrap-tools.tar.xz";
sha256 = "5466b19288e980125fc62ebb864d09908ffe0bc50cebe52cfee89acff14d5b9f";
};
}

View file

@ -0,0 +1,11 @@
{
busybox = import <nix/fetchurl.nix> {
url = "https://wdtz.org/files/gywxhjgl70sxippa0pxs0vj5qcgz1wi8-stdenv-bootstrap-tools/on-server/busybox";
sha256 = "0779c2wn00467h76xpqil678gfi1y2p57c7zq2d917jsv2qj5009";
executable = true;
};
bootstrapTools = import <nix/fetchurl.nix> {
url = "https://wdtz.org/files/gywxhjgl70sxippa0pxs0vj5qcgz1wi8-stdenv-bootstrap-tools/on-server/bootstrap-tools.tar.xz";
sha256 = "1dwiqw4xvnm0b5fdgl89lz2qq45f6s9icwxn6n6ams71xw0dbqyi";
};
}

View file

@ -0,0 +1,9 @@
# Use busybox for i686-linux since it works on x86_64-linux as well.
(import ./i686.nix) //
{
bootstrapTools = import <nix/fetchurl.nix> {
url = "http://tarballs.nixos.org/stdenv-linux/x86_64/c5aabb0d603e2c1ea05f5a93b3be82437f5ebf31/bootstrap-tools.tar.xz";
sha256 = "a5ce9c155ed09397614646c9717fc7cd94b1023d7b76b618d409e4fefd6e9d39";
};
}

View file

@ -0,0 +1,18 @@
{ system, bootstrapFiles, extraAttrs }:
derivation ({
name = "bootstrap-tools";
builder = bootstrapFiles.busybox;
args = [ "ash" "-e" ./scripts/unpack-bootstrap-tools.sh ];
tarball = bootstrapFiles.bootstrapTools;
inherit system;
# Needed by the GCC wrapper.
langC = true;
langCC = true;
isGNU = true;
} // extraAttrs)

View file

@ -0,0 +1,64 @@
# Unpack the bootstrap tools tarball.
echo Unpacking the bootstrap tools...
$builder mkdir $out
< $tarball $builder unxz | $builder tar x -C $out
# Set the ELF interpreter / RPATH in the bootstrap binaries.
echo Patching the bootstrap tools...
if test -f $out/lib/ld.so.?; then
# MIPS case
LD_BINARY=$out/lib/ld.so.?
else
# i686, x86_64 and armv5tel
LD_BINARY=$out/lib/ld-*so.?
fi
# On x86_64, ld-linux-x86-64.so.2 barfs on patchelf'ed programs. So
# use a copy of patchelf.
LD_LIBRARY_PATH=$out/lib $LD_BINARY $out/bin/cp $out/bin/patchelf .
for i in $out/bin/* $out/libexec/gcc/*/*/*; do
if [ -L "$i" ]; then continue; fi
if [ -z "${i##*/liblto*}" ]; then continue; fi
echo patching "$i"
LD_LIBRARY_PATH=$out/lib $LD_BINARY \
./patchelf --set-interpreter $LD_BINARY --set-rpath $out/lib --force-rpath "$i"
done
for i in $out/lib/libpcre* $out/lib/libc.so; do
if [ -L "$i" ]; then continue; fi
echo patching "$i"
$out/bin/patchelf --set-rpath $out/lib --force-rpath "$i"
done
export PATH=$out/bin
# Fix the libc linker script.
#cat $out/lib/libc.so | sed "s|/nix/store/e*-[^/]*/|$out/|g" > $out/lib/libc.so.tmp
#mv $out/lib/libc.so.tmp $out/lib/libc.so
#cat $out/lib/libpthread.so | sed "s|/nix/store/e*-[^/]*/|$out/|g" > $out/lib/libpthread.so.tmp
#mv $out/lib/libpthread.so.tmp $out/lib/libpthread.so
# Provide some additional symlinks.
ln -s bash $out/bin/sh
ln -s bzip2 $out/bin/bunzip2
# 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
# Provide xz (actually only xz -d will work).
echo "#! $out/bin/sh" > $out/bin/xz
echo "exec $builder unxz \"\$@\"" >> $out/bin/xz
chmod +x $out/bin/egrep $out/bin/fgrep $out/bin/xz

View file

@ -0,0 +1,18 @@
{ system, bootstrapFiles, extraAttrs }:
derivation ({
name = "bootstrap-tools";
builder = bootstrapFiles.busybox;
args = [ "ash" "-e" ./scripts/unpack-bootstrap-tools.sh ];
tarball = bootstrapFiles.bootstrapTools;
inherit system;
# Needed by the GCC wrapper.
langC = true;
langCC = true;
isGNU = true;
} // extraAttrs)

View file

@ -0,0 +1,61 @@
# Unpack the bootstrap tools tarball.
echo Unpacking the bootstrap tools...
$builder mkdir $out
< $tarball $builder unxz | $builder tar x -C $out
# Set the ELF interpreter / RPATH in the bootstrap binaries.
echo Patching the bootstrap tools...
if test -f $out/lib/ld.so.?; then
# MIPS case
LD_BINARY=$out/lib/ld.so.?
elif test -f $out/lib/ld64.so.?; then
# ppc64(le)
LD_BINARY=$out/lib/ld64.so.?
else
# i686, x86_64 and armv5tel
LD_BINARY=$out/lib/ld-*so.?
fi
# On x86_64, ld-linux-x86-64.so.2 barfs on patchelf'ed programs. So
# use a copy of patchelf.
LD_LIBRARY_PATH=$out/lib $LD_BINARY $out/bin/cp $out/bin/patchelf .
for i in $out/bin/* $out/libexec/gcc/*/*/*; do
if [ -L "$i" ]; then continue; fi
if [ -z "${i##*/liblto*}" ]; then continue; fi
echo patching "$i"
LD_LIBRARY_PATH=$out/lib $LD_BINARY \
./patchelf --set-interpreter $LD_BINARY --set-rpath $out/lib --force-rpath "$i"
done
for i in $out/lib/librt-*.so $out/lib/libpcre*; do
if [ -L "$i" ]; then continue; fi
echo patching "$i"
$out/bin/patchelf --set-rpath $out/lib --force-rpath "$i"
done
export PATH=$out/bin
# Provide some additional symlinks.
ln -s bash $out/bin/sh
ln -s bzip2 $out/bin/bunzip2
# 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
# Provide xz (actually only xz -d will work).
echo "#! $out/bin/sh" > $out/bin/xz
echo "exec $builder unxz \"\$@\"" >> $out/bin/xz
chmod +x $out/bin/egrep $out/bin/fgrep $out/bin/xz

View file

@ -0,0 +1,449 @@
# This file constructs the standard build environment for the
# Linux/i686 platform. It's completely pure; that is, it relies on no
# external (non-Nix) tools, such as /usr/bin/gcc, and it contains a C
# compiler and linker that do not search in default locations,
# ensuring purity of components produced by it.
{ lib
, localSystem, crossSystem, config, overlays, crossOverlays ? []
, bootstrapFiles ?
let table = {
glibc = {
i686-linux = import ./bootstrap-files/i686.nix;
x86_64-linux = import ./bootstrap-files/x86_64.nix;
armv5tel-linux = import ./bootstrap-files/armv5tel.nix;
armv6l-linux = import ./bootstrap-files/armv6l.nix;
armv7l-linux = import ./bootstrap-files/armv7l.nix;
aarch64-linux = import ./bootstrap-files/aarch64.nix;
mipsel-linux = import ./bootstrap-files/loongson2f.nix;
powerpc64le-linux = import ./bootstrap-files/powerpc64le.nix;
riscv64-linux = import ./bootstrap-files/riscv64.nix;
};
musl = {
aarch64-linux = import ./bootstrap-files/aarch64-musl.nix;
armv6l-linux = import ./bootstrap-files/armv6l-musl.nix;
x86_64-linux = import ./bootstrap-files/x86_64-musl.nix;
};
};
# Try to find an architecture compatible with our current system. We
# just try every bootstrap weve got and test to see if it is
# compatible with or current architecture.
getCompatibleTools = lib.foldl (v: system:
if v != null then v
else if localSystem.canExecute (lib.systems.elaborate { inherit system; }) then archLookupTable.${system}
else null) null (lib.attrNames archLookupTable);
archLookupTable = table.${localSystem.libc}
or (abort "unsupported libc for the pure Linux stdenv");
files = archLookupTable.${localSystem.system} or (if getCompatibleTools != null then getCompatibleTools
else (abort "unsupported platform for the pure Linux stdenv"));
in files
}:
assert crossSystem == localSystem;
let
inherit (localSystem) system;
commonPreHook =
''
export NIX_ENFORCE_PURITY="''${NIX_ENFORCE_PURITY-1}"
export NIX_ENFORCE_NO_NATIVE="''${NIX_ENFORCE_NO_NATIVE-1}"
${if system == "x86_64-linux" then "NIX_LIB64_IN_SELF_RPATH=1" else ""}
${if system == "mipsel-linux" then "NIX_LIB32_IN_SELF_RPATH=1" else ""}
'';
# The bootstrap process proceeds in several steps.
# Create a standard environment by downloading pre-built binaries of
# coreutils, GCC, etc.
# Download and unpack the bootstrap tools (coreutils, GCC, Glibc, ...).
bootstrapTools = import (if localSystem.libc == "musl" then ./bootstrap-tools-musl else ./bootstrap-tools) {
inherit system bootstrapFiles;
extraAttrs = lib.optionalAttrs
config.contentAddressedByDefault
{
__contentAddressed = true;
outputHashAlgo = "sha256";
outputHashMode = "recursive";
};
};
getLibc = stage: stage.${localSystem.libc};
# This function builds the various standard environments used during
# the bootstrap. In all stages, we build an stdenv and the package
# set that can be built with that stdenv.
stageFun = prevStage:
{ name, overrides ? (self: super: {}), extraNativeBuildInputs ? [] }:
let
thisStdenv = import ../generic {
name = "${name}-stdenv-linux";
buildPlatform = localSystem;
hostPlatform = localSystem;
targetPlatform = localSystem;
inherit config extraNativeBuildInputs;
preHook =
''
# Don't patch #!/interpreter because it leads to retained
# dependencies on the bootstrapTools in the final stdenv.
dontPatchShebangs=1
${commonPreHook}
'';
shell = "${bootstrapTools}/bin/bash";
initialPath = [bootstrapTools];
fetchurlBoot = import ../../build-support/fetchurl/boot.nix {
inherit system;
};
cc = if prevStage.gcc-unwrapped == null
then null
else lib.makeOverridable (import ../../build-support/cc-wrapper) {
name = "${name}-gcc-wrapper";
nativeTools = false;
nativeLibc = false;
buildPackages = lib.optionalAttrs (prevStage ? stdenv) {
inherit (prevStage) stdenv;
};
cc = prevStage.gcc-unwrapped;
bintools = prevStage.binutils;
isGNU = true;
libc = getLibc prevStage;
inherit lib;
inherit (prevStage) coreutils gnugrep;
stdenvNoCC = prevStage.ccWrapperStdenv;
};
overrides = self: super: (overrides self super) // { fetchurl = thisStdenv.fetchurlBoot; };
};
in {
inherit config overlays;
stdenv = thisStdenv;
};
in
[
({}: {
__raw = true;
gcc-unwrapped = null;
binutils = null;
coreutils = null;
gnugrep = null;
})
# Build a dummy stdenv with no GCC or working fetchurl. This is
# because we need a stdenv to build the GCC wrapper and fetchurl.
(prevStage: stageFun prevStage {
name = "bootstrap-stage0";
overrides = self: super: {
# We thread stage0's stdenv through under this name so downstream stages
# can use it for wrapping gcc too. This way, downstream stages don't need
# to refer to this stage directly, which violates the principle that each
# stage should only access the stage that came before it.
ccWrapperStdenv = self.stdenv;
# The Glibc include directory cannot have the same prefix as the
# GCC include directory, since GCC gets confused otherwise (it
# will search the Glibc headers before the GCC headers). So
# create a dummy Glibc here, which will be used in the stdenv of
# stage1.
${localSystem.libc} = self.stdenv.mkDerivation {
pname = "bootstrap-stage0-${localSystem.libc}";
strictDeps = true;
version = "bootstrap";
enableParallelBuilding = true;
buildCommand = ''
mkdir -p $out
ln -s ${bootstrapTools}/lib $out/lib
'' + lib.optionalString (localSystem.libc == "glibc") ''
ln -s ${bootstrapTools}/include-glibc $out/include
'' + lib.optionalString (localSystem.libc == "musl") ''
ln -s ${bootstrapTools}/include-libc $out/include
'';
};
gcc-unwrapped = bootstrapTools;
binutils = import ../../build-support/bintools-wrapper {
name = "bootstrap-stage0-binutils-wrapper";
nativeTools = false;
nativeLibc = false;
buildPackages = { };
libc = getLibc self;
inherit lib;
inherit (self) stdenvNoCC coreutils gnugrep;
bintools = bootstrapTools;
};
coreutils = bootstrapTools;
gnugrep = bootstrapTools;
};
})
# Create the first "real" standard environment. This one consists
# of bootstrap tools only, and a minimal Glibc to keep the GCC
# configure script happy.
#
# For clarity, we only use the previous stage when specifying these
# stages. So stageN should only ever have references for stage{N-1}.
#
# If we ever need to use a package from more than one stage back, we
# simply re-export those packages in the middle stage(s) using the
# overrides attribute and the inherit syntax.
(prevStage: stageFun prevStage {
name = "bootstrap-stage1";
# Rebuild binutils to use from stage2 onwards.
overrides = self: super: {
binutils-unwrapped = super.binutils-unwrapped.override {
enableGold = false;
};
inherit (prevStage)
ccWrapperStdenv
gcc-unwrapped coreutils gnugrep;
${localSystem.libc} = getLibc prevStage;
# A threaded perl build needs glibc/libpthread_nonshared.a,
# which is not included in bootstrapTools, so disable threading.
# This is not an issue for the final stdenv, because this perl
# won't be included in the final stdenv and won't be exported to
# top-level pkgs as an override either.
perl = super.perl.override { enableThreading = false; };
};
})
# 2nd stdenv that contains our own rebuilt binutils and is used for
# compiling our own Glibc.
(prevStage: stageFun prevStage {
name = "bootstrap-stage2";
overrides = self: super: {
inherit (prevStage)
ccWrapperStdenv
gcc-unwrapped coreutils gnugrep
perl gnum4 bison;
dejagnu = super.dejagnu.overrideAttrs (a: { doCheck = false; } );
# We need libidn2 and its dependency libunistring as glibc dependency.
# To avoid the cycle, we build against bootstrap libc, nuke references,
# and use the result as input for our final glibc. We also pass this pair
# through, so the final package-set uses exactly the same builds.
libunistring = super.libunistring.overrideAttrs (attrs: {
postFixup = attrs.postFixup or "" + ''
${self.nukeReferences}/bin/nuke-refs "$out"/lib/lib*.so.*.*
'';
# Apparently iconv won't work with bootstrap glibc, but it will be used
# with glibc built later where we keep *this* build of libunistring,
# so we need to trick it into supporting libiconv.
am_cv_func_iconv_works = "yes";
});
libidn2 = super.libidn2.overrideAttrs (attrs: {
postFixup = attrs.postFixup or "" + ''
${self.nukeReferences}/bin/nuke-refs -e '${lib.getLib self.libunistring}' \
"$out"/lib/lib*.so.*.*
'';
});
# This also contains the full, dynamically linked, final Glibc.
binutils = prevStage.binutils.override {
# Rewrap the binutils with the new glibc, so both the next
# stage's wrappers use it.
libc = getLibc self;
# Unfortunately, when building gcc in the next stage, its LTO plugin
# would use the final libc but `ld` would use the bootstrap one,
# and that can fail to load. Therefore we upgrade `ld` to use newer libc;
# apparently the interpreter needs to match libc, too.
bintools = self.stdenvNoCC.mkDerivation {
inherit (prevStage.bintools.bintools) name;
enableParallelBuilding = true;
dontUnpack = true;
dontBuild = true;
strictDeps = true;
# We wouldn't need to *copy* all, but it's easier and the result is temporary anyway.
installPhase = ''
mkdir -p "$out"/bin
cp -a '${prevStage.bintools.bintools}'/bin/* "$out"/bin/
chmod +w "$out"/bin/ld.bfd
patchelf --set-interpreter '${getLibc self}'/lib/ld*.so.? \
--set-rpath "${getLibc self}/lib:$(patchelf --print-rpath "$out"/bin/ld.bfd)" \
"$out"/bin/ld.bfd
'';
};
};
};
# `libtool` comes with obsolete config.sub/config.guess that don't recognize Risc-V.
extraNativeBuildInputs =
lib.optional (localSystem.isRiscV) prevStage.updateAutotoolsGnuConfigScriptsHook;
})
# Construct a third stdenv identical to the 2nd, except that this
# one uses the rebuilt Glibc from stage2. It still uses the recent
# binutils and rest of the bootstrap tools, including GCC.
(prevStage: stageFun prevStage {
name = "bootstrap-stage3";
overrides = self: super: rec {
inherit (prevStage)
ccWrapperStdenv
binutils coreutils gnugrep
perl patchelf linuxHeaders gnum4 bison libidn2 libunistring;
${localSystem.libc} = getLibc prevStage;
# Link GCC statically against GMP etc. This makes sense because
# these builds of the libraries are only used by GCC, so it
# reduces the size of the stdenv closure.
gmp = super.gmp.override { stdenv = self.makeStaticLibraries self.stdenv; };
mpfr = super.mpfr.override { stdenv = self.makeStaticLibraries self.stdenv; };
libmpc = super.libmpc.override { stdenv = self.makeStaticLibraries self.stdenv; };
isl_0_20 = super.isl_0_20.override { stdenv = self.makeStaticLibraries self.stdenv; };
gcc-unwrapped = super.gcc-unwrapped.override {
isl = isl_0_20;
# Use a deterministically built compiler
# see https://github.com/NixOS/nixpkgs/issues/108475 for context
reproducibleBuild = true;
profiledCompiler = false;
};
};
extraNativeBuildInputs = [ prevStage.patchelf ] ++
# Many tarballs come with obsolete config.sub/config.guess that don't recognize aarch64.
lib.optional (!localSystem.isx86 || localSystem.libc == "musl")
prevStage.updateAutotoolsGnuConfigScriptsHook;
})
# Construct a fourth stdenv that uses the new GCC. But coreutils is
# still from the bootstrap tools.
(prevStage: stageFun prevStage {
name = "bootstrap-stage4";
overrides = self: super: {
# Zlib has to be inherited and not rebuilt in this stage,
# because gcc (since JAR support) already depends on zlib, and
# then if we already have a zlib we want to use that for the
# other purposes (binutils and top-level pkgs) too.
inherit (prevStage) gettext gnum4 bison gmp perl texinfo zlib linuxHeaders libidn2 libunistring;
${localSystem.libc} = getLibc prevStage;
binutils = super.binutils.override {
# Don't use stdenv's shell but our own
shell = self.bash + "/bin/bash";
# Build expand-response-params with last stage like below
buildPackages = {
inherit (prevStage) stdenv;
};
};
gcc = lib.makeOverridable (import ../../build-support/cc-wrapper) {
nativeTools = false;
nativeLibc = false;
isGNU = true;
buildPackages = {
inherit (prevStage) stdenv;
};
cc = prevStage.gcc-unwrapped;
bintools = self.binutils;
libc = getLibc self;
inherit lib;
inherit (self) stdenvNoCC coreutils gnugrep;
shell = self.bash + "/bin/bash";
};
};
extraNativeBuildInputs = [ prevStage.patchelf prevStage.xz ] ++
# Many tarballs come with obsolete config.sub/config.guess that don't recognize aarch64.
lib.optional (!localSystem.isx86 || localSystem.libc == "musl")
prevStage.updateAutotoolsGnuConfigScriptsHook;
})
# Construct the final stdenv. It uses the Glibc and GCC, and adds
# in a new binutils that doesn't depend on bootstrap-tools, as well
# as dynamically linked versions of all other tools.
#
# When updating stdenvLinux, make sure that the result has no
# dependency (`nix-store -qR') on bootstrapTools or the first
# binutils built.
(prevStage: {
inherit config overlays;
stdenv = import ../generic rec {
name = "stdenv-linux";
buildPlatform = localSystem;
hostPlatform = localSystem;
targetPlatform = localSystem;
inherit config;
preHook = commonPreHook;
initialPath =
((import ../common-path.nix) {pkgs = prevStage;});
extraNativeBuildInputs = [ prevStage.patchelf ] ++
# Many tarballs come with obsolete config.sub/config.guess that don't recognize aarch64.
lib.optional (!localSystem.isx86 || localSystem.libc == "musl")
prevStage.updateAutotoolsGnuConfigScriptsHook;
cc = prevStage.gcc;
shell = cc.shell;
inherit (prevStage.stdenv) fetchurlBoot;
extraAttrs = {
# remove before 22.11
glibc = lib.warn
( "`stdenv.glibc` is deprecated and will be removed in release 22.11."
+ " Please use `pkgs.glibc` instead.")
prevStage.glibc;
inherit bootstrapTools;
shellPackage = prevStage.bash;
};
# Mainly avoid reference to bootstrap tools
allowedRequisites = with prevStage; with lib;
# Simple executable tools
concatMap (p: [ (getBin p) (getLib p) ]) [
gzip bzip2 xz bash binutils.bintools coreutils diffutils findutils
gawk gnumake gnused gnutar gnugrep gnupatch patchelf ed
]
# Library dependencies
++ map getLib (
[ attr acl zlib pcre libidn2 libunistring ]
++ lib.optional (gawk.libsigsegv != null) gawk.libsigsegv
)
# More complicated cases
++ (map (x: getOutput x (getLibc prevStage)) [ "out" "dev" "bin" ] )
++ [ /*propagated from .dev*/ linuxHeaders
binutils gcc gcc.cc gcc.cc.lib gcc.expand-response-params
]
++ lib.optionals (!localSystem.isx86 || localSystem.libc == "musl")
[ prevStage.updateAutotoolsGnuConfigScriptsHook prevStage.gnu-config ];
overrides = self: super: {
inherit (prevStage)
gzip bzip2 xz bash coreutils diffutils findutils gawk
gnumake gnused gnutar gnugrep gnupatch patchelf
attr acl zlib pcre libunistring libidn2;
${localSystem.libc} = getLibc prevStage;
} // lib.optionalAttrs (super.stdenv.targetPlatform == localSystem) {
# Need to get rid of these when cross-compiling.
inherit (prevStage) binutils binutils-unwrapped;
gcc = cc;
};
};
})
]

View file

@ -0,0 +1,25 @@
{system ? builtins.currentSystem}:
let
make = crossSystem: import ./make-bootstrap-tools.nix {
localSystem = { inherit system; };
inherit crossSystem;
};
lib = import ../../../lib;
in lib.mapAttrs (n: make) (with lib.systems.examples; {
armv5tel = sheevaplug;
pogoplug4 = pogoplug4;
armv6l = raspberryPi;
armv7l = armv7l-hf-multiplatform;
aarch64 = aarch64-multiplatform;
x86_64-musl = musl64;
armv6l-musl = muslpi;
aarch64-musl = aarch64-multiplatform-musl;
riscv64 = riscv64;
mips64el-linux-gnuabin32 = mips64el-linux-gnuabin32;
mips64el-linux-gnuabi64 = mips64el-linux-gnuabi64;
powerpc64 = ppc64;
powerpc64-musl = ppc64-musl;
powerpc64le = powernv;
powerpc64le-musl = musl-power;
})

View file

@ -0,0 +1,305 @@
{ pkgs ? import ../../.. {} }:
let
libc = pkgs.stdenv.cc.libc;
in with pkgs; rec {
coreutilsMinimal = coreutils.override (args: {
# We want coreutils without ACL/attr support.
aclSupport = false;
attrSupport = false;
# Our tooling currently can't handle scripts in bin/, only ELFs and symlinks.
singleBinary = "symlinks";
});
tarMinimal = gnutar.override { acl = null; };
busyboxMinimal = busybox.override {
useMusl = !stdenv.targetPlatform.isRiscV;
enableStatic = true;
enableMinimal = true;
extraConfig = ''
CONFIG_ASH y
CONFIG_ASH_ECHO y
CONFIG_ASH_TEST y
CONFIG_ASH_OPTIMIZE_FOR_SIZE y
CONFIG_MKDIR y
CONFIG_TAR y
CONFIG_UNXZ y
'';
};
bootGCC = gcc.cc.override { enableLTO = false; };
bootBinutils = binutils.bintools.override {
withAllTargets = false;
# Don't need two linkers, disable whatever's not primary/default.
enableGold = false;
# bootstrap is easier w/static
enableShared = false;
};
build =
stdenv.mkDerivation {
name = "stdenv-bootstrap-tools";
meta = {
# Increase priority to unblock nixpkgs-unstable
# https://github.com/NixOS/nixpkgs/pull/104679#issuecomment-732267288
schedulingPriority = 200;
};
nativeBuildInputs = [ buildPackages.nukeReferences buildPackages.cpio ];
buildCommand = ''
set -x
mkdir -p $out/bin $out/lib $out/libexec
'' + (if (stdenv.hostPlatform.libc == "glibc") then ''
# Copy what we need of Glibc.
cp -d ${libc.out}/lib/ld*.so* $out/lib
cp -d ${libc.out}/lib/libc*.so* $out/lib
cp -d ${libc.out}/lib/libc_nonshared.a $out/lib
cp -d ${libc.out}/lib/libm*.so* $out/lib
cp -d ${libc.out}/lib/libdl*.so* $out/lib
cp -d ${libc.out}/lib/librt*.so* $out/lib
cp -d ${libc.out}/lib/libpthread*.so* $out/lib
cp -d ${libc.out}/lib/libnsl*.so* $out/lib
cp -d ${libc.out}/lib/libutil*.so* $out/lib
cp -d ${libc.out}/lib/libnss*.so* $out/lib
cp -d ${libc.out}/lib/libresolv*.so* $out/lib
cp -d ${libc.out}/lib/crt?.o $out/lib
# Hacky compat with our current unpack-bootstrap-tools.sh
ln -s librt.so "$out"/lib/librt-dummy.so
cp -rL ${libc.dev}/include $out
chmod -R u+w "$out"
# libc can contain linker scripts: find them, copy their deps,
# and get rid of absolute paths (nuke-refs would make them useless)
local lScripts=$(grep --files-with-matches --max-count=1 'GNU ld script' -R "$out/lib")
cp -d -t "$out/lib/" $(cat $lScripts | tr " " "\n" | grep -F '${libc.out}' | sort -u)
for f in $lScripts; do
substituteInPlace "$f" --replace '${libc.out}/lib/' ""
done
# Hopefully we won't need these.
rm -rf $out/include/mtd $out/include/rdma $out/include/sound $out/include/video
find $out/include -name .install -exec rm {} \;
find $out/include -name ..install.cmd -exec rm {} \;
mv $out/include $out/include-glibc
'' else if (stdenv.hostPlatform.libc == "musl") then ''
# Copy what we need from musl
cp ${libc.out}/lib/* $out/lib
cp -rL ${libc.dev}/include $out
chmod -R u+w "$out"
rm -rf $out/include/mtd $out/include/rdma $out/include/sound $out/include/video
find $out/include -name .install -exec rm {} \;
find $out/include -name ..install.cmd -exec rm {} \;
mv $out/include $out/include-libc
'' else throw "unsupported libc for bootstrap tools")
+ ''
# Copy coreutils, bash, etc.
cp -d ${coreutilsMinimal.out}/bin/* $out/bin
(cd $out/bin && rm vdir dir sha*sum pinky factor pathchk runcon shuf who whoami shred users)
cp ${bash.out}/bin/bash $out/bin
cp ${findutils.out}/bin/find $out/bin
cp ${findutils.out}/bin/xargs $out/bin
cp -d ${diffutils.out}/bin/* $out/bin
cp -d ${gnused.out}/bin/* $out/bin
cp -d ${gnugrep.out}/bin/grep $out/bin
cp ${gawk.out}/bin/gawk $out/bin
cp -d ${gawk.out}/bin/awk $out/bin
cp ${tarMinimal.out}/bin/tar $out/bin
cp ${gzip.out}/bin/gzip $out/bin
cp ${bzip2.bin}/bin/bzip2 $out/bin
cp -d ${gnumake.out}/bin/* $out/bin
cp -d ${patch}/bin/* $out/bin
cp ${patchelf}/bin/* $out/bin
cp -d ${gnugrep.pcre.out}/lib/libpcre*.so* $out/lib # needed by grep
# Copy what we need of GCC.
cp -d ${bootGCC.out}/bin/gcc $out/bin
cp -d ${bootGCC.out}/bin/cpp $out/bin
cp -d ${bootGCC.out}/bin/g++ $out/bin
cp -d ${bootGCC.lib}/lib/libgcc_s.so* $out/lib
cp -d ${bootGCC.lib}/lib/libstdc++.so* $out/lib
cp -d ${bootGCC.out}/lib/libssp.a* $out/lib
cp -d ${bootGCC.out}/lib/libssp_nonshared.a $out/lib
cp -rd ${bootGCC.out}/lib/gcc $out/lib
chmod -R u+w $out/lib
rm -f $out/lib/gcc/*/*/include*/linux
rm -f $out/lib/gcc/*/*/include*/sound
rm -rf $out/lib/gcc/*/*/include*/root
rm -f $out/lib/gcc/*/*/include-fixed/asm
rm -rf $out/lib/gcc/*/*/plugin
#rm -f $out/lib/gcc/*/*/*.a
cp -rd ${bootGCC.out}/libexec/* $out/libexec
chmod -R u+w $out/libexec
rm -rf $out/libexec/gcc/*/*/plugin
mkdir -p $out/include
cp -rd ${bootGCC.out}/include/c++ $out/include
chmod -R u+w $out/include
rm -rf $out/include/c++/*/ext/pb_ds
rm -rf $out/include/c++/*/ext/parallel
cp -d ${gmpxx.out}/lib/libgmp*.so* $out/lib
cp -d ${mpfr.out}/lib/libmpfr*.so* $out/lib
cp -d ${libmpc.out}/lib/libmpc*.so* $out/lib
cp -d ${zlib.out}/lib/libz.so* $out/lib
cp -d ${libelf}/lib/libelf.so* $out/lib
'' + lib.optionalString (stdenv.hostPlatform != stdenv.buildPlatform) ''
# These needed for cross but not native tools because the stdenv
# GCC has certain things built in statically. See
# pkgs/stdenv/linux/default.nix for the details.
cp -d ${isl_0_20.out}/lib/libisl*.so* $out/lib
'' + lib.optionalString (stdenv.hostPlatform.isRiscV) ''
# libatomic is required on RiscV platform for C/C++ atomics and pthread
# even though they may be translated into native instructions.
cp -d ${bootGCC.out}/lib/libatomic.a* $out/lib
'' + ''
cp -d ${bzip2.out}/lib/libbz2.so* $out/lib
# Copy binutils.
for i in as ld ar ranlib nm strip readelf objdump; do
cp ${bootBinutils.out}/bin/$i $out/bin
done
cp -r '${lib.getLib binutils.bintools}'/lib/* "$out/lib/"
chmod -R u+w $out
# Strip executables even further.
for i in $out/bin/* $out/libexec/gcc/*/*/*; do
if test -x $i -a ! -L $i; then
chmod +w $i
$STRIP -s $i || true
fi
done
nuke-refs $out/bin/*
nuke-refs $out/lib/*
nuke-refs $out/lib/*/*
nuke-refs $out/libexec/gcc/*/*/*
nuke-refs $out/lib/gcc/*/*/*
nuke-refs $out/lib/gcc/*/*/include-fixed/*{,/*}
mkdir $out/.pack
mv $out/* $out/.pack
mv $out/.pack $out/pack
mkdir $out/on-server
XZ_OPT="-9 -e" tar cvJf $out/on-server/bootstrap-tools.tar.xz --hard-dereference --sort=name --numeric-owner --owner=0 --group=0 --mtime=@1 -C $out/pack .
cp ${busyboxMinimal}/bin/busybox $out/on-server
chmod u+w $out/on-server/busybox
nuke-refs $out/on-server/busybox
''; # */
# The result should not contain any references (store paths) so
# that we can safely copy them out of the store and to other
# locations in the store.
allowedReferences = [];
};
dist = stdenv.mkDerivation {
name = "stdenv-bootstrap-tools";
meta = {
# Increase priority to unblock nixpkgs-unstable
# https://github.com/NixOS/nixpkgs/pull/104679#issuecomment-732267288
schedulingPriority = 200;
};
buildCommand = ''
mkdir -p $out/nix-support
echo "file tarball ${build}/on-server/bootstrap-tools.tar.xz" >> $out/nix-support/hydra-build-products
echo "file busybox ${build}/on-server/busybox" >> $out/nix-support/hydra-build-products
'';
};
bootstrapFiles = {
# Make them their own store paths to test that busybox still works when the binary is named /nix/store/HASH-busybox
busybox = runCommand "busybox" {} "cp ${build}/on-server/busybox $out";
bootstrapTools = runCommand "bootstrap-tools.tar.xz" {} "cp ${build}/on-server/bootstrap-tools.tar.xz $out";
};
bootstrapTools =
let extraAttrs = lib.optionalAttrs
config.contentAddressedByDefault
{
__contentAddressed = true;
outputHashAlgo = "sha256";
outputHashMode = "recursive";
};
in
if (stdenv.hostPlatform.libc == "glibc") then
import ./bootstrap-tools {
inherit (stdenv.buildPlatform) system; # Used to determine where to build
inherit bootstrapFiles extraAttrs;
}
else if (stdenv.hostPlatform.libc == "musl") then
import ./bootstrap-tools-musl {
inherit (stdenv.buildPlatform) system; # Used to determine where to build
inherit bootstrapFiles extraAttrs;
}
else throw "unsupported libc";
test = derivation {
name = "test-bootstrap-tools";
inherit (stdenv.hostPlatform) system; # We cannot "cross test"
builder = bootstrapFiles.busybox;
args = [ "ash" "-e" "-c" "eval \"$buildCommand\"" ];
buildCommand = ''
export PATH=${bootstrapTools}/bin
ls -l
mkdir $out
mkdir $out/bin
sed --version
find --version
diff --version
patch --version
make --version
awk --version
grep --version
gcc --version
'' + lib.optionalString (stdenv.hostPlatform.libc == "glibc") ''
ldlinux=$(echo ${bootstrapTools}/lib/${builtins.baseNameOf binutils.dynamicLinker})
export CPP="cpp -idirafter ${bootstrapTools}/include-glibc -B${bootstrapTools}"
export CC="gcc -idirafter ${bootstrapTools}/include-glibc -B${bootstrapTools} -Wl,-dynamic-linker,$ldlinux -Wl,-rpath,${bootstrapTools}/lib"
export CXX="g++ -idirafter ${bootstrapTools}/include-glibc -B${bootstrapTools} -Wl,-dynamic-linker,$ldlinux -Wl,-rpath,${bootstrapTools}/lib"
'' + lib.optionalString (stdenv.hostPlatform.libc == "musl") ''
ldmusl=$(echo ${bootstrapTools}/lib/ld-musl*.so.?)
export CPP="cpp -idirafter ${bootstrapTools}/include-libc -B${bootstrapTools}"
export CC="gcc -idirafter ${bootstrapTools}/include-libc -B${bootstrapTools} -Wl,-dynamic-linker,$ldmusl -Wl,-rpath,${bootstrapTools}/lib"
export CXX="g++ -idirafter ${bootstrapTools}/include-libc -B${bootstrapTools} -Wl,-dynamic-linker,$ldmusl -Wl,-rpath,${bootstrapTools}/lib"
'' + ''
echo '#include <stdio.h>' >> foo.c
echo '#include <limits.h>' >> foo.c
echo 'int main() { printf("Hello World\\n"); return 0; }' >> foo.c
$CC -o $out/bin/foo foo.c
$out/bin/foo
echo '#include <iostream>' >> bar.cc
echo 'int main() { std::cout << "Hello World\\n"; }' >> bar.cc
$CXX -v -o $out/bin/bar bar.cc
$out/bin/bar
tar xvf ${hello.src}
cd hello-*
./configure --prefix=$out
make
make install
'';
};
}

View file

@ -0,0 +1,170 @@
{ lib
, localSystem, crossSystem, config, overlays, crossOverlays ? []
}:
assert crossSystem == localSystem;
let
inherit (localSystem) system;
shell =
if system == "i686-freebsd" || system == "x86_64-freebsd" then "/usr/local/bin/bash"
else "/bin/bash";
path =
(if system == "i686-solaris" then [ "/usr/gnu" ] else []) ++
(if system == "i686-netbsd" then [ "/usr/pkg" ] else []) ++
(if system == "x86_64-solaris" then [ "/opt/local/gnu" ] else []) ++
["/" "/usr" "/usr/local"];
prehookBase = ''
# Disable purity tests; it's allowed (even needed) to link to
# libraries outside the Nix store (like the C library).
export NIX_ENFORCE_PURITY=
export NIX_ENFORCE_NO_NATIVE="''${NIX_ENFORCE_NO_NATIVE-1}"
'';
prehookFreeBSD = ''
${prehookBase}
alias make=gmake
alias tar=gtar
alias sed=gsed
export MAKE=gmake
shopt -s expand_aliases
'';
prehookOpenBSD = ''
${prehookBase}
alias make=gmake
alias grep=ggrep
alias mv=gmv
alias ln=gln
alias sed=gsed
alias tar=gtar
export MAKE=gmake
shopt -s expand_aliases
'';
prehookNetBSD = ''
${prehookBase}
alias make=gmake
alias sed=gsed
alias tar=gtar
export MAKE=gmake
shopt -s expand_aliases
'';
# prevent libtool from failing to find dynamic libraries
prehookCygwin = ''
${prehookBase}
shopt -s expand_aliases
export lt_cv_deplibs_check_method=pass_all
'';
extraNativeBuildInputsCygwin = [
../cygwin/all-buildinputs-as-runtimedep.sh
../cygwin/wrap-exes-to-find-dlls.sh
] ++ (if system == "i686-cygwin" then [
../cygwin/rebase-i686.sh
] else if system == "x86_64-cygwin" then [
../cygwin/rebase-x86_64.sh
] else []);
# A function that builds a "native" stdenv (one that uses tools in
# /usr etc.).
makeStdenv =
{ cc, fetchurl, extraPath ? [], overrides ? (self: super: { }), extraNativeBuildInputs ? [] }:
import ../generic {
buildPlatform = localSystem;
hostPlatform = localSystem;
targetPlatform = localSystem;
preHook =
if system == "i686-freebsd" then prehookFreeBSD else
if system == "x86_64-freebsd" then prehookFreeBSD else
if system == "i686-openbsd" then prehookOpenBSD else
if system == "i686-netbsd" then prehookNetBSD else
if system == "i686-cygwin" then prehookCygwin else
if system == "x86_64-cygwin" then prehookCygwin else
prehookBase;
extraNativeBuildInputs = extraNativeBuildInputs ++
(if system == "i686-cygwin" then extraNativeBuildInputsCygwin else
if system == "x86_64-cygwin" then extraNativeBuildInputsCygwin else
[]);
initialPath = extraPath ++ path;
fetchurlBoot = fetchurl;
inherit shell cc overrides config;
};
in
[
({}: rec {
__raw = true;
stdenv = makeStdenv {
cc = null;
fetchurl = null;
};
stdenvNoCC = stdenv;
cc = let
nativePrefix = { # switch
i686-solaris = "/usr/gnu";
x86_64-solaris = "/opt/local/gcc47";
}.${system} or "/usr";
in
import ../../build-support/cc-wrapper {
name = "cc-native";
nativeTools = true;
nativeLibc = true;
inherit lib nativePrefix;
bintools = import ../../build-support/bintools-wrapper {
name = "bintools";
inherit lib stdenvNoCC nativePrefix;
nativeTools = true;
nativeLibc = true;
};
inherit stdenvNoCC;
};
fetchurl = import ../../build-support/fetchurl {
inherit lib stdenvNoCC;
# Curl should be in /usr/bin or so.
curl = null;
};
})
# First build a stdenv based only on tools outside the store.
(prevStage: {
inherit config overlays;
stdenv = makeStdenv {
inherit (prevStage) cc fetchurl;
} // { inherit (prevStage) fetchurl; };
})
# Using that, build a stdenv that adds the xz command (which most systems
# don't have, so we mustn't rely on the native environment providing it).
(prevStage: {
inherit config overlays;
stdenv = makeStdenv {
inherit (prevStage.stdenv) cc fetchurl;
extraPath = [ prevStage.xz ];
overrides = self: super: { inherit (prevStage) xz; };
extraNativeBuildInputs = if localSystem.isLinux then [ prevStage.patchelf ] else [];
};
})
]

View file

@ -0,0 +1,50 @@
{ lib
, crossSystem, localSystem, config, overlays
, bootStages
, ...
}:
assert crossSystem == localSystem;
bootStages ++ [
(prevStage: {
inherit config overlays;
stdenv = import ../generic rec {
inherit config;
inherit (prevStage.stdenv) buildPlatform hostPlatform targetPlatform;
preHook = ''
export NIX_ENFORCE_PURITY="''${NIX_ENFORCE_PURITY-1}"
export NIX_ENFORCE_NO_NATIVE="''${NIX_ENFORCE_NO_NATIVE-1}"
export NIX_IGNORE_LD_THROUGH_GCC=1
'';
initialPath = (import ../common-path.nix) { pkgs = prevStage; };
cc = import ../../build-support/cc-wrapper {
inherit lib;
nativeTools = false;
nativePrefix = lib.optionalString hostPlatform.isSunOS "/usr";
nativeLibc = true;
inherit (prevStage) stdenvNoCC binutils coreutils gnugrep;
cc = prevStage.gcc.cc;
isGNU = true;
shell = prevStage.bash + "/bin/sh";
};
shell = prevStage.bash + "/bin/sh";
fetchurlBoot = prevStage.stdenv.fetchurlBoot;
overrides = self: super: {
inherit cc;
inherit (cc) binutils;
inherit (prevStage)
gzip bzip2 xz bash coreutils diffutils findutils gawk
gnumake gnused gnutar gnugrep gnupatch perl;
};
};
})
]