push sheeet
Some checks failed
Periodic Merges (6h) / master → staging-nixos (push) Failing after 12m50s
Periodic Merges (6h) / master → staging-next (push) Failing after 12m54s
Periodic Merges (24h) / merge-base(master,staging) → haskell-updates (push) Failing after 11m54s
Periodic Merges (6h) / staging-next → staging (push) Failing after 12m13s
Periodic Merges (24h) / staging-next-25.05 → staging-25.05 (push) Failing after 13m24s
Periodic Merges (24h) / release-25.05 → staging-next-25.05 (push) Failing after 14m28s

This commit is contained in:
Dark Steveneq
2025-10-09 14:15:47 +02:00
commit 646b892680
49168 changed files with 5897842 additions and 0 deletions

407
pkgs/stdenv/adapters.nix Normal file
View File

@@ -0,0 +1,407 @@
/*
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 =
stdenv: (import ./generic/make-derivation.nix { inherit lib config; } stdenv).mkDerivation;
# Low level function to help with overriding `mkDerivationFromStdenv`. One
# gives it the old stdenv arguments and a "continuation" function, and
# 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;
hasCC = cc != null;
};
# 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 (
args:
(
if (args.__structuredAttrs or false) || (args ? env.NIX_CFLAGS_LINK) then
{
env = (args.env or { }) // {
NIX_CFLAGS_LINK = toString (args.env.NIX_CFLAGS_LINK or "") + " -static";
};
}
else
{
NIX_CFLAGS_LINK = toString (args.NIX_CFLAGS_LINK or "") + " -static";
}
)
// lib.optionalAttrs (!(args.dontAddStaticConfigureFlags or false)) {
configureFlags = (args.configureFlags or [ ]) ++ [
"--disable-shared" # brrr...
];
cmakeFlags = (args.cmakeFlags or [ ]) ++ [ "-DCMAKE_SKIP_INSTALL_RPATH=On" ];
}
)
);
}
// lib.optionalAttrs (stdenv0.hostPlatform.libc == "glibc") {
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"
"-Ddefault_both_libraries=static"
];
}
);
});
# Best effort static binaries. Will still be linked to libSystem,
# but more portable than Nix store binaries.
makeStaticDarwin =
stdenv:
stdenv.override (old: {
mkDerivationFromStdenv = withOldMkDerivation old (
stdenv: mkDerivationSuper: args:
(mkDerivationSuper args).overrideAttrs (
prevAttrs:
if prevAttrs ? env.NIX_CFLAGS_LINK then
{
env = prevAttrs.env // {
NIX_CFLAGS_LINK =
toString (args.env.NIX_CFLAGS_LINK or "")
+ lib.optionalString (stdenv.cc.isGNU or false) " -static-libgcc";
};
}
else
{
NIX_CFLAGS_LINK =
toString (prevAttrs.NIX_CFLAGS_LINK or "")
+ lib.optionalString (stdenv.cc.isGNU or false) " -static-libgcc";
}
)
);
});
# 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
);
/*
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
{ env.NIX_CFLAGS_COMPILE = "-O0"; }
stdenv;
*/
addAttrsToDerivation =
extraAttrs: stdenv:
stdenv.override (old: {
mkDerivationFromStdenv = extendMkDerivationArgs old (_: extraAttrs);
});
/*
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}:${toString license}:@" val;
in
pkg
// {
outPath = printDrvPath pkg.outPath;
drvPath = printDrvPath 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;
env = (args.env or { }) // {
NIX_CFLAGS_COMPILE = toString (args.env.NIX_CFLAGS_COMPILE or "") + " -ggdb -Og";
NIX_RUSTFLAGS = toString (args.env.NIX_RUSTFLAGS or "") + " -g -C opt-level=0 -C strip=none";
};
});
});
# 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";
});
});
/*
Copy the libstdc++ from the model stdenv to the target stdenv.
TODO(@connorbaker):
This interface provides behavior which should be revisited prior to the
release of 24.05. For a more detailed explanation and discussion, see
https://github.com/NixOS/nixpkgs/issues/283517.
*/
useLibsFrom =
modelStdenv: targetStdenv:
let
ccForLibs = modelStdenv.cc.cc;
/*
NOTE(@connorbaker):
This assumes targetStdenv.cc is a cc-wrapper.
*/
cc = targetStdenv.cc.override {
/*
NOTE(originally by rrbutani):
Normally the `useCcForLibs`/`gccForLibs` mechanism is used to get a
clang based `cc` to use `libstdc++` (from gcc).
Here we (ab)use it to use a `libstdc++` from a different `gcc` than our
`cc`.
Note that this does not inhibit our `cc`'s lib dir from being added to
cflags/ldflags (see `cc_solib` in `cc-wrapper`) but this is okay: our
`gccForLibs`'s paths should take precedence.
*/
useCcForLibs = true;
gccForLibs = ccForLibs;
};
in
overrideCC targetStdenv cc;
useMoldLinker =
stdenv:
if stdenv.targetPlatform.isDarwin then
throw "Mold can't be used to emit Mach-O (Darwin) binaries"
else
let
bintools = stdenv.cc.bintools.override {
extraBuildCommands = ''
wrap ld.mold ${../build-support/bintools-wrapper/ld-wrapper.sh} ${pkgs.buildPackages.mold}/bin/ld.mold
wrap ${stdenv.cc.bintools.targetPrefix}ld.mold ${../build-support/bintools-wrapper/ld-wrapper.sh} ${pkgs.buildPackages.mold}/bin/ld.mold
wrap ${stdenv.cc.bintools.targetPrefix}ld ${../build-support/bintools-wrapper/ld-wrapper.sh} ${pkgs.buildPackages.mold}/bin/ld.mold
'';
};
in
stdenv.override (
old:
{
allowedRequisites = null;
cc = stdenv.cc.override { inherit bintools; };
# gcc >12.1.0 supports '-fuse-ld=mold'
# the wrap ld above in bintools supports gcc <12.1.0 and shouldn't harm >12.1.0
# https://github.com/rui314/mold#how-to-use
}
//
lib.optionalAttrs
(stdenv.cc.isClang || (stdenv.cc.isGNU && lib.versionAtLeast stdenv.cc.version "12"))
{
mkDerivationFromStdenv = extendMkDerivationArgs old (args: {
NIX_CFLAGS_LINK = toString (args.NIX_CFLAGS_LINK or "") + " -fuse-ld=mold";
});
}
);
/*
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: {
env = (args.env or { }) // {
NIX_CFLAGS_COMPILE = toString (args.env.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: {
env = (args.env or { }) // {
NIX_CFLAGS_COMPILE = toString (args.env.NIX_CFLAGS_COMPILE or "") + " ${toString compilerFlags}";
};
});
});
withDefaultHardeningFlags =
defaultHardeningFlags: stdenv:
let
bintools =
let
bintools' = stdenv.cc.bintools;
in
if bintools' ? override then
(bintools'.override {
inherit defaultHardeningFlags;
})
else
bintools';
in
stdenv.override (old: {
cc =
if stdenv.cc == null then
null
else
stdenv.cc.override {
inherit bintools;
};
allowedRequisites = lib.mapNullable (rs: rs ++ [ bintools ]) (stdenv.allowedRequisites or null);
});
}

166
pkgs/stdenv/booter.nix Normal file
View File

@@ -0,0 +1,166 @@
# 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 in 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.__bootPackages` 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 (
(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.pkgsBuildTarget.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,139 @@
{
lib,
localSystem,
crossSystem,
config,
overlays,
crossOverlays ? [ ],
}:
let
bootStages = import ../. {
inherit lib localSystem overlays;
crossSystem = localSystem;
crossOverlays = [ ];
# Ignore custom stdenvs when cross compiling for compatibility
# Use replaceCrossStdenv instead.
config = 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;
stdenvNoCC = 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
allowedRequisites = null;
cc = null;
hasCC = false;
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;
})
);
in
{
inherit config;
overlays = overlays ++ crossOverlays;
selfBuild = false;
inherit stdenvNoCC;
stdenv =
let
inherit (stdenvNoCC) hostPlatform targetPlatform;
baseStdenv = stdenvNoCC.override {
# Old ones run on wrong platform
extraBuildInputs = lib.optionals hostPlatform.isDarwin [
buildPackages.targetPackages.apple-sdk
];
hasCC = !stdenvNoCC.targetPlatform.isGhcjs;
cc =
if crossSystem.useiOSPrebuilt or false then
buildPackages.darwin.iosSdkPkgs.clang
else if crossSystem.useAndroidPrebuilt or false then
buildPackages."androidndkPkgs_${crossSystem.androidNdkVersion}".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.systemLibcxxClang
else if crossSystem.useLLVM or false then
buildPackages.llvmPackages.clang
else if crossSystem.useZig or false then
buildPackages.zig.cc
else if crossSystem.useArocc or false then
buildPackages.arocc
else
buildPackages.gcc;
};
in
if config ? replaceCrossStdenv then
config.replaceCrossStdenv { inherit buildPackages baseStdenv; }
else
baseStdenv;
}
)
]

View File

@@ -0,0 +1,37 @@
{
lib,
localSystem,
crossSystem,
config,
overlays,
crossOverlays ? [ ],
}:
assert crossSystem == localSystem;
let
bootStages = import ../. {
inherit
lib
localSystem
crossSystem
overlays
;
# Remove config.replaceStdenv to ensure termination.
config = removeAttrs config [ "replaceStdenv" ];
};
in
bootStages
++ [
# Additional stage, built using custom stdenv
(vanillaPackages: {
inherit config overlays;
stdenv =
assert vanillaPackages.stdenv.hostPlatform == localSystem;
assert vanillaPackages.stdenv.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,26 @@
# Darwin stdenv design goals
There are two more goals worth calling out explicitly:
1. The standard environment should build successfully with sandboxing enabled on Darwin. It is
fine if a package requires a `sandboxProfile` to build, but it should not be necessary to
disable the sandbox to build the stdenv successfully; and
2. The output should depend weakly on the bootstrap tools. Historically, Darwin required updating
the bootstrap tools prior to updating the version of LLVM used in the standard environment.
By not depending on a specific version, the LLVM used on Darwin can be updated simply by
bumping the definition of llvmPackages in `all-packages.nix`.
# Updating the stdenv
There are effectively two steps when updating the standard environment:
1. Update the definition of llvmPackages in `all-packages.nix` for Darwin to match the value of
llvmPackages.latest in `all-packages.nix`. Timing-wise, this is done currently using the spring
release of LLVM and once llvmPackages.latest has been updated to match. If the LLVM project
has announced a release schedule of patch updates, wait until those are in nixpkgs. Otherwise,
the LLVM updates will have to go through staging instead of being merged into master; and
2. Fix the resulting breakage. Most things break due to additional warnings being turned into
errors or additional strictness applied by LLVM. Fixes may come in the form of disabling those
new warnings or by fixing the actual source (e.g., with a patch or update upstream). If the
fix is trivial (e.g., adding a missing int to an implicit declaration), it is better to fix
the problem instead of silencing the warning.

View File

@@ -0,0 +1,24 @@
# FIXME: Changed to arm64-apple-darwin in release.nix stdenvBootstrapTools, please handle when refreshing
# Autogenerated by maintainers/scripts/bootstrap-files/refresh-tarballs.bash as:
# $ ./refresh-tarballs.bash --targets=aarch64-apple-darwin
#
# Metadata:
# - nixpkgs revision: d8657587c0c1ce2191b4b489299c386b5b7148c6
# - hydra build: https://hydra.nixos.org/job/nixpkgs/trunk/stdenvBootstrapTools.aarch64-apple-darwin.build/latest
# - resolved hydra build: https://hydra.nixos.org/build/290554342
# - instantiated derivation: /nix/store/g4x0vd6rfvr124sbxqfphkf8l06sy4pc-stdenv-bootstrap-tools.drv
# - output directory: /nix/store/8wbnh6accpx3fcf20jvbnapcalvm1cmd-stdenv-bootstrap-tools
# - build time: Thu, 20 Feb 2025 12:38:34 +0000
{
bootstrapTools = import <nix/fetchurl.nix> {
url = "http://tarballs.nixos.org/stdenv/aarch64-apple-darwin/d8657587c0c1ce2191b4b489299c386b5b7148c6/bootstrap-tools.tar.xz";
hash = "sha256-i+KwTIY6P3dKfNmE42BWC9+qUomoDxazO50uvrzNlpE=";
};
unpack = import <nix/fetchurl.nix> {
url = "http://tarballs.nixos.org/stdenv/aarch64-apple-darwin/d8657587c0c1ce2191b4b489299c386b5b7148c6/unpack.nar.xz";
hash = "sha256-mzql+dmvqtn663HvzWZORA8f9d9RPShwPJNIk9VGEvU=";
name = "unpack";
unpack = true;
};
}

View File

@@ -0,0 +1,22 @@
# Autogenerated by maintainers/scripts/bootstrap-files/refresh-tarballs.bash as:
# $ ./refresh-tarballs.bash --targets=x86_64-apple-darwin
#
# Metadata:
# - nixpkgs revision: d8657587c0c1ce2191b4b489299c386b5b7148c6
# - hydra build: https://hydra.nixos.org/job/nixpkgs/trunk/stdenvBootstrapTools.x86_64-apple-darwin.build/latest
# - resolved hydra build: https://hydra.nixos.org/build/290554343
# - instantiated derivation: /nix/store/38sk9c8s4zyhjrifcr9cd3a8d9hyi4zj-stdenv-bootstrap-tools.drv
# - output directory: /nix/store/y617yisg19x2pj34hzxg9zcm3wlsfj29-stdenv-bootstrap-tools
# - build time: Thu, 20 Feb 2025 12:38:34 +0000
{
bootstrapTools = import <nix/fetchurl.nix> {
url = "http://tarballs.nixos.org/stdenv/x86_64-apple-darwin/d8657587c0c1ce2191b4b489299c386b5b7148c6/bootstrap-tools.tar.xz";
hash = "sha256-gtkeaUaV8ZXY8JxEkyd7ZeB75MESpsBPjaux0B2c0lE=";
};
unpack = import <nix/fetchurl.nix> {
url = "http://tarballs.nixos.org/stdenv/x86_64-apple-darwin/d8657587c0c1ce2191b4b489299c386b5b7148c6/unpack.nar.xz";
hash = "sha256-vgfZGKo6I565ORLZ/AGKh6SUpgLhgaanFuhYk897+zw=";
name = "unpack";
unpack = true;
};
}

View File

@@ -0,0 +1,25 @@
{
lib,
stdenv,
bootstrapTools,
unpack,
}:
derivation {
inherit (stdenv.hostPlatform) system;
name = "bootstrap-tools";
builder = "${unpack}/bin/bash";
args = [
"${unpack}/bootstrap-tools-unpack.sh"
bootstrapTools
];
PATH = lib.makeBinPath [
(placeholder "out")
unpack
];
allowedReferences = [ "out" ];
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,65 @@
{
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');
}
else
{ };
pkgs = import pkgspath ({ inherit localSystem; } // cross // custom-bootstrap);
build = pkgs.callPackage ./stdenv-bootstrap-tools.nix { };
bootstrapTools = pkgs.callPackage ./bootstrap-tools.nix {
inherit (build.bootstrapFiles) bootstrapTools unpack;
};
test = pkgs.callPackage ./test-bootstrap-tools.nix { inherit bootstrapTools; };
# The ultimate test: bootstrap a whole stdenv from the tools specified above and get a package set out of it
# eg: nix-build -A freshBootstrapTools.test-pkgs.stdenv
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 (build) bootstrapFiles;
};
in
(import (test-pkgspath + "/pkgs/stdenv/darwin") args');
};
in
{
inherit
build
bootstrapTools
test
test-pkgs
;
inherit (build) bootstrapFiles;
}

View File

@@ -0,0 +1,297 @@
{
lib,
stdenv,
bashNonInteractive,
bzip2,
coreutils,
cpio,
curlMinimal,
darwin,
diffutils,
dumpnar,
findutils,
gawk,
gettext,
gmpxx,
gnugrep,
gnumake,
gnused,
gnutar,
gzip,
jq,
ld64,
libffi,
libiconv,
libxml2,
llvmPackages,
ncurses,
nukeReferences,
oniguruma,
openssl,
patch,
pbzx,
runCommand,
writeText,
xarMinimal,
xz,
zlib,
}:
stdenv.mkDerivation (finalAttrs: {
name = "stdenv-bootstrap-tools";
nativeBuildInputs = [
dumpnar
nukeReferences
];
buildCommand =
let
inherit (lib) getBin getDev getLib;
coreutils_ =
(coreutils.override (prevArgs: {
# We want coreutils without ACL support.
aclSupport = false;
# Cannot use a single binary build, or it gets dynamically linked against gmp.
singleBinary = false;
})).overrideAttrs
(prevAttrs: {
# Increase header size to be able to inject extra RPATHs. Otherwise
# x86_64-darwin build fails as:
# https://cache.nixos.org/log/g5wyq9xqshan6m3kl21bjn1z88hx48rh-stdenv-bootstrap-tools.drv
NIX_LDFLAGS = (prevAttrs.NIX_LDFLAGS or "") + " -headerpad_max_install_names";
});
# Avoid messing with libkrb5 and libnghttp2.
curl_ = curlMinimal.override (prevArgs: {
gssSupport = false;
http2Support = false;
scpSupport = false;
});
unpackScript = writeText "bootstrap-tools-unpack.sh" ''
set -euo pipefail
echo Unpacking the bootstrap tools... >&2
mkdir $out
tar xf "$1" -C $out
updateInstallName() {
local path="$1"
cp "$path" "$path.new"
install_name_tool -id "$path" "$path.new"
codesign -f -i "$(basename "$path")" -s - "$path.new"
mv -f "$path.new" "$path"
}
find $out/lib -type f -name '*.dylib' -print0 | while IFS= read -r -d $'\0' lib; do
updateInstallName "$lib"
done
# as is a wrapper around clang. need to replace the nuked store paths
sed -i 's|/.*/bin/|'"$out"'/bin/|' $out/bin/as
# Provide a gunzip script.
cat > $out/bin/gunzip <<EOF
#!$out/bin/sh
exec $out/bin/gzip -d "\$@"
EOF
chmod +x $out/bin/gunzip
# Provide fgrep/egrep.
echo "#! $out/bin/sh" > $out/bin/egrep
echo "exec $out/bin/grep -E \"\$@\"" >> $out/bin/egrep
echo "#! $out/bin/sh" > $out/bin/fgrep
echo "exec $out/bin/grep -F \"\$@\"" >> $out/bin/fgrep
cat >$out/bin/dsymutil << EOF
#!$out/bin/sh
EOF
chmod +x $out/bin/egrep $out/bin/fgrep $out/bin/dsymutil
'';
in
''
mkdir -p $out/bin $out/include $out/lib $out/lib/darwin
chmod -R u+w $out/include
cp -rL ${getDev libiconv}/include/* $out/include
cp -rL ${getDev gnugrep.pcre2}/include/* $out/include
# Copy binutils.
for i in as ld ar ranlib nm strip otool install_name_tool lipo codesign_allocate; do
cp ${getBin darwin.binutils-unwrapped}/bin/$i $out/bin
done
cp -d ${getLib ld64}/lib/libcodedirectory*.dylib $out/lib
# Copy coreutils, bash, etc.
cp ${getBin coreutils_}/bin/* $out/bin
(cd $out/bin && rm vdir dir sha*sum pinky factor pathchk runcon shuf who whoami shred users)
cp -d ${getBin bashNonInteractive}/bin/{ba,}sh $out/bin
cp -d ${getBin diffutils}/bin/* $out/bin
cp ${getBin findutils}/bin/{find,xargs} $out/bin
cp -d ${getBin gawk}/bin/{g,}awk $out/bin
cp -d ${getBin gnugrep}/bin/grep $out/bin
cp -d ${getBin gnumake}/bin/* $out/bin
cp -d ${getBin gnused}/bin/* $out/bin
cp -d ${getBin patch}/bin/* $out/bin
cp -d ${getLib gettext}/lib/libintl*.dylib $out/lib
cp -d ${getLib gnugrep.pcre2}/lib/libpcre2*.dylib $out/lib
cp -d ${getLib libiconv}/lib/lib*.dylib $out/lib
cp -d ${getLib libxml2}/lib/libxml2*.dylib $out/lib
cp -d ${getLib ncurses}/lib/libncurses*.dylib $out/lib
# copy package extraction tools
cp -d ${getBin bzip2}/bin/b{,un}zip2 $out/bin
cp ${getBin cpio}/bin/cpio $out/bin
cp ${getBin gnutar}/bin/tar $out/bin
cp ${getBin gzip}/bin/.gzip-wrapped $out/bin/gzip
cp ${getBin pbzx}/bin/pbzx $out/bin
cp ${getBin xz}/bin/xz $out/bin
cp -d ${getLib bzip2}/lib/libbz2*.dylib $out/lib
cp -d ${getLib gmpxx}/lib/libgmp*.dylib $out/lib
cp -d ${getLib xarMinimal}/lib/libxar*.dylib $out/lib
cp -d ${getLib xz}/lib/liblzma*.dylib $out/lib
cp -d ${getLib zlib}/lib/libz*.dylib $out/lib
# This used to be in-nixpkgs, but now is in the bundle
# because I can't be bothered to make it partially static
cp ${getBin curl_}/bin/curl $out/bin
cp -d ${getLib curl_}/lib/libcurl*.dylib $out/lib
cp -d ${getLib openssl}/lib/*.dylib $out/lib
# Copy what we need of clang
cp -d ${getBin llvmPackages.clang-unwrapped}/bin/clang{,++,-cl,-cpp,-[0-9]*} $out/bin
cp -d ${getLib llvmPackages.clang-unwrapped}/lib/libclang-cpp*.dylib $out/lib
cp -rd ${getLib llvmPackages.clang-unwrapped}/lib/clang $out/lib
cp -d ${getLib llvmPackages.libcxx}/lib/libc++*.dylib $out/lib
mkdir -p $out/lib/darwin
cp -d ${getLib llvmPackages.compiler-rt}/lib/darwin/libclang_rt.{,profile_}osx.a $out/lib/darwin
cp -d ${getLib llvmPackages.compiler-rt}/lib/libclang_rt.{,profile_}osx.a $out/lib
cp -d ${getLib llvmPackages.llvm}/lib/libLLVM.dylib $out/lib
cp -d ${getLib libffi}/lib/libffi*.dylib $out/lib
cp -rd ${getDev llvmPackages.libcxx}/include/c++ $out/include
# Copy tools needed to build the SDK
cp -d ${getBin jq}/bin/* $out/bin
cp -d ${getBin llvmPackages.llvm}/bin/llvm-readtapi $out/bin
cp -d ${getLib jq}/lib/lib*.dylib $out/lib
cp -d ${getLib oniguruma}/lib/lib*.dylib $out/lib
# copy sigtool
cp -d ${getBin darwin.sigtool}/bin/{codesign,sigtool} $out/bin
# tools needed to unpack bootstrap archive
mkdir -p unpack/bin unpack/lib
cp -d ${getBin bashNonInteractive}/bin/{ba,}sh unpack/bin
cp ${getBin coreutils_}/bin/mkdir unpack/bin
cp ${getBin gnutar}/bin/tar unpack/bin
cp ${getBin xz}/bin/xz unpack/bin
cp -d ${getLib gettext}/lib/libintl*.dylib unpack/lib
cp -d ${getLib libiconv}/lib/lib*.dylib unpack/lib
cp -d ${getLib xz}/lib/liblzma*.dylib unpack/lib
cp ${unpackScript} unpack/bootstrap-tools-unpack.sh
#
# All files copied. Perform processing to update references to point into
# the archive
#
chmod -R u+w $out unpack
# - change nix store library paths to use @rpath/library
# - if needed add an rpath containing lib/
# - strip executable
rpathify() {
local libs=$(${stdenv.cc.targetPrefix}otool -L "$1" | tail -n +2 | grep -o "$NIX_STORE.*-\S*" || true)
local lib rpath
for lib in $libs; do
${stdenv.cc.targetPrefix}install_name_tool -change $lib "@rpath/$(basename "$lib")" "$1"
done
case "$(dirname "$1")" in
*/bin)
# Strip executables even further
${stdenv.cc.targetPrefix}strip "$i"
rpath='@executable_path/../lib'
;;
*/lib)
# the '/.' suffix is required
rpath='@loader_path/.'
;;
*/lib/darwin)
rpath='@loader_path/..'
;;
*)
echo unknown executable $1 >&2
exit 1
;;
esac
# if shared object contains references add an rpath to lib/
if ${stdenv.cc.targetPrefix}otool -l "$1"| grep -q '@rpath/'; then
${stdenv.cc.targetPrefix}install_name_tool -add_rpath "$rpath" "$1"
fi
}
# check that linked library paths exist in lib
# must be run after rpathify is performed
checkDeps() {
local deps=$(${stdenv.cc.targetPrefix}otool -l "$1"| grep -o '@rpath/[^ ]*' || true)
local lib
shopt -s extglob
for lib in $deps; do
local root="''${1/\/@(lib|bin)\/*}"
if [[ ! -e $root/''${lib/@rpath/lib} ]]; then
echo "error: $1 missing lib for $lib" >&2
exit 1
fi
done
shopt -u extglob
}
for i in {unpack,$out}/bin/* {unpack,$out}/lib{,/darwin}/*.dylib; do
if [[ ! -L $i ]] && isMachO "$i"; then
rpathify "$i"
checkDeps "$i"
fi
done
nuke-refs {unpack,$out}/bin/*
nuke-refs {unpack,$out}/lib/*
nuke-refs $out/lib/darwin/*
mkdir $out/.pack
mv $out/* $out/.pack
mv $out/.pack $out/pack
mkdir $out/on-server
cp -r unpack $out
XZ_OPT="-9 -T $NIX_BUILD_CORES" tar cvJf $out/on-server/bootstrap-tools.tar.xz \
--hard-dereference --sort=name --numeric-owner --owner=0 --group=0 --mtime=@1 -C $out/pack .
dumpnar $out/unpack | xz -9 -T $NIX_BUILD_CORES > $out/on-server/unpack.nar.xz
'';
allowedReferences = [ ];
passthru = {
bootstrapFiles = {
bootstrapTools = "${finalAttrs.finalPackage}/on-server/bootstrap-tools.tar.xz";
unpack = runCommand "unpack" { allowedReferences = [ ]; } ''
cp -r ${finalAttrs.finalPackage}/unpack $out
'';
};
};
meta = {
teams = [ lib.teams.darwin ];
};
})

View File

@@ -0,0 +1,92 @@
{
lib,
stdenv,
apple-sdk,
bootstrapTools,
hello,
}:
derivation {
name = "test-bootstrap-tools";
inherit (stdenv.hostPlatform) system;
builder = "${bootstrapTools}/bin/bash";
args = [
"-euo"
"pipefail"
"-c"
"eval \"$buildCommand\""
];
PATH = lib.makeBinPath [ bootstrapTools ];
tools = bootstrapTools;
"${stdenv.cc.darwinMinVersionVariable}" = stdenv.cc.darwinMinVersion;
# Create a pure environment where we use just what's in the bootstrap tools.
buildCommand = ''
mkdir -p $out/bin
for exe in $tools/bin/*; do
[[ $exe =~ bunzip2|codesign.*|false|install_name_tool|ld|lipo|pbzx|ranlib|sigtool ]] && continue
$exe --version > /dev/null || { echo $exe failed >&2; exit 1; }
done
# run all exes that don't take a --version flag
bunzip2 -h
codesign --help
codesign_allocate -i $tools/bin/true -r -o true
false || (($? == 1))
install_name_tool -id true true
ld -v
lipo -info true
pbzx -v
# ranlib gets tested bulding hello
sigtool -h
rm true
# 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
# The stdenv bootstrap builds the SDK in the bootstrap. Use an existing SDK to test the tools.
export SDKROOT='${apple-sdk.sdkroot}'
export resource_dir="$(echo "$tools"/lib/clang/*)" # Expand wildcard
export flags="-resource-dir=$resource_dir -idirafter $SDKROOT/usr/include --sysroot=$SDKROOT -L$SDKROOT/usr/lib -L$tools/lib -DTARGET_OS_IPHONE=0"
export CPP="clang -E $flags"
export CC="clang $flags"
export CXX="clang++ $flags --stdlib=libc++ -isystem$tools/include/c++/v1"
echo '#include <stdio.h>' >> hello1.c
echo '#include <float.h>' >> hello1.c
echo '#include <limits.h>' >> hello1.c
echo 'int main() { printf("Hello World\n"); return 0; }' >> hello1.c
$CC -o $out/bin/hello1 hello1.c
$out/bin/hello1
echo '#include <iostream>' >> hello3.cc
echo 'int main() { std::cout << "Hello World\n"; }' >> hello3.cc
$CXX -v -o $out/bin/hello3 hello3.cc
$out/bin/hello3
# test that libc++.dylib rpaths are correct so it can reference libc++abi.dylib when linked.
# using -Wl,-flat_namespace is required to generate an error
mkdir libtest/
ln -s $tools/lib/libc++.dylib libtest/
clang++ -Wl,-flat_namespace -resource-dir=$resource_dir -idirafter $SDKROOT/usr/include -isystem$tools/include/c++/v1 \
--sysroot=$SDKROOT -L$SDKROOT/usr/lib -L./libtest -L$PWD/libSystem-boot hello3.cc
tar xvf ${hello.src}
cd hello-*
# hello configure detects -liconv is needed but doesn't add to the link step
LDFLAGS=-liconv ./configure --prefix=$out
make
make install
$out/bin/hello
'';
}

61
pkgs/stdenv/default.nix Normal file
View File

@@ -0,0 +1,61 @@
# 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;
stagesDarwin = import ./darwin args;
stagesCross = import ./cross args;
stagesCustom = import ./custom args;
in
# Select the appropriate stages for the platform `system'.
if crossSystem != localSystem || crossOverlays != [ ] then
stagesCross
else if config ? replaceStdenv then
stagesCustom
else if localSystem.isLinux then
stagesLinux
else if localSystem.isDarwin then
stagesDarwin
# misc special cases
else
{
# switch
x86_64-solaris = stagesNix;
i686-cygwin = stagesNative;
x86_64-cygwin = stagesNative;
x86_64-freebsd = stagesFreeBSD;
}
.${localSystem.system} or stagesNative

View File

@@ -0,0 +1,5 @@
fixupOutputHooks+=(_FreeBSDPatchelfShrink)
_FreeBSDPatchelfShrink() {
find $prefix -type f | xargs -n1 patchelf --shrink-rpath &>/dev/null || true
}

View File

@@ -0,0 +1,22 @@
# Autogenerated by maintainers/scripts/bootstrap-files/refresh-tarballs.bash as:
# $ ./refresh-tarballs.bash --targets=x86_64-unknown-freebsd
#
# Metadata:
# - nixpkgs revision: b92edf1104c47016385e85c87c2d953cf5cd2f98
# - hydra build: https://hydra.nixos.org/job/nixpkgs/cross-trunk/bootstrapTools.x86_64-unknown-freebsd.build/latest
# - resolved hydra build: https://hydra.nixos.org/build/276943819
# - instantiated derivation: /nix/store/npq4w33g3a2gcgh1q535gj4ixd1g5ksl-build.drv
# - output directory: /nix/store/yy36y5s9i4wl768imwfn112sb7w3pyk8-build
# - build time: Thu, 31 Oct 2024 20:57:22 +0000
{
bootstrapTools = import <nix/fetchurl.nix> {
url = "http://tarballs.nixos.org/stdenv/x86_64-unknown-freebsd/b92edf1104c47016385e85c87c2d953cf5cd2f98/bootstrap-tools.tar.xz";
hash = "sha256-oHLddpWWwe/ixYuf3hQfmGrGuixF3+G8HCm+B7g3CzY=";
};
unpack = import <nix/fetchurl.nix> {
url = "http://tarballs.nixos.org/stdenv/x86_64-unknown-freebsd/b92edf1104c47016385e85c87c2d953cf5cd2f98/unpack.nar.xz";
hash = "sha256-aR3lz35Y3ppJBG0/WAT8avsUeDgNMejhGf9LRxTiScI=";
name = "unpack";
unpack = true;
};
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,596 @@
# afaik the longest dependency chain is stdenv -> stdenv-1#coreutils -> stdenv-1#gmp -> stdenv-0#libcxx -> stdenv-0#libc
# this is only possible through aggressive hacking to make libcxx build with stdenv-0#libc instead of bootstrapTools.libc.
{
lib,
localSystem,
crossSystem,
config,
overlays,
crossOverlays ? [ ],
bootstrapFiles ?
let
table = {
x86_64-freebsd = import ./bootstrap-files/x86_64-unknown-freebsd.nix;
};
files =
table.${localSystem.system}
or (throw "unsupported platform ${localSystem.system} for the pure FreeBSD stdenv");
in
files,
}:
assert crossSystem == localSystem;
let
inherit (localSystem) system;
mkExtraBuildCommands0 = cc: ''
rsrc="$out/resource-root"
mkdir "$rsrc"
ln -s "${lib.getLib cc}/lib/clang/${lib.versions.major cc.version}/include" "$rsrc"
echo "-resource-dir=$rsrc" >> $out/nix-support/cc-cflags
'';
mkExtraBuildCommands =
cc: compiler-rt:
mkExtraBuildCommands0 cc
+ ''
ln -s "${compiler-rt.out}/lib" "$rsrc/lib"
ln -s "${compiler-rt.out}/share" "$rsrc/share"
'';
bootstrapArchive = (
derivation {
inherit system;
name = "bootstrap-archive";
pname = "bootstrap-archive";
version = "9.9.9";
builder = "${bootstrapFiles.unpack}/libexec/ld-elf.so.1";
args = [
"${bootstrapFiles.unpack}/bin/bash"
./unpack-bootstrap-files.sh
];
LD_LIBRARY_PATH = "${bootstrapFiles.unpack}/lib";
src = bootstrapFiles.unpack;
inherit (bootstrapFiles) bootstrapTools;
}
);
linkBootstrap = (
attrs:
derivation (
attrs
// {
inherit system;
name = attrs.name or (baseNameOf (builtins.elemAt attrs.paths 0));
src = bootstrapArchive;
builder = "${bootstrapArchive}/bin/bash";
# this script will prefer to link files instead of copying them.
# this prevents clang in particular, but possibly others, from calling readlink(argv[0])
# and obtaining dependencies, ld(1) in particular, from there instead of $PATH.
args = [ ./linkBootstrap.sh ];
PATH = "${bootstrapArchive}/bin";
paths = attrs.paths;
}
)
);
# commented linkBootstrap entries are provided but unused
bootstrapTools = {
expand-response-params = "";
bsdcp = linkBootstrap { paths = [ "bin/bsdcp" ]; };
patchelf = linkBootstrap { paths = [ "bin/patchelf" ]; };
bashNonInteractive = linkBootstrap {
paths = [
"bin/bash"
"bin/sh"
];
shell = "bin/bash";
shellPath = "/bin/bash";
};
curl = linkBootstrap {
paths = [
"bin/curl"
];
};
llvmPackages = {
clang-unwrapped = linkBootstrap {
paths = [
"bin/clang"
"bin/clang++"
"bin/cpp"
"lib/clang"
];
# SYNCME: this version number must be synced with the one in make-bootstrap-tools.nix
version = "18";
};
libunwind = linkBootstrap {
name = "libunwind";
paths = [
"lib/libunwind.a"
"lib/libunwind.so"
"lib/libunwind.so.1"
"lib/libunwind.so.1.0"
"lib/libunwind_shared.so"
];
};
};
coreutils = linkBootstrap {
name = "coreutils";
paths = map (str: "bin/" + str) [
"base64"
"basename"
"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"
"groups"
"head"
"hostid"
"id"
"install"
"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"
"shred"
"shuf"
"sleep"
"sort"
"split"
"stat"
"stdbuf"
"stty"
"sum"
"tac"
"tail"
"tee"
"test"
"timeout"
"touch"
"tr"
"true"
"truncate"
"tsort"
"tty"
"uname"
"unexpand"
"uniq"
"unlink"
"users"
"vdir"
"wc"
"who"
"whoami"
"yes"
"["
];
};
diffutils = linkBootstrap {
name = "diffutils";
paths = map (str: "bin/" + str) [
"diff"
"cmp"
#"diff3"
#"sdiff"
];
};
findutils = linkBootstrap {
name = "findutils";
paths = [
"bin/find"
"bin/xargs"
];
};
iconv = linkBootstrap { paths = [ "bin/iconv" ]; };
libiconv = linkBootstrap { paths = [ "include/iconv.h" ]; };
patch = linkBootstrap { paths = [ "bin/patch" ]; };
gnutar = linkBootstrap { paths = [ "bin/tar" ]; };
gawk = linkBootstrap {
paths = [
"bin/awk"
"bin/gawk"
];
};
gnumake = linkBootstrap { paths = [ "bin/make" ]; };
gnugrep = linkBootstrap {
paths = [
"bin/grep"
"bin/egrep"
"bin/fgrep"
];
};
gnused = linkBootstrap { paths = [ "bin/sed" ]; };
gzip = linkBootstrap {
paths = [
"bin/gzip"
#"bin/gunzip"
];
};
bzip2 = linkBootstrap {
paths = [
"bin/bzip2"
"lib/libbz2.so"
"lib/libbz2.so.1"
];
};
xz = linkBootstrap {
paths = [
"bin/xz"
"bin/unxz"
"lib/liblzma.so"
"lib/liblzma.so.5"
];
};
binutils-unwrapped = linkBootstrap {
name = "binutils";
paths = map (str: "bin/" + str) [
"ld"
#"as"
#"addr2line"
"ar"
#"c++filt"
#"elfedit"
#"gprof"
#"objdump"
"nm"
"objcopy"
"ranlib"
"readelf"
"size"
"strings"
"strip"
];
};
freebsd = {
locales = linkBootstrap { paths = [ "share/locale" ]; };
libc = linkBootstrap {
name = "bootstrapLibs";
paths = [
"lib/Scrt1.o"
"lib/crt1.o"
"lib/crtbegin.o"
"lib/crtbeginS.o"
"lib/crtbeginT.o"
"lib/crtend.o"
"lib/crtendS.o"
"lib/crti.o"
"lib/crtn.o"
"lib/libc++.a"
"lib/libc++.so"
"lib/libc++.so.1"
"lib/libc.a"
"lib/libc.so"
"lib/libc.so.7"
"lib/libc_nonshared.a"
"lib/libcrypt.so"
"lib/libcrypt.so.5"
"lib/libcxxrt.a"
"lib/libcxxrt.so"
"lib/libcxxrt.so.1"
"lib/libdevstat.so"
"lib/libdevstat.so.7"
"lib/libdl.so"
"lib/libdl.so.1"
"lib/libelf.so"
"lib/libelf.so.2"
"lib/libexecinfo.so"
"lib/libexecinfo.so.1"
"lib/libgcc.a"
"lib/libgcc_eh.a"
"lib/libgcc_s.so"
"lib/libgcc_s.so.1"
"lib/libkvm.so"
"lib/libkvm.so.7"
"lib/libm.a"
"lib/libm.so"
"lib/libm.so.5"
"lib/libmd.so"
"lib/libmd.so.6"
"lib/libncurses.so"
"lib/libncurses.so.6"
"lib/libncursesw.so"
"lib/libncursesw.so.6"
"lib/libpthread.so"
"lib/librt.so"
"lib/librt.so.1"
"lib/libthr.so"
"lib/libthr.so.3"
"lib/libutil.so"
"lib/libutil.so.9"
"lib/libxnet.so"
"include"
"share"
"libexec"
];
pname = "libs";
version = "bootstrap";
};
};
};
mkStdenv =
{
name ? "freebsd",
overrides ?
prevStage: super: self:
{ },
hascxx ? true,
}:
prevStage:
let
bsdcp =
prevStage.bsdcp or (prevStage.runCommand "bsdcp" { }
"mkdir -p $out/bin; cp ${prevStage.freebsd.cp}/bin/cp $out/bin/bsdcp"
);
initialPath = with prevStage; [
coreutils
gnutar
findutils
gnumake
gnused
patchelf
gnugrep
gawk
diffutils
patch
bashNonInteractive
xz
gzip
bzip2
bsdcp
];
shell = "${prevStage.bashNonInteractive}/bin/bash";
stdenvNoCC = import ../generic {
inherit
config
initialPath
shell
fetchurlBoot
;
name = "stdenvNoCC-${name}";
buildPlatform = localSystem;
hostPlatform = localSystem;
targetPlatform = localSystem;
cc = null;
};
fetchurlBoot = import ../../build-support/fetchurl {
inherit lib stdenvNoCC;
inherit (prevStage) curl;
inherit (config) hashedMirrors rewriteURL;
};
stdenv = import ../generic {
inherit
config
initialPath
shell
fetchurlBoot
;
name = "stdenv-${name}";
buildPlatform = localSystem;
hostPlatform = localSystem;
targetPlatform = localSystem;
extraNativeBuildInputs = [
./unpack-source.sh
./always-patchelf.sh
];
cc = lib.makeOverridable (import ../../build-support/cc-wrapper) {
inherit lib stdenvNoCC;
name = "${name}-cc";
inherit (prevStage.freebsd) libc;
inherit (prevStage) gnugrep coreutils expand-response-params;
libcxx = prevStage.llvmPackages.libcxx or null;
runtimeShell = shell;
propagateDoc = false;
nativeTools = false;
nativeLibc = false;
cc = prevStage.llvmPackages.clang-unwrapped;
isClang = true;
extraPackages = lib.optionals hascxx [
prevStage.llvmPackages.compiler-rt
];
nixSupport = {
libcxx-cxxflags = lib.optionals (!hascxx) [ "-isystem ${prevStage.freebsd.libc}/include/c++/v1" ];
};
extraBuildCommands = lib.optionalString hascxx (
mkExtraBuildCommands prevStage.llvmPackages.clang-unwrapped prevStage.llvmPackages.compiler-rt
);
bintools = lib.makeOverridable (import ../../build-support/bintools-wrapper) {
inherit lib stdenvNoCC;
name = "${name}-bintools";
inherit (prevStage.freebsd) libc;
inherit (prevStage) gnugrep coreutils expand-response-params;
runtimeShell = shell;
bintools = (prevStage.llvmPackages or { }).bintools-unwrapped or prevStage.binutils-unwrapped;
propagateDoc = false;
nativeTools = false;
nativeLibc = false;
};
};
overrides = overrides prevStage;
preHook = ''
export NIX_ENFORCE_PURITY="''${NIX_ENFORCE_PURITY-1}"
export NIX_ENFORCE_NO_NATIVE="''${NIX_ENFORCE_NO_NATIVE-1}"
export PATH_LOCALE=${prevStage.freebsd.localesReal or prevStage.freebsd.locales}/share/locale
''
+ lib.optionalString (prevStage.freebsd ? libiconvModules) ''
export PATH_I18NMODULE=${prevStage.freebsd.libiconvModules}/lib/i18n
'';
};
in
{
inherit config overlays stdenv;
};
in
[
(
{ }:
mkStdenv {
name = "freebsd-boot-0";
hascxx = false;
overrides = prevStage: self: super: {
# this one's goal is to build foundational libs like libc and libcxx. we want to override literally every possible bin package we can with bootstrap tools
# we CAN'T import LLVM because the compiler built here is used to build the final compiler and the final compiler must not be built by the bootstrap compiler
inherit (bootstrapTools)
patchelf
bashNonInteractive
curl
coreutils
diffutils
findutils
iconv
libiconv
patch
gnutar
gawk
gnumake
gnugrep
gnused
gzip
bzip2
xz
;
binutils-unwrapped = removeAttrs bootstrapTools.binutils-unwrapped [ "src" ];
fetchurl = import ../../build-support/fetchurl {
inherit lib;
inherit (self) stdenvNoCC;
inherit (prevStage) curl;
inherit (config) hashedMirrors rewriteURL;
};
gettext = super.gettext.overrideAttrs {
NIX_CFLAGS_COMPILE = "-DHAVE_ICONV=1"; # we clearly have iconv. what do you want?
};
curlReal = super.curl;
tzdata = super.tzdata.overrideAttrs { NIX_CFLAGS_COMPILE = "-DHAVE_GETTEXT=0"; };
# make it so libcxx/libunwind are built in this stdenv and not the next
freebsd = super.freebsd.overrideScope (
self': super': {
inherit (prevStage.freebsd) locales;
stdenvNoLibcxx = self.overrideCC (self.stdenv // { name = "stdenv-freebsd-boot-0.4"; }) (
self.stdenv.cc.override {
name = "freebsd-boot-0.4-cc";
libc = self.freebsd.libc;
bintools = self.stdenv.cc.bintools.override {
name = "freebsd-boot-0.4-bintools";
libc = self.freebsd.libc;
};
}
);
}
);
llvmPackages = super.llvmPackages // {
libcxx =
(super.llvmPackages.libcxx.override {
stdenv = self.overrideCC (self.stdenv // { name = "stdenv-freebsd-boot-0.5"; }) (
self.stdenv.cc.override {
name = "freebsd-boot-0.5-cc";
libc = self.freebsd.libc;
bintools = self.stdenv.cc.bintools.override {
name = "freebsd-boot-0.5-bintools";
libc = self.freebsd.libc;
};
extraPackages = [
self.llvmPackages.compiler-rt
];
extraBuildCommands = mkExtraBuildCommands self.llvmPackages.clang-unwrapped self.llvmPackages.compiler-rt;
}
);
}).overrideAttrs
(
self': super': {
NIX_CFLAGS_COMPILE = "-nostdlib++";
NIX_LDFLAGS = "--allow-shlib-undefined";
cmakeFlags = builtins.filter (x: x != "-DCMAKE_SHARED_LINKER_FLAGS=-nostdlib") super'.cmakeFlags;
}
);
};
};
} bootstrapTools
)
(mkStdenv {
name = "freebsd-boot-1";
overrides = prevStage: self: super: {
# this one's goal is to build all the tools that get imported into the final stdenv.
# we can import the foundational libs from boot-0
# we can import bins and libs that DON'T get imported OR LINKED into the final stdenv from boot-0
curl = prevStage.curlReal;
inherit (prevStage)
fetchurl
python3
bison
perl
cmake
ninja
;
fetchurlReal = super.fetchurl;
freebsd = super.freebsd.overrideScope (
self': super': {
locales = prevStage.freebsd.locales;
localesReal = super'.locales;
libc = prevStage.freebsd.libc;
}
);
llvmPackages = super.llvmPackages // {
libcxx = prevStage.llvmPackages.libcxx;
};
};
})
(mkStdenv {
name = "freebsd";
overrides = prevStage: self: super: {
__bootstrapArchive = bootstrapArchive;
fetchurl = prevStage.fetchurlReal;
freebsd = super.freebsd.overrideScope (
self': super': { localesPrev = prevStage.freebsd.localesReal; }
);
};
})
]

View File

@@ -0,0 +1,14 @@
#!/usr/bin/env bash
for path in $paths; do
if ! [ -e "$src/$path" ]; then
echo "Error: $path does not exist"
exit 1
fi
mkdir -p $out/$(dirname $path)
if [[ -d $src/$path ]]; then
ln -s $src/$path $out/$path
else
cp -RL $src/$path $out/$path
fi
done

View File

@@ -0,0 +1,30 @@
{
system ? builtins.currentSystem,
}:
let
inherit (releaseLib) lib;
releaseLib = import ../../top-level/release-lib.nix {
# We're not using any functions from release-lib.nix that look at
# supportedSystems.
supportedSystems = [ ];
};
make =
crossSystem:
import ./make-bootstrap-tools.nix {
pkgs = releaseLib.pkgsForCross crossSystem system;
};
in
lib.mapAttrs (n: make) (
with lib.systems.examples;
{
# NOTE: Only add platforms for which there are files in `./bootstrap-files`
# or for which you plan to request the tarball upload soon. See the
# maintainers/scripts/bootstrap-files/README.md
# on how to request an upload.
# Sort following the sorting in `./default.nix` `bootstrapFiles` argument.
x86_64-unknown-freebsd = x86_64-freebsd;
}
)

View File

@@ -0,0 +1,120 @@
{
pkgs ? import ../../.. { },
}:
let
inherit (pkgs) runCommand closureInfo;
# splicing doesn't seem to work right here
inherit (pkgs.buildPackages) dumpnar rsync;
pack-all =
packCmd: name: pkgs: fixups:
(runCommand name
{
nativeBuildInputs = [
rsync
dumpnar
];
}
''
base=$PWD
requisites="$(cat ${closureInfo { rootPaths = pkgs; }}/store-paths)"
for f in $requisites; do
cd $f
rsync --safe-links --chmod="+w" -av . $base
done
cd $base
rm -rf nix nix-support
mkdir nix-support
for dir in $requisites; do
cd "$dir/nix-support" 2>/dev/null || continue
for f in $(find . -type f); do
mkdir -p "$base/nix-support/$(dirname $f)"
cat $f >>"$base/nix-support/$f"
done
done
rm -f $base/nix-support/propagated-build-inputs
cd $base
${fixups}
${packCmd}
''
);
nar-all = pack-all "dumpnar . | xz -9 -e -T $NIX_BUILD_CORES >$out";
tar-all = pack-all "XZ_OPT=\"-9 -e -T $NIX_BUILD_CORES\" tar cJf $out --hard-dereference --sort=name --numeric-owner --owner=0 --group=0 --mtime=@1 .";
coreutils-big = pkgs.coreutils.override { singleBinary = false; };
mkdir = runCommand "mkdir" { coreutils = coreutils-big; } ''
mkdir -p $out/bin
cp $coreutils/bin/mkdir $out/bin
'';
in
rec {
unpack =
nar-all "unpack.nar.xz"
(with pkgs; [
bash
mkdir
xz
gnutar
])
''
rm -rf include lib/*.a lib/i18n lib/bash share
'';
bootstrap-tools = tar-all "bootstrap-tools.tar.xz" (
with pkgs;
# SYNCME: this version number must be synced with the one in default.nix
let
llvmPackages = llvmPackages_18;
in
[
(runCommand "bsdcp" { } "mkdir -p $out/bin; cp ${freebsd.cp}/bin/cp $out/bin/bsdcp")
coreutils
gnutar
findutils
gnumake
gnused
patchelf
gnugrep
gawk
diffutils
patch
bash
xz
xz.dev
gzip
bzip2
bzip2.dev
curl
expand-response-params
binutils-unwrapped
freebsd.libc
llvmPackages.libcxx
llvmPackages.libcxx.dev
llvmPackages.compiler-rt
llvmPackages.compiler-rt.dev
llvmPackages.clang-unwrapped
(freebsd.locales.override { locales = [ "C.UTF-8" ]; })
]
# INSTRUCTIONS FOR GENERATING THE SPURIOUS LIST
# - empty this list
# - rebuild bootstrap files and update their urls and hashes
# - turn on atime on your FreeBSD nix store filesystem
# - run nix-collect-garbage on FreeBSD to make it so we rebuild FODs
# - build the nixpkgs __bootstrapArchive attribute on FreeBSD
# - reboot your FreeBSD system. Otherwise the atimes will simply be wrong because of kernel caching
# - run a full build of stdenv on FreeBSD. with -j3, this takes 1h40 on my 20 cpu VM (AMD host)
# - use the following to generate a list with access times and filenames
# find /nix/store/###-bootstrap-archive -type f | xargs stat | grep -E 'Access: 2|File:' | paste -d ' ' - - | awk '{ print $4 " " $5 " " $6 " " $2 }' | sort -n > atimes
# - manually identify the point where files have no longer been accessed after the patching phase
# - use your favorite text editor to snip out the time column, the /nix/store/###-bootstrap-archive/ prefix, and the files that have not been used during bootstrap
# - turn off atime if it was off before since it will degrade performance
# - manually remove bin/strings from the list, since it will be used only during bootstrap
# - manually remove all files under include and lib/clang/*/include from the list in order to improve forward compatibility (and since they are very small)
# - plop it here
) "xargs rm -f <${./bootstrap-tools-spurious.txt}";
build = runCommand "build" { } ''
mkdir -p $out/on-server
ln -s ${unpack} $out/on-server/unpack.nar.xz
ln -s ${bootstrap-tools} $out/on-server/bootstrap-tools.tar.xz
'';
}

View File

@@ -0,0 +1,57 @@
$src/libexec/ld-elf.so.1 $src/bin/mkdir $out
$src/libexec/ld-elf.so.1 $src/bin/tar -I "$src/libexec/ld-elf.so.1 $src/bin/xz" -C $out -xf $bootstrapTools
export LD_LIBRARY_PATH=$out/lib
BADLIST=ld-elf.so.1
oobpatch() {
$out/libexec/ld-elf.so.1 $src/bin/cp $1 ./tmp
$out/libexec/ld-elf.so.1 $out/bin/patchelf --set-rpath $out/lib --set-interpreter $out/libexec/ld-elf.so.1 ./tmp
$out/libexec/ld-elf.so.1 $src/bin/mv ./tmp $1
BADLIST="$BADLIST|${1##*/}"
}
oobpatch $out/bin/patchelf
oobpatch $out/lib/libthr.so.3
oobpatch $out/lib/libc.so.7
for f in $($out/libexec/ld-elf.so.1 $out/bin/find $out/lib -type f); do
$out/libexec/ld-elf.so.1 $out/bin/grep -E "$BADLIST" <<<"$f" && continue
$out/libexec/ld-elf.so.1 $out/bin/patchelf --set-rpath $out/lib $f
done
for f in $out/bin/* $out/bin/.*; do
$out/libexec/ld-elf.so.1 $out/bin/grep -E "$BADLIST" <<<"$f" &>/dev/null && continue
$out/libexec/ld-elf.so.1 $out/bin/patchelf --set-rpath $out/lib --set-interpreter $out/libexec/ld-elf.so.1 $f
done
unset LD_LIBRARY_PATH
export PATH=$out/bin
# sanity check
$out/bin/true || exit 1
# meticulously replace every nix store path with the right one
# to work with binaries, make sure the path remains the same length by prefixing pathsep chars
for f in $(find $out -type f); do
while true; do
BADMAN="$(strings $f | grep -o '/nix/store/.*' | grep -v "$out" | head -n1)"
if [ -z "$BADMAN" ]; then
break
fi
echo scorch $f
BADMAN="$(echo "$BADMAN" | cut -d/ -f-4)"
GOODMAN="$out"
if [ ${#GOODMAN} -gt ${#BADMAN} ]; then
echo "Can't patch $f: $BADMAN too short"
break
fi
while ! [ ${#GOODMAN} -eq ${#BADMAN} ]; do
GOODMAN="/$GOODMAN"
done
if ! sed -E -i -e "s@$BADMAN@$GOODMAN@g" $f; then
echo "Can't patch $f: sed failed"
break
fi
done
done
echo $out

View File

@@ -0,0 +1,41 @@
unpackCmdHooks+=(_FreeBSDUnpackSource)
_FreeBSDUnpackSource() {
local fn="$1"
local destination
if [ -d "$fn" ]; then
destination="$(stripHash "$fn")"
if [ -e "$destination" ]; then
echo "Cannot copy $fn to $destination: destination already exists!"
echo "Did you specify two \"srcs\" with the same \"name\"?"
return 1
fi
# We can't preserve hardlinks because they may have been
# introduced by store optimization, which might break things
# in the build.
bsdcp -a -- "$fn" "$destination"
chmod -R +w "$destination"
else
case "$fn" in
*.tar.xz | *.tar.lzma | *.txz)
# Don't rely on tar knowing about .xz.
xz -d < "$fn" | tar xf - --warning=no-timestamp
;;
*.tar | *.tar.* | *.tgz | *.tbz2 | *.tbz)
# GNU tar can automatically select the decompression method
# (info "(tar) gzip").
tar xf "$fn" --warning=no-timestamp
;;
*)
return 1
;;
esac
fi
}

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,764 @@
# Checks derivation meta and attrs for problems (like brokenness,
# licenses, etc).
{
lib,
config,
hostPlatform,
}:
let
inherit (lib)
all
attrNames
attrValues
concatMapStrings
concatMapStringsSep
concatStrings
findFirst
isDerivation
length
concatMap
mutuallyExclusive
optional
optionalAttrs
optionalString
optionals
isAttrs
isString
mapAttrs
;
inherit (lib.lists)
any
toList
isList
elem
;
inherit (lib.meta)
availableOn
cpeFullVersionWithVendor
tryCPEPatchVersionInUpdateWithVendor
;
inherit (lib.generators)
toPretty
;
# 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;
getNameWithVersion =
attrs: attrs.name or "${attrs.pname or "«name-missing»"}-${attrs.version or "«version-missing»"}";
allowUnfree = config.allowUnfree || builtins.getEnv "NIXPKGS_ALLOW_UNFREE" == "1";
allowNonSource =
let
envVar = builtins.getEnv "NIXPKGS_ALLOW_NONSOURCE";
in
if envVar != "" then envVar != "0" else config.allowNonSource or true;
allowlist = config.allowlistedLicenses or config.whitelistedLicenses or [ ];
blocklist = config.blocklistedLicenses or config.blacklistedLicenses or [ ];
areLicenseListsValid =
if mutuallyExclusive allowlist blocklist then
true
else
throw "allowlistedLicenses and blocklistedLicenses are not mutually exclusive.";
hasLicense = attrs: attrs ? meta.license;
hasListedLicense =
assert areLicenseListsValid;
list: attrs:
length list > 0
&& hasLicense attrs
&& (
if isList attrs.meta.license then
any (l: elem l list) attrs.meta.license
else
elem attrs.meta.license list
);
hasAllowlistedLicense = attrs: hasListedLicense allowlist attrs;
hasBlocklistedLicense = attrs: hasListedLicense blocklist attrs;
allowBroken = config.allowBroken || builtins.getEnv "NIXPKGS_ALLOW_BROKEN" == "1";
allowUnsupportedSystem =
config.allowUnsupportedSystem || builtins.getEnv "NIXPKGS_ALLOW_UNSUPPORTED_SYSTEM" == "1";
isUnfree =
licenses:
if isAttrs licenses then
!licenses.free or true
# TODO: Returning false in the case of a string is a bug that should be fixed.
# In a previous implementation of this function the function body
# was `licenses: lib.lists.any (l: !l.free or true) licenses;`
# which always evaluates to `!true` for strings.
else if isString licenses then
false
else
any (l: !l.free or true) licenses;
hasUnfreeLicense = attrs: hasLicense attrs && isUnfree attrs.meta.license;
hasNoMaintainers =
# To get usable output, we want to avoid flagging "internal" derivations.
# Because we do not have a way to reliably decide between internal or
# external derivation, some heuristics are required to decide.
#
# If `outputHash` is defined, the derivation is a FOD, such as the output of a fetcher.
# If `description` is not defined, the derivation is probably not a package.
# Simply checking whether `meta` is defined is insufficient,
# as some fetchers and trivial builders do define meta.
attrs:
(!attrs ? outputHash)
&& (attrs ? meta.description)
&& (attrs.meta.maintainers or [ ] == [ ])
&& (attrs.meta.teams or [ ] == [ ]);
isMarkedBroken = attrs: attrs.meta.broken or false;
# Allow granular checks to allow only some broken packages
# Example:
# { pkgs, ... }:
# {
# allowBroken = false;
# allowBrokenPredicate = pkg: builtins.elem (pkgs.lib.getName pkg) [ "hello" ];
# }
allowBrokenPredicate = config.allowBrokenPredicate or (x: false);
hasDeniedBroken =
attrs: (attrs.meta.broken or false) && !allowBroken && !allowBrokenPredicate attrs;
hasUnsupportedPlatform = pkg: !(availableOn hostPlatform pkg);
isMarkedInsecure = attrs: (attrs.meta.knownVulnerabilities or [ ]) != [ ];
# Allow 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 explicitly allowed by the
# `allowUnfreePredicate` function.
hasDeniedUnfreeLicense =
attrs: hasUnfreeLicense attrs && !allowUnfree && !allowUnfreePredicate attrs;
allowInsecureDefaultPredicate =
x: builtins.elem (getNameWithVersion 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: any (t: !t.isSource) sourceTypes;
hasNonSourceProvenance =
attrs: (attrs ? meta.sourceProvenance) && isNonSource 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) 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 v.fullName or "unknown") (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: When using `nix shell`, `nix build`, `nix develop`, etc with a flake,
then pass `--impure` in order to allow use of environment variables.
";
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:
''
+ (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 ${getNameWithVersion attrs} to
`nixpkgs.config.permittedInsecurePackages` in the configuration.nix,
like so:
{
nixpkgs.config.permittedInsecurePackages = [
"${getNameWithVersion attrs}"
];
}
c) For `nix-env`, `nix-build`, `nix-shell` or any other Nix command you can add
${getNameWithVersion attrs} to `permittedInsecurePackages` in
~/.config/nixpkgs/config.nix, like so:
{
permittedInsecurePackages = [
"${getNameWithVersion 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 ${getNameWithVersion attrs} has set meta.outputsToInstall to: ${builtins.concatStringsSep ", " expectedOutputs}
however ${getNameWithVersion attrs} only has the outputs: ${builtins.concatStringsSep ", " actualOutputs}
and is missing the following outputs:
${concatStrings (map (output: " - ${output}\n") missingOutputs)}
'';
handleEvalIssue =
{ meta, attrs }:
{
reason,
errormsg ? "",
}:
let
msg =
if inHydra then
"Failed to evaluate ${getNameWithVersion attrs}: «${reason}»: ${errormsg}"
else
''
Package ${getNameWithVersion 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 ${getNameWithVersion attrs}: «${reason}»: ${errormsg}"
else
"Package ${getNameWithVersion attrs} in ${pos_str meta} ${errormsg}, continuing anyway."
+ (optionalString (remediationMsg != "") "\n${remediationMsg}");
isEnabled = findFirst (x: x == reason) null showWarnings;
in
if isEnabled != null then builtins.trace msg true else true;
metaTypes =
let
types = import ./meta-types.nix { inherit lib; };
inherit (types)
str
union
int
attrs
attrsOf
any
listOf
bool
;
platforms = listOf (union [
str
(attrsOf any)
]); # see lib.meta.platformMatch
in
{
# These keys are documented
description = str;
mainProgram = str;
longDescription = str;
branch = str;
homepage = union [
(listOf str)
str
];
downloadPage = str;
changelog = union [
(listOf str)
str
];
license =
let
# TODO disallow `str` licenses, use a module
licenseType = union [
(attrsOf any)
str
];
in
union [
(listOf licenseType)
licenseType
];
sourceProvenance = listOf attrs;
maintainers = listOf (attrsOf any); # TODO use the maintainer type from lib/tests/maintainer-module.nix
teams = listOf (attrsOf any); # TODO similar to maintainers, use a teams type
priority = int;
pkgConfigModules = listOf str;
inherit platforms;
hydraPlatforms = listOf str;
broken = bool;
unfree = bool;
unsupported = bool;
insecure = bool;
tests = {
name = "test";
verify =
x:
x == { }
||
# Accept {} for tests that are unsupported
(isDerivation x && x ? meta.timeout);
};
timeout = int;
knownVulnerabilities = listOf str;
badPlatforms = platforms;
# Needed for Hydra to expose channel tarballs:
# https://github.com/NixOS/hydra/blob/53335323ae79ca1a42643f58e520b376898ce641/doc/manual/src/jobs.md#meta-fields
isHydraChannel = bool;
# Weirder stuff that doesn't appear in the documentation?
maxSilent = int;
name = str;
version = str;
tag = str;
executables = listOf str;
outputsToInstall = listOf str;
position = str;
available = any;
isBuildPythonPackage = platforms;
schedulingPriority = int;
isFcitxEngine = bool;
isIbusEngine = bool;
isGutenprint = bool;
# Used for the original location of the maintainer and team attributes to assist with pings.
maintainersPosition = any;
teamsPosition = any;
identifiers = attrs;
};
checkMetaAttr =
let
# Map attrs directly to the verify function for performance
metaTypes' = mapAttrs (_: t: t.verify) metaTypes;
in
k: v:
if metaTypes ? ${k} then
if metaTypes'.${k} v then
[ ]
else
[
"key 'meta.${k}' has invalid value; expected ${metaTypes.${k}.name}, got\n ${
toPretty { indent = " "; } v
}"
]
else
[
"key 'meta.${k}' is unrecognized; expected one of: \n [${
concatMapStringsSep ", " (x: "'${x}'") (attrNames metaTypes)
}]"
];
checkMeta =
meta:
optionals config.checkMeta (concatMap (attr: checkMetaAttr attr meta.${attr}) (attrNames meta));
checkOutputsToInstall =
attrs:
let
expectedOutputs = attrs.meta.outputsToInstall or [ ];
actualOutputs = attrs.outputs or [ "out" ];
missingOutputs = builtins.filter (output: !builtins.elem output actualOutputs) expectedOutputs;
in
if config.checkMeta 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: "yes", "warn" or "no" } and additionally
# { reason: String; errormsg: String } if it is not valid, where
# reason is one of "unfree", "blocklisted", "broken", "insecure", ...
# !!! reason strings are hardcoded into OfBorg, make sure to keep them in sync
# Along with a boolean flag for each reason
checkValidity =
let
validYes = {
valid = "yes";
handled = true;
};
in
attrs:
# Check meta attribute types first, to make sure it is always called even when there are other issues
# Note that this is not a full type check and functions below still need to by careful about their inputs!
let
res = checkMeta (attrs.meta or { });
in
if res != [ ] then
{
valid = "no";
reason = "unknown-meta";
errormsg = "has an invalid meta attrset:${concatMapStrings (x: "\n - " + x) res}\n";
}
# --- Put checks that cannot be ignored here ---
else if checkOutputsToInstall attrs then
{
valid = "no";
reason = "broken-outputs";
errormsg = "has invalid meta.outputsToInstall";
}
# --- Put checks that can be ignored here ---
else 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 hasDeniedBroken attrs then
{
valid = "no";
reason = "broken";
errormsg = "is marked as broken";
}
else if !allowUnsupportedSystem && hasUnsupportedPlatform attrs then
let
toPretty' = toPretty {
allowPrettyValues = true;
indent = " ";
};
in
{
valid = "no";
reason = "unsupported";
errormsg = ''
is not available on the requested hostPlatform:
hostPlatform.system = "${hostPlatform.system}"
package.meta.platforms = ${toPretty' (attrs.meta.platforms or [ ])}
package.meta.badPlatforms = ${toPretty' (attrs.meta.badPlatforms or [ ])}
'';
}
else if !(hasAllowedInsecure attrs) then
{
valid = "no";
reason = "insecure";
errormsg = "is marked as insecure";
}
# --- 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 or teams";
}
# -----
else
validYes;
# Helper functions and declarations to handle identifiers, extracted to reduce allocations
hasAllCPEParts =
cpeParts:
let
values = attrValues cpeParts;
in
(length values == 11) && !any isNull values;
makeCPE =
{
part,
vendor,
product,
version,
update,
edition,
sw_edition,
target_sw,
target_hw,
language,
other,
}:
"cpe:2.3:${part}:${vendor}:${product}:${version}:${update}:${edition}:${sw_edition}:${target_sw}:${target_hw}:${language}:${other}";
possibleCPEPartsFuns = [
(vendor: version: {
success = true;
value = cpeFullVersionWithVendor vendor version;
})
tryCPEPatchVersionInUpdateWithVendor
];
# 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.
# Example:
# meta = checkMeta.commonMeta { inherit validity attrs pos references; };
# validity = checkMeta.assertValidity { inherit meta attrs; };
commonMeta =
{
validity,
attrs,
pos ? null,
references ? [ ],
}:
let
outputs = attrs.outputs or [ "out" ];
hasOutput = out: builtins.elem out outputs;
maintainersPosition = builtins.unsafeGetAttrPos "maintainers" (attrs.meta or { });
teamsPosition = builtins.unsafeGetAttrPos "teams" (attrs.meta or { });
in
{
# `name` derivation attribute 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 = [
(
if hasOutput "bin" then
"bin"
else if hasOutput "out" then
"out"
else
findFirst hasOutput null outputs
)
]
++ optional (hasOutput "man") "man";
# CI scripts look at these to determine pings. Note that we should filter nulls out of this,
# or nix-env complains: https://github.com/NixOS/nix/blob/2.18.8/src/nix-env/nix-env.cc#L963
${if maintainersPosition == null then null else "maintainersPosition"} = maintainersPosition;
${if teamsPosition == null then null else "teamsPosition"} = teamsPosition;
}
// attrs.meta or { }
// {
# Fill `meta.position` to identify the source location of the package.
${if pos == null then null else "position"} = pos.file + ":" + toString pos.line;
# Maintainers should be inclusive of teams.
# Note that there may be external consumers of this API (repology, for instance) -
# if you add a new maintainer or team attribute please ensure that this expectation is still met.
maintainers =
attrs.meta.maintainers or [ ] ++ concatMap (team: team.members or [ ]) attrs.meta.teams or [ ];
identifiers =
let
# nix-env writes a warning for each derivation that has null in its meta values, so
# fields without known values are removed from the result
defaultCPEParts = {
part = "a";
#vendor = null;
${if attrs ? pname then "product" else null} = attrs.pname;
#version = null;
#update = null;
edition = "*";
sw_edition = "*";
target_sw = "*";
target_hw = "*";
language = "*";
other = "*";
};
cpeParts = defaultCPEParts // attrs.meta.identifiers.cpeParts or { };
cpe = if hasAllCPEParts cpeParts then makeCPE cpeParts else null;
possibleCPEs =
if cpe != null then
[ { inherit cpeParts cpe; } ]
else if attrs.meta.identifiers.cpeParts.vendor or null == null || attrs.version or null == null then
[ ]
else
concatMap (
f:
let
result = f attrs.meta.identifiers.cpeParts.vendor attrs.version;
# Note that attrs.meta.identifiers.cpeParts at this point can include defaults with user overrides.
# Since we can't split them apart, user overrides don't apply to possibleCPEs.
guessedParts = cpeParts // result.value;
in
optional (result.success && hasAllCPEParts guessedParts) {
cpeParts = guessedParts;
cpe = makeCPE guessedParts;
}
) possibleCPEPartsFuns;
v1 = {
inherit cpeParts possibleCPEs;
${if cpe != null then "cpe" else null} = cpe;
};
in
v1
// {
inherit v1;
};
# Expose the result of the checks for everyone to see.
unfree = hasUnfreeLicense attrs;
broken = isMarkedBroken attrs;
unsupported = hasUnsupportedPlatform attrs;
insecure = isMarkedInsecure attrs;
available =
validity.valid != "no"
&& (
if config.checkMetaRecursively or false then all (d: d.meta.available or true) references else true
);
};
assertValidity =
{ meta, attrs }:
let
validity = checkValidity attrs;
inherit (validity) valid;
in
if validity ? handled then
validity
else
validity
// {
# Throw an error if trying to evaluate a non-valid derivation
# or, alternatively, just output a warning message.
handled = (
if valid == "yes" then
true
else if valid == "no" then
(handleEvalIssue { inherit meta attrs; } { inherit (validity) reason errormsg; })
else if valid == "warn" then
(handleEvalWarning { inherit meta attrs; } { inherit (validity) reason errormsg; })
else
throw "Unknown validity: '${valid}'"
);
};
in
{
inherit assertValidity commonMeta;
}

View File

@@ -0,0 +1,24 @@
{ pkgs }:
[
pkgs.coreutils
pkgs.findutils
pkgs.diffutils
pkgs.gnused
pkgs.gnugrep
pkgs.gawk
pkgs.gnutar
pkgs.gzip
pkgs.bzip2.bin
pkgs.gnumake
pkgs.bashNonInteractive
pkgs.patch
pkgs.xz.bin
# The `file` command is added here because an enormous number of
# packages have a vendored dependency upon `file` in their
# `./configure` script, due to libtool<=2.4.6, or due to
# libtool>=2.4.7 in which the package author decided to set FILECMD
# when running libtoolize. In fact, file-5.4.6 *depends on itself*
# and tries to invoke `file` from its own ./configure script.
pkgs.file
]

View File

@@ -0,0 +1 @@
genericBuild

View File

@@ -0,0 +1,229 @@
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 definitely have `cc !=
# null`.
#
# TODO(@Ericson2314): Add assert without creating infinite recursion
hasCC ? cc != null,
cc,
shell,
allowedRequisites ? null,
extraAttrs ? { },
overrides ? (self: super: { }),
config,
disallowedRequisites ? [ ],
# 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 convenient to have as a parameter so the stdenv "adapters" work better
mkDerivationFromStdenv ?
stdenv: (import ./make-derivation.nix { inherit lib config; } stdenv).mkDerivation,
}:
let
defaultNativeBuildInputs =
extraNativeBuildInputs
++ [
../../build-support/setup-hooks/no-broken-symlinks.sh
../../build-support/setup-hooks/audit-tmpdir.sh
../../build-support/setup-hooks/compress-man-pages.sh
../../build-support/setup-hooks/make-symlinks-relative.sh
../../build-support/setup-hooks/move-docs.sh
../../build-support/setup-hooks/move-lib64.sh
../../build-support/setup-hooks/move-sbin.sh
../../build-support/setup-hooks/move-systemd-user-units.sh
../../build-support/setup-hooks/multiple-outputs.sh
../../build-support/setup-hooks/patch-shebangs.sh
../../build-support/setup-hooks/prune-libtool-files.sh
../../build-support/setup-hooks/reproducible-builds.sh
../../build-support/setup-hooks/set-source-date-epoch-to-latest.sh
../../build-support/setup-hooks/strip.sh
]
++ lib.optionals hasCC [ cc ];
defaultBuildInputs = extraBuildInputs;
stdenv = (stdenv-overridable argsStdenv);
in
# The stdenv that we are producing.
derivation (
lib.optionalAttrs (allowedRequisites != null) {
allowedRequisites = allowedRequisites ++ defaultNativeBuildInputs ++ defaultBuildInputs;
}
// lib.optionalAttrs config.contentAddressedByDefault {
__contentAddressed = true;
outputHashAlgo = "sha256";
outputHashMode = "recursive";
}
// {
inherit name;
inherit disallowedRequisites;
# 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.isElf && !hostPlatform.isMacho)) ''
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 due to
# `pkgsCross.*.buildPackages` not being the same, resulting in cross-compiling
# for a target rebuilding all of `nativeBuildInputs` for that target.
#
# 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";
tests = {
succeedOnFailure = import ../tests/succeedOnFailure.nix { inherit stdenv; };
};
passthru.tests = lib.warn "Use `stdenv.tests` instead. `passthru` is a `mkDerivation` detail." stdenv.tests;
}
# 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,954 @@
{ lib, config }:
stdenv:
let
# Lib attributes are inherited to the lexical scope for performance reasons.
inherit (lib)
any
assertMsg
attrNames
boolToString
concatLists
concatMap
concatMapStrings
concatStringsSep
elem
elemAt
extendDerivation
filter
findFirst
getDev
head
imap1
isAttrs
isBool
isDerivation
isInt
isList
isString
mapAttrs
mapNullable
optional
optionalAttrs
optionalString
optionals
pipe
remove
splitString
subtractLists
toFunction
unique
zipAttrsWith
;
inherit (import ../../build-support/lib/cmake.nix { inherit lib stdenv; }) makeCMakeFlags;
inherit (import ../../build-support/lib/meson.nix { inherit lib stdenv; }) makeMesonFlags;
/**
This function creates a derivation, and returns it in the form of a [package attribute set](https://nix.dev/manual/nix/latest/glossary#package-attribute-set)
that refers to the derivation's outputs.
`mkDerivation` takes many argument attributes, most of which affect the derivation environment,
but [`meta`](#chap-meta) and [`passthru`](#var-stdenv-passthru) only directly affect package attributes.
The `mkDerivation` argument attributes can be made to refer to one another by passing a function to `mkDerivation`.
See [Fixed-point argument of `mkDerivation`](#mkderivation-recursive-attributes).
Reference documentation see: https://nixos.org/manual/nixpkgs/stable/#sec-using-stdenv
:::{.note}
This is used as the fundamental building block of most other functions in Nixpkgs for creating derivations.
Most arguments are also passed through to the underlying call of [`derivation`](https://nixos.org/manual/nix/stable/language/derivations).
:::
*/
mkDerivation = fnOrAttrs: makeDerivationExtensible (toFunction fnOrAttrs);
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 overrideAttrs; });
# ^^^^
/**
Override the attributes that were passed to `mkDerivation` in order to generate this derivation.
*/
# NOTE: the above documentation had to be duplicated in `lib/customisation.nix`: `makeOverridable`.
overrideAttrs =
f0:
let
extends' =
overlay: f:
(
final:
let
prev = f final;
thisOverlay = overlay final prev;
warnForBadVersionOverride = (
thisOverlay ? version
&& prev ? version
# We could check that the version is actually distinct, but that
# would probably just delay the inevitable, or preserve tech debt.
# && prev.version != thisOverlay.version
&& !(thisOverlay ? src)
&& !(thisOverlay.__intentionallyOverridingVersion or false)
);
pname = args.pname or "<unknown name>";
version = args.version or "<unknown version>";
pos = builtins.unsafeGetAttrPos "version" thisOverlay;
in
lib.warnIf warnForBadVersionOverride ''
${
args.name or "${pname}-${version}"
} was overridden with `version` but not `src` at ${pos.file or "<unknown file>"}:${
toString pos.line or "<unknown line>"
}:${toString pos.column or "<unknown column>"}.
This is most likely not what you want. In order to properly change the version of a package, override
both the `version` and `src` attributes:
hello.overrideAttrs (oldAttrs: rec {
version = "1.0.0";
src = pkgs.fetchurl {
url = "mirror://gnu/hello/hello-''${version}.tar.gz";
hash = "...";
};
})
(To silence this warning, set `__intentionallyOverridingVersion = true` in your `overrideAttrs` call.)
'' (prev // (removeAttrs thisOverlay [ "__intentionallyOverridingVersion" ]))
);
in
makeDerivationExtensible (extends' (lib.toExtension f0) rattrs);
finalPackage = mkDerivationSimple overrideAttrs args;
in
finalPackage;
knownHardeningFlags = [
"bindnow"
"format"
"fortify"
"fortify3"
"strictflexarrays1"
"strictflexarrays3"
"shadowstack"
"nostrictaliasing"
"pacret"
"pic"
"pie"
"relro"
"stackprotector"
"glibcxxassertions"
"stackclashprotection"
"strictoverflow"
"trivialautovarinit"
"zerocallusedregs"
];
removedOrReplacedAttrNames = [
"checkInputs"
"installCheckInputs"
"nativeCheckInputs"
"nativeInstallCheckInputs"
"__contentAddressed"
"__darwinAllowLocalNetworking"
"__impureHostDeps"
"__propagatedImpureHostDeps"
"sandboxProfile"
"propagatedSandboxProfile"
"disallowedReferences"
"disallowedRequisites"
"allowedReferences"
"allowedRequisites"
"allowedImpureDLLs"
];
inherit (stdenv)
hostPlatform
buildPlatform
targetPlatform
extraNativeBuildInputs
extraBuildInputs
extraSandboxProfile
__extraImpureHostDeps
;
stdenvHasCC = stdenv.hasCC;
stdenvShell = stdenv.shell;
buildPlatformSystem = buildPlatform.system;
buildIsDarwin = buildPlatform.isDarwin;
inherit (hostPlatform)
isLinux
isDarwin
isWindows
isCygwin
isOpenBSD
isStatic
isMusl
;
# 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 / resolve #87909
useDefaultConfigurePlatforms = hostPlatform != buildPlatform || config.configurePlatformsByDefault;
defaultConfigurePlatforms = optionals useDefaultConfigurePlatforms [
"build"
"host"
];
buildPlatformConfigureFlag = "--build=${buildPlatform.config}";
hostPlatformConfigureFlag = "--host=${hostPlatform.config}";
targetPlatformConfigureFlag = "--target=${targetPlatform.config}";
defaultConfigurePlatformsFlags = optionals useDefaultConfigurePlatforms [
buildPlatformConfigureFlag
hostPlatformConfigureFlag
];
# TODO(@Ericson2314): Make always true and remove / resolve #178468
defaultStrictDeps = if config.strictDepsByDefault then true else hostPlatform != buildPlatform;
canExecuteHostOnBuild = buildPlatform.canExecute hostPlatform;
defaultHardeningFlags =
(if stdenvHasCC then stdenv.cc else { }).defaultHardeningFlags or
# fallback safe-ish set of flags
(
if isOpenBSD && isStatic then
knownHardeningFlags # Need pie, in fact
else
remove "pie" knownHardeningFlags
);
stdenvHostSuffix = optionalString (hostPlatform != buildPlatform) "-${hostPlatform.config}";
stdenvStaticMarker = optionalString isStatic "-static";
userHook = config.stdenv.userHook or null;
requiredSystemFeaturesShouldBeSet =
buildPlatform ? gcc.arch
&& !(
buildPlatform.isAarch64
&& (
# `aarch64-darwin` sets `{gcc.arch = "armv8.3-a+crypto+sha2+...";}`
buildPlatform.isDarwin
||
# `aarch64-linux` has `{ gcc.arch = "armv8-a"; }` set by default
buildPlatform.gcc.arch == "armv8-a"
)
);
gccArchFeature = [ "gccarch-${buildPlatform.gcc.arch}" ];
# Turn a derivation into its outPath without a string context attached.
# See the comment at the usage site.
unsafeDerivationToUntrackedOutpath =
drv:
if isDerivation drv && (!drv.__contentAddressed or false) then
builtins.unsafeDiscardStringContext drv.outPath
else
drv;
makeOutputChecks =
attrs:
# If we use derivations directly here, they end up as build-time dependencies.
# This is especially problematic in the case of disallowed*, since the disallowed
# derivations will be built by nix as build-time dependencies, while those
# derivations might take a very long time to build, or might not even build
# successfully on the platform used.
# We can improve on this situation by instead passing only the outPath,
# without an attached string context, to nix. The out path will be a placeholder
# which will be replaced by the actual out path if the derivation in question
# is part of the final closure (and thus needs to be built). If it is not
# part of the final closure, then the placeholder will be passed along,
# but in that case we know for a fact that the derivation is not part of the closure.
# This means that passing the out path to nix does the right thing in either
# case, both for disallowed and allowed references/requisites, and we won't
# build the derivation if it wouldn't be part of the closure, saving time and resources.
# While the problem is less severe for allowed*, since we want the derivation
# to be built eventually, we would still like to get the error early and without
# having to wait while nix builds a derivation that might not be used.
# See also https://github.com/NixOS/nix/issues/4629
{
${if (attrs ? disallowedReferences) then "disallowedReferences" else null} =
map unsafeDerivationToUntrackedOutpath attrs.disallowedReferences;
${if (attrs ? disallowedRequisites) then "disallowedRequisites" else null} =
map unsafeDerivationToUntrackedOutpath attrs.disallowedRequisites;
${if (attrs ? allowedReferences) then "allowedReferences" else null} =
mapNullable unsafeDerivationToUntrackedOutpath attrs.allowedReferences;
${if (attrs ? allowedRequisites) then "allowedRequisites" else null} =
mapNullable unsafeDerivationToUntrackedOutpath attrs.allowedRequisites;
};
makeDerivationArgument =
# `makeDerivationArgument` is responsible for the `mkDerivation` arguments that
# affect the actual derivation, excluding a few behaviors that are not
# essential, and specific to `mkDerivation`: `env`, `cmakeFlags`, `mesonFlags`.
#
# See also:
#
# * 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 ? [ ],
nativeCheckInputs ? [ ],
nativeInstallCheckInputs ? [ ],
# Configure Phase
configureFlags ? [ ],
configurePlatforms ? defaultConfigurePlatforms,
# 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 / resolve #178468
strictDeps ? defaultStrictDeps,
enableParallelBuilding ? config.enableParallelBuildingByDefault,
separateDebugInfo ? false,
outputs ? [ "out" ],
__darwinAllowLocalNetworking ? false,
__impureHostDeps ? [ ],
__propagatedImpureHostDeps ? [ ],
sandboxProfile ? "",
propagatedSandboxProfile ? "",
allowedImpureDLLs ? [ ],
hardeningEnable ? [ ],
hardeningDisable ? [ ],
patches ? [ ],
__contentAddressed ?
(!attrs ? outputHash) # Fixed-output drvs can't be content addressed too
&& config.contentAddressedByDefault,
# Experimental. For simple packages mostly just works,
# but for anything complex, be prepared to debug if enabling.
__structuredAttrs ? config.structuredAttrsByDefault or false,
...
}@attrs:
# Policy on acceptable hash types in nixpkgs
assert
attrs ? outputHash
-> (
let
algo = attrs.outputHashAlgo or (head (splitString "-" attrs.outputHash));
in
if algo == "md5" then throw "Rejected insecure ${algo} hash '${attrs.outputHash}'" else true
);
let
# TODO(@oxij, @Ericson2314): This is here to keep the old semantics, remove when
# no package has `doCheck = true`.
doCheck' = doCheck && canExecuteHostOnBuild;
doInstallCheck' = doInstallCheck && canExecuteHostOnBuild;
separateDebugInfo' =
let
actualValue = separateDebugInfo && isLinux;
conflictingOption =
attrs ? "disallowedReferences"
|| attrs ? "disallowedRequisites"
|| attrs ? "allowedRequisites"
|| attrs ? "allowedReferences";
in
if actualValue && conflictingOption && !__structuredAttrs then
throw "separateDebugInfo = true in ${
attrs.pname or "mkDerivation argument"
} requires __structuredAttrs if {dis,}allowedRequisites or {dis,}allowedReferences is set"
else
actualValue;
outputs' = outputs ++ optional separateDebugInfo' "debug";
noNonNativeDeps =
builtins.length (
depsBuildTarget
++ depsBuildTargetPropagated
++ depsHostHost
++ depsHostHostPropagated
++ buildInputs
++ propagatedBuildInputs
++ depsTargetTarget
++ depsTargetTargetPropagated
) == 0;
dontAddHostSuffix = attrs ? outputHash && !noNonNativeDeps || !stdenvHasCC;
concretizeFlagImplications =
flag: impliesFlags: list:
if any (x: x == flag) list then (list ++ impliesFlags) else list;
hardeningDisable' = unique (
pipe hardeningDisable [
# disabling fortify implies fortify3 should also be disabled
(concretizeFlagImplications "fortify" [ "fortify3" ])
# disabling strictflexarrays1 implies strictflexarrays3 should also be disabled
(concretizeFlagImplications "strictflexarrays1" [ "strictflexarrays3" ])
]
);
enabledHardeningOptions =
if builtins.elem "all" hardeningDisable' then
[ ]
else
subtractLists hardeningDisable' (defaultHardeningFlags ++ hardeningEnable);
# hardeningDisable additionally supports "all".
erroneousHardeningFlags = subtractLists knownHardeningFlags (
hardeningEnable ++ remove "all" hardeningDisable
);
checkDependencyList = checkDependencyList' [ ];
checkDependencyList' =
positions: name: deps:
imap1 (
index: dep:
if dep == null || isDerivation dep || builtins.isString dep || builtins.isPath dep then
dep
else if isList dep then
checkDependencyList' ([ index ] ++ positions) name dep
else
throw "Dependency is not of a valid type: ${
concatMapStrings (ix: "element ${toString ix} of ") ([ index ] ++ positions)
}${name} for ${attrs.name or attrs.pname}"
) deps;
in
if builtins.length erroneousHardeningFlags != 0 then
abort (
"mkDerivation was called with unsupported hardening flags: "
+ lib.generators.toPretty { } {
inherit
erroneousHardeningFlags
hardeningDisable
hardeningEnable
knownHardeningFlags
;
}
)
else
let
doCheck = doCheck';
doInstallCheck = doInstallCheck';
buildInputs' =
buildInputs ++ optionals doCheck checkInputs ++ optionals doInstallCheck installCheckInputs;
nativeBuildInputs' =
nativeBuildInputs
++ optional separateDebugInfo' ../../build-support/setup-hooks/separate-debug-info.sh
++ optional isWindows ../../build-support/setup-hooks/win-dll-link.sh
++ optional isCygwin ../../build-support/setup-hooks/cygwin-dll-link.sh
++ optionals doCheck nativeCheckInputs
++ optionals doInstallCheck nativeInstallCheckInputs;
outputs = outputs';
dependencies = [
[
(map (drv: getDev drv.__spliced.buildBuild or drv) (
checkDependencyList "depsBuildBuild" depsBuildBuild
))
(map (drv: getDev drv.__spliced.buildHost or drv) (
checkDependencyList "nativeBuildInputs" nativeBuildInputs'
))
(map (drv: getDev drv.__spliced.buildTarget or drv) (
checkDependencyList "depsBuildTarget" depsBuildTarget
))
]
[
(map (drv: getDev drv.__spliced.hostHost or drv) (checkDependencyList "depsHostHost" depsHostHost))
(map (drv: getDev drv.__spliced.hostTarget or drv) (checkDependencyList "buildInputs" buildInputs'))
]
[
(map (drv: getDev drv.__spliced.targetTarget or drv) (
checkDependencyList "depsTargetTarget" depsTargetTarget
))
]
];
propagatedDependencies = [
[
(map (drv: getDev drv.__spliced.buildBuild or drv) (
checkDependencyList "depsBuildBuildPropagated" depsBuildBuildPropagated
))
(map (drv: getDev drv.__spliced.buildHost or drv) (
checkDependencyList "propagatedNativeBuildInputs" propagatedNativeBuildInputs
))
(map (drv: getDev drv.__spliced.buildTarget or drv) (
checkDependencyList "depsBuildTargetPropagated" depsBuildTargetPropagated
))
]
[
(map (drv: getDev drv.__spliced.hostHost or drv) (
checkDependencyList "depsHostHostPropagated" depsHostHostPropagated
))
(map (drv: getDev drv.__spliced.hostTarget or drv) (
checkDependencyList "propagatedBuildInputs" propagatedBuildInputs
))
]
[
(map (drv: getDev drv.__spliced.targetTarget or drv) (
checkDependencyList "depsTargetTargetPropagated" depsTargetTargetPropagated
))
]
];
derivationArg =
removeAttrs attrs removedOrReplacedAttrNames
// {
${if (attrs ? name || (attrs ? pname && attrs ? version)) then "name" else null} =
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 = optionalString (!dontAddHostSuffix) stdenvHostSuffix;
# 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 = stdenvStaticMarker;
in
lib.strings.sanitizeDerivationName (
if attrs ? name then
attrs.name + hostSuffix
else
# we cannot coerce null to a string below
assert assertMsg (
attrs ? version && attrs.version != null
) "The `version` attribute cannot be null.";
"${attrs.pname}${staticMarker}${hostSuffix}-${attrs.version}"
);
builder = attrs.realBuilder or stdenvShell;
args =
attrs.args or [
"-e"
./source-stdenv.sh
(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 `buildPlatform` matches Nix's degree of specificity.
# exactly.
system = buildPlatformSystem;
inherit userHook;
__ignoreNulls = true;
inherit __structuredAttrs strictDeps;
depsBuildBuild = elemAt (elemAt dependencies 0) 0;
nativeBuildInputs = elemAt (elemAt dependencies 0) 1;
depsBuildTarget = elemAt (elemAt dependencies 0) 2;
depsHostHost = elemAt (elemAt dependencies 1) 0;
buildInputs = elemAt (elemAt dependencies 1) 1;
depsTargetTarget = elemAt (elemAt dependencies 2) 0;
depsBuildBuildPropagated = elemAt (elemAt propagatedDependencies 0) 0;
propagatedNativeBuildInputs = elemAt (elemAt propagatedDependencies 0) 1;
depsBuildTargetPropagated = elemAt (elemAt propagatedDependencies 0) 2;
depsHostHostPropagated = elemAt (elemAt propagatedDependencies 1) 0;
propagatedBuildInputs = elemAt (elemAt propagatedDependencies 1) 1;
depsTargetTargetPropagated = elemAt (elemAt propagatedDependencies 2) 0;
# This parameter is sometimes a string, sometimes null, and sometimes a list, yuck
configureFlags =
configureFlags
++ (
if configurePlatforms == defaultConfigurePlatforms then
defaultConfigurePlatformsFlags
else
optional (elem "build" configurePlatforms) buildPlatformConfigureFlag
++ optional (elem "host" configurePlatforms) hostPlatformConfigureFlag
++ optional (elem "target" configurePlatforms) targetPlatformConfigureFlag
);
inherit patches;
inherit doCheck doInstallCheck;
inherit outputs;
# When the derivations is content addressed provide default values
# for outputHashMode and outputHashAlgo because most people won't
# care about these anyways
${if __contentAddressed then "__contentAddressed" else null} = __contentAddressed;
${if __contentAddressed then "outputHashAlgo" else null} = attrs.outputHashAlgo or "sha256";
${if __contentAddressed then "outputHashMode" else null} = attrs.outputHashMode or "recursive";
${if enableParallelBuilding then "enableParallelBuilding" else null} = enableParallelBuilding;
${if enableParallelBuilding then "enableParallelChecking" else null} =
attrs.enableParallelChecking or true;
${if enableParallelBuilding then "enableParallelInstalling" else null} =
attrs.enableParallelInstalling or true;
${
if (hardeningDisable != [ ] || hardeningEnable != [ ] || isMusl) then
"NIX_HARDENING_ENABLE"
else
null
} =
builtins.concatStringsSep " " enabledHardeningOptions;
# TODO: remove platform condition
# Enabling this check could be a breaking change as it requires to edit nix.conf
# NixOS module already sets gccarch, unsure of nix installers and other distributions
${if requiredSystemFeaturesShouldBeSet then "requiredSystemFeatures" else null} =
attrs.requiredSystemFeatures or [ ] ++ gccArchFeature;
}
// optionalAttrs buildIsDarwin (
let
allDependencies = concatLists (concatLists dependencies);
allPropagatedDependencies = concatLists (concatLists propagatedDependencies);
computedSandboxProfile = concatMap (input: input.__propagatedSandboxProfile or [ ]) (
extraNativeBuildInputs ++ extraBuildInputs ++ allDependencies
);
computedPropagatedSandboxProfile = concatMap (
input: input.__propagatedSandboxProfile or [ ]
) allPropagatedDependencies;
computedImpureHostDeps = unique (
concatMap (input: input.__propagatedImpureHostDeps or [ ]) (
extraNativeBuildInputs ++ extraBuildInputs ++ allDependencies
)
);
computedPropagatedImpureHostDeps = unique (
concatMap (input: input.__propagatedImpureHostDeps or [ ]) allPropagatedDependencies
);
in
{
inherit __darwinAllowLocalNetworking;
# TODO: remove `unique` once nix has a list canonicalization primitive
__sandboxProfile =
let
profiles = [
extraSandboxProfile
]
++ computedSandboxProfile
++ computedPropagatedSandboxProfile
++ [
propagatedSandboxProfile
sandboxProfile
];
final = concatStringsSep "\n" (filter (x: x != "") (unique profiles));
in
final;
__propagatedSandboxProfile = unique (
computedPropagatedSandboxProfile ++ [ propagatedSandboxProfile ]
);
__impureHostDeps =
computedImpureHostDeps
++ computedPropagatedImpureHostDeps
++ __propagatedImpureHostDeps
++ __impureHostDeps
++ __extraImpureHostDeps
++ [
"/dev/zero"
"/dev/random"
"/dev/urandom"
"/bin/sh"
];
__propagatedImpureHostDeps = computedPropagatedImpureHostDeps ++ __propagatedImpureHostDeps;
}
)
// optionalAttrs (isWindows || isCygwin) (
let
dlls =
allowedImpureDLLs
++ lib.optionals isCygwin [
"KERNEL32.dll"
"cygwin1.dll"
];
in
{
allowedImpureDLLs = if dlls != [ ] then dlls else null;
}
)
// (
if !__structuredAttrs then
makeOutputChecks attrs
else
{
outputChecks = builtins.listToAttrs (
map (name: {
inherit name;
value =
let
raw = zipAttrsWith (_: builtins.concatLists) [
(makeOutputChecks attrs)
(makeOutputChecks attrs.outputChecks.${name} or { })
];
in
# separateDebugInfo = true will put all sorts of files in
# the debug output which could carry references, but
# that's "normal". Notably it symlinks to the source.
# So disable reference checking for the debug output
if separateDebugInfo' && name == "debug" then
removeAttrs raw [
"allowedReferences"
"allowedRequisites"
"disallowedReferences"
"disallowedRequisites"
]
else
raw;
}) outputs
);
}
);
in
derivationArg;
mkDerivationSimple =
overrideAttrs:
# `mkDerivation` wraps the builtin `derivation` function to
# produce derivations that use this stdenv and its shell.
#
# Internally, it delegates most of its behavior to `makeDerivationArgument`,
# except for the `env`, `cmakeFlags`, and `mesonFlags` attributes, as well
# as the attributes `meta` and `passthru` that affect [package attributes],
# and not the derivation itself.
#
# See also:
#
# * https://nixos.org/nixpkgs/manual/#sec-using-stdenv
# Details on how to use this mkDerivation function
#
# * https://nixos.org/manual/nix/stable/expressions/derivations.html#derivations
# Explanation about derivations in general
#
# * [package attributes]: https://nixos.org/manual/nix/stable/glossary#package-attribute-set
{
# Configure Phase
cmakeFlags ? [ ],
mesonFlags ? [ ],
meta ? { },
passthru ? { },
pos ? # position used in error messages and for meta.position
(
if attrs.meta.description or null != null then
builtins.unsafeGetAttrPos "description" attrs.meta
else if attrs.version or null != null then
builtins.unsafeGetAttrPos "version" attrs
else
builtins.unsafeGetAttrPos "name" attrs
),
# Experimental. For simple packages mostly just works,
# but for anything complex, be prepared to debug if enabling.
__structuredAttrs ? config.structuredAttrsByDefault or false,
env ? { },
...
}@attrs:
# Policy on acceptable hash types in nixpkgs
assert
attrs ? outputHash
-> (
let
algo = attrs.outputHashAlgo or (head (splitString "-" attrs.outputHash));
in
if algo == "md5" then throw "Rejected insecure ${algo} hash '${attrs.outputHash}'" else true
);
let
mainProgram = meta.mainProgram or null;
env' = env // lib.optionalAttrs (mainProgram != null) { NIX_MAIN_PROGRAM = mainProgram; };
derivationArg = makeDerivationArgument (
removeAttrs attrs [
"meta"
"passthru"
"pos"
"env"
]
// lib.optionalAttrs __structuredAttrs { env = checkedEnv; }
// {
cmakeFlags = makeCMakeFlags attrs;
mesonFlags = makeMesonFlags attrs;
}
);
meta = checkMeta.commonMeta {
inherit validity attrs pos;
references =
attrs.nativeBuildInputs or [ ]
++ attrs.buildInputs or [ ]
++ attrs.propagatedNativeBuildInputs or [ ]
++ attrs.propagatedBuildInputs or [ ];
};
validity = checkMeta.assertValidity { inherit meta attrs; };
checkedEnv =
let
overlappingNames = attrNames (builtins.intersectAttrs env' derivationArg);
prettyPrint = lib.generators.toPretty { };
makeError =
name:
" - ${name}: in `env`: ${prettyPrint env'.${name}}; in derivation arguments: ${
prettyPrint derivationArg.${name}
}";
errors = lib.concatMapStringsSep "\n" makeError overlappingNames;
in
assert assertMsg (isAttrs env && !isDerivation env)
"`env` must be an attribute set of environment variables. Set `env.env` or pick a more specific name.";
assert assertMsg (overlappingNames == [ ])
"The `env` attribute set cannot contain any attributes passed to derivation. The following attributes are overlapping:\n${errors}";
mapAttrs (
n: v:
assert assertMsg (isString v || isBool v || isInt v || isDerivation v)
"The `env` attribute set can only contain derivation, string, boolean or integer attributes. The `${n}` attribute is of type ${builtins.typeOf v}.";
v
) env';
# Fixed-output derivations may not reference other paths, which means that
# for a fixed-output derivation, the corresponding inputDerivation should
# *not* be fixed-output. To achieve this we simply delete the attributes that
# would make it fixed-output.
deleteFixedOutputRelatedAttrs = lib.flip removeAttrs [
"outputHashAlgo"
"outputHash"
"outputHashMode"
];
in
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 (
deleteFixedOutputRelatedAttrs 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 = stdenvShell;
# The builtin `declare -p` dumps all bash and 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). Using placeholder for $out works with
# and without structuredAttrs.
# This build script does not use setup.sh or stdenv, to keep
# the env most pristine. This gives us a very bare bones env,
# hence the extra/duplicated compatibility logic and "pure bash" style.
args = [
"-c"
''
out="${placeholder "out"}"
if [ -e "$NIX_ATTRS_SH_FILE" ]; then . "$NIX_ATTRS_SH_FILE"; fi
declare -p > $out
for var in $passAsFile; do
pathVar="''${var}Path"
printf "%s" "$(< "''${!pathVar}")" >> $out
done
''
];
}
// (
let
sharedOutputChecks = {
# inputDerivation produces the inputs; not the outputs, so any
# restrictions on what used to be the outputs don't serve a purpose
# anymore.
allowedReferences = null;
allowedRequisites = null;
disallowedReferences = [ ];
disallowedRequisites = [ ];
};
in
if __structuredAttrs then
{
outputChecks.out = sharedOutputChecks;
}
else
sharedOutputChecks
)
);
inherit passthru overrideAttrs;
inherit meta;
}
//
# 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 // checkedEnv));
in
{
inherit mkDerivation;
}

View File

@@ -0,0 +1,98 @@
{ lib }:
# Simple internal type checks for meta.
# This file is not a stable interface and may be changed arbitrarily.
#
# TODO: add a method to the module system types
# see https://github.com/NixOS/nixpkgs/pull/273935#issuecomment-1854173100
let
inherit (builtins)
isString
isInt
isAttrs
isList
all
any
attrValues
isFunction
isBool
concatStringsSep
isFloat
;
isTypeDef = t: isAttrs t && t ? name && isString t.name && t ? verify && isFunction t.verify;
in
lib.fix (self: {
string = {
name = "string";
verify = isString;
};
str = self.string; # Type alias
any = {
name = "any";
verify = _: true;
};
int = {
name = "int";
verify = isInt;
};
float = {
name = "float";
verify = isFloat;
};
bool = {
name = "bool";
verify = isBool;
};
attrs = {
name = "attrs";
verify = isAttrs;
};
list = {
name = "list";
verify = isList;
};
attrsOf =
t:
assert isTypeDef t;
let
inherit (t) verify;
in
{
name = "attrsOf<${t.name}>";
verify =
# attrsOf<any> can be optimised to just isAttrs
if t == self.any then isAttrs else attrs: isAttrs attrs && all verify (attrValues attrs);
};
listOf =
t:
assert isTypeDef t;
let
inherit (t) verify;
in
{
name = "listOf<${t.name}>";
verify =
# listOf<any> can be optimised to just isList
if t == self.any then isList else v: isList v && all verify v;
};
union =
types:
assert all isTypeDef types;
let
# Store a list of functions so we don't have to pay the cost of attrset lookups at runtime.
funcs = map (t: t.verify) types;
in
{
name = "union<${concatStringsSep "," (map (t: t.name) types)}>";
verify = v: any (func: func v) funcs;
};
})

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

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,3 @@
if [ -e "$NIX_ATTRS_SH_FILE" ]; then . "$NIX_ATTRS_SH_FILE"; fi
source "$stdenv/setup"
source "$1"

View File

@@ -0,0 +1,11 @@
{
busybox = import <nix/fetchurl.nix> {
url = "http://tarballs.nixos.org/stdenv-linux/aarch64/21ec906463ea8f11abf3f9091ddd4c3276516e58/busybox";
executable = true;
hash = "sha256-0MuIeQlBUaeisqoFSu8y+8oB6K4ZG5Lhq8RcS9JqkFQ=";
};
bootstrapTools = import <nix/fetchurl.nix> {
url = "http://tarballs.nixos.org/stdenv-linux/aarch64/21ec906463ea8f11abf3f9091ddd4c3276516e58/bootstrap-tools.tar.xz";
hash = "sha256-aJvtsWeuQHbb14BGZ2EiOKzjQn46h3x3duuPEawG0eE=";
};
}

View File

@@ -0,0 +1,25 @@
#
# Files came from this Hydra build:
#
# https://hydra.nixos.org/build/246470544
#
# …which used nixpkgs revision dd5621df6dcb90122b50da5ec31c411a0de3e538
# to instantiate:
#
# /nix/store/g480ass2vjmakaq03z7k2j95xnxh206a-stdenv-bootstrap-tools.drv
#
# …and then built:
#
# /nix/store/95lm0y33dayag4542s8bi83s31bw68dr-stdenv-bootstrap-tools
#
{
busybox = import <nix/fetchurl.nix> {
url = "http://tarballs.nixos.org/stdenv/aarch64-unknown-linux-musl/dd5621df6dcb90122b50da5ec31c411a0de3e538/busybox";
sha256 = "sha256-WuOaun7U5enbOy8SuuCo6G1fbGwsO16jhy/oM8K0lAs=";
executable = true;
};
bootstrapTools = import <nix/fetchurl.nix> {
url = "http://tarballs.nixos.org/stdenv/aarch64-unknown-linux-musl/dd5621df6dcb90122b50da5ec31c411a0de3e538/bootstrap-tools.tar.xz";
hash = "sha256-ZY9IMOmx1VOn6uoFDpdJbTnPX59TEkrVCzWNtjQ8/QE=";
};
}

View File

@@ -0,0 +1,21 @@
# Autogenerated by maintainers/scripts/bootstrap-files/refresh-tarballs.bash as:
# $ ./refresh-tarballs.bash --targets=armv5tel-unknown-linux-gnueabi
#
# Metadata:
# - nixpkgs revision: 029dea9aaacf920ce8f7d89e4cf09da31a38d8e1
# - hydra build: https://hydra.nixos.org/job/nixpkgs/cross-trunk/bootstrapTools.armv5tel-unknown-linux-gnueabi.build/latest
# - resolved hydra build: https://hydra.nixos.org/build/281086357
# - instantiated derivation: /nix/store/j44ipis8k634n1a6j9j1blff88w13ix9-stdenv-bootstrap-tools-armv5tel-unknown-linux-gnueabi.drv
# - output directory: /nix/store/7xapg8fj3p2fpmnppsd28a66q62vzdg1-stdenv-bootstrap-tools-armv5tel-unknown-linux-gnueabi
# - build time: Tue, 03 Dec 2024 13:59:40 +0000
{
bootstrapTools = import <nix/fetchurl.nix> {
url = "http://tarballs.nixos.org/stdenv/armv5tel-unknown-linux-gnueabi/029dea9aaacf920ce8f7d89e4cf09da31a38d8e1/bootstrap-tools.tar.xz";
hash = "sha256-+7cdKUThhOb4pVFBjPWFpBbTfn64A/ezkZnP6hEhMRM=";
};
busybox = import <nix/fetchurl.nix> {
url = "http://tarballs.nixos.org/stdenv/armv5tel-unknown-linux-gnueabi/029dea9aaacf920ce8f7d89e4cf09da31a38d8e1/busybox";
hash = "sha256-vZ3oSKUjGVcx2TJsrKmTX4d+3S4/flD780vFVaaHDGI=";
executable = true;
};
}

View File

@@ -0,0 +1,21 @@
# Autogenerated by maintainers/scripts/bootstrap-files/refresh-tarballs.bash as:
# $ ./refresh-tarballs.bash --targets=armv6l-unknown-linux-gnueabihf
#
# Metadata:
# - nixpkgs revision: 029dea9aaacf920ce8f7d89e4cf09da31a38d8e1
# - hydra build: https://hydra.nixos.org/job/nixpkgs/cross-trunk/bootstrapTools.armv6l-unknown-linux-gnueabihf.build/latest
# - resolved hydra build: https://hydra.nixos.org/build/281086894
# - instantiated derivation: /nix/store/gq29b3av5mf7x9zlbvaf1qrvlnb1ps4l-stdenv-bootstrap-tools-armv6l-unknown-linux-gnueabihf.drv
# - output directory: /nix/store/cwfvh58lcbyk26d34j1w26d3ladgcgn8-stdenv-bootstrap-tools-armv6l-unknown-linux-gnueabihf
# - build time: Tue, 03 Dec 2024 13:59:47 +0000
{
bootstrapTools = import <nix/fetchurl.nix> {
url = "http://tarballs.nixos.org/stdenv/armv6l-unknown-linux-gnueabihf/029dea9aaacf920ce8f7d89e4cf09da31a38d8e1/bootstrap-tools.tar.xz";
hash = "sha256-IOZRTJRvoP0bIz5GI6GqGAYb/FdME+xVVyFTvgtmLuw=";
};
busybox = import <nix/fetchurl.nix> {
url = "http://tarballs.nixos.org/stdenv/armv6l-unknown-linux-gnueabihf/029dea9aaacf920ce8f7d89e4cf09da31a38d8e1/busybox";
hash = "sha256-kdlAOhgypLa+ZesRT1ZVDoDQdNefV1Rx5Yf7H254o80=";
executable = true;
};
}

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,21 @@
# Autogenerated by maintainers/scripts/bootstrap-files/refresh-tarballs.bash as:
# $ ./refresh-tarballs.bash --targets=armv7l-unknown-linux-gnueabihf
#
# Metadata:
# - nixpkgs revision: b92edf1104c47016385e85c87c2d953cf5cd2f98
# - hydra build: https://hydra.nixos.org/job/nixpkgs/cross-trunk/bootstrapTools.armv7l-unknown-linux-gnueabihf.build/latest
# - resolved hydra build: https://hydra.nixos.org/build/276944599
# - instantiated derivation: /nix/store/ldvkcqvzvwqv6frf6aqkl44jja88gvbx-stdenv-bootstrap-tools-armv7l-unknown-linux-gnueabihf.drv
# - output directory: /nix/store/y2xac60x8qkli271qn4dz78lzm2sqiv8-stdenv-bootstrap-tools-armv7l-unknown-linux-gnueabihf
# - build time: Thu, 31 Oct 2024 20:57:35 +0000
{
bootstrapTools = import <nix/fetchurl.nix> {
url = "http://tarballs.nixos.org/stdenv/armv7l-unknown-linux-gnueabihf/b92edf1104c47016385e85c87c2d953cf5cd2f98/bootstrap-tools.tar.xz";
hash = "sha256-FpBUnMI20l4LVdtmPpaGWP5+V52ZpvAH1JmHkOqFhCI=";
};
busybox = import <nix/fetchurl.nix> {
url = "http://tarballs.nixos.org/stdenv/armv7l-unknown-linux-gnueabihf/b92edf1104c47016385e85c87c2d953cf5cd2f98/busybox";
hash = "sha256-LSK7lkzpD1Zv5aFzp45W+3JGLi8iqOIk8brl1TNIl4g=";
executable = true;
};
}

View File

@@ -0,0 +1,21 @@
# Autogenerated by maintainers/scripts/bootstrap-files/refresh-tarballs.bash as:
# $ ./refresh-tarballs.bash --targets=i686-unknown-linux-gnu
#
# Metadata:
# - nixpkgs revision: 125cefd4cf8f857e5ff1aceaef9230ba578a033d
# - hydra build: https://hydra.nixos.org/job/nixpkgs/trunk/stdenvBootstrapTools.i686-unknown-linux-gnu.build/latest
# - resolved hydra build: https://hydra.nixos.org/build/247889988
# - instantiated derivation: /nix/store/chcf0brhdyn7ihmb14n0w4rm2a59gqrw-stdenv-bootstrap-tools.drv
# - output directory: /nix/store/5x6dldhza7if5s6wsicaxa8fbndyixps-stdenv-bootstrap-tools
# - build time: Fri, 26 Jan 2024 22:04:03 +0000
{
bootstrapTools = import <nix/fetchurl.nix> {
url = "http://tarballs.nixos.org/stdenv/i686-unknown-linux-gnu/125cefd4cf8f857e5ff1aceaef9230ba578a033d/bootstrap-tools.tar.xz";
hash = "sha256-KTAh3t91aJMiMO/7NFOjUz6fXI9Iu+H7cuODreWz9N8=";
};
busybox = import <nix/fetchurl.nix> {
url = "http://tarballs.nixos.org/stdenv/i686-unknown-linux-gnu/125cefd4cf8f857e5ff1aceaef9230ba578a033d/busybox";
hash = "sha256-omz+ZT0bhMkAZcDs9evA2PNpO6VHUozdtjMgdui6fxw=";
executable = true;
};
}

View File

@@ -0,0 +1,21 @@
# Autogenerated by maintainers/scripts/bootstrap-files/refresh-tarballs.bash as:
# $ ./refresh-tarballs.bash --targets=loongarch64-unknown-linux-gnu
#
# Metadata:
# - nixpkgs revision: bdcacf48f3b064c93a9064d1d545f75c60ca6c77
# - hydra build: https://hydra.nixos.org/job/nixpkgs/cross-trunk/bootstrapTools.loongarch64-unknown-linux-gnu.build/latest
# - resolved hydra build: https://hydra.nixos.org/build/295459473
# - instantiated derivation: /nix/store/q7r692xs6kpsyipmkfamhj36va79wa5r-stdenv-bootstrap-tools-loongarch64-unknown-linux-gnu.drv
# - output directory: /nix/store/gvjaqdhmvsqn821iypwj0cb8xq8yiii6-stdenv-bootstrap-tools-loongarch64-unknown-linux-gnu
# - build time: Wed, 23 Apr 2025 12:35:42 +0000
{
bootstrapTools = import <nix/fetchurl.nix> {
url = "http://tarballs.nixos.org/stdenv/loongarch64-unknown-linux-gnu/bdcacf48f3b064c93a9064d1d545f75c60ca6c77/bootstrap-tools.tar.xz";
hash = "sha256-Yx0YmbVElsbN0VKgPiKfm7+e3ed5JXu3vZv0kKIhER8=";
};
busybox = import <nix/fetchurl.nix> {
url = "http://tarballs.nixos.org/stdenv/loongarch64-unknown-linux-gnu/bdcacf48f3b064c93a9064d1d545f75c60ca6c77/busybox";
hash = "sha256-0UFp0zpeC8oTmS5/XJoMFnnOMTVTciQYmO/0JAi6uqk=";
executable = true;
};
}

View File

@@ -0,0 +1,25 @@
#
# Files came from this Hydra build:
#
# https://hydra.nixos.org/build/182757245
#
# Which used nixpkgs revision ef3fe254f3c59455386bc92fe84164f9679b92b1
# to instantiate:
#
# /nix/store/a2bvv663wjnyhq8m7v84aspsd3sgf9h6-stdenv-bootstrap-tools-mips64el-unknown-linux-gnuabi64.drv
#
# and then built:
#
# /nix/store/aw3dmsrh22831l83vi3q9apg9qi3x8ms-stdenv-bootstrap-tools-mips64el-unknown-linux-gnuabi64
#
{
busybox = import <nix/fetchurl.nix> {
url = "http://tarballs.nixos.org/stdenv-linux/mips64el/ef3fe254f3c59455386bc92fe84164f9679b92b1/busybox";
sha256 = "sha256-sTE58ofjqAqX3Xtq1g9wDxzIe6Vo//GHbicfqJoivDI=";
executable = true;
};
bootstrapTools = import <nix/fetchurl.nix> {
url = "http://tarballs.nixos.org/stdenv-linux/mips64el/ef3fe254f3c59455386bc92fe84164f9679b92b1/bootstrap-tools.tar.xz";
sha256 = "sha256-tTgjeXpd2YgnfP4JvRuO0bXd2j8GqzBcd57JI3wH9x0=";
};
}

View File

@@ -0,0 +1,25 @@
#
# Files came from this Hydra build:
#
# https://hydra.nixos.org/build/188389586
#
# Which used nixpkgs revision 97d9c84e1df4397b43ecb39359f1bd003cd44585
# to instantiate:
#
# /nix/store/hakn8s85s9011v61r6svp5qy8x1y64fv-stdenv-bootstrap-tools-mips64el-unknown-linux-gnuabin32.drv
#
# and then built:
#
# /nix/store/rjgybpnf3yiqyhvl2n2lx31jf800fii2-stdenv-bootstrap-tools-mips64el-unknown-linux-gnuabin32
#
{
busybox = import <nix/fetchurl.nix> {
url = "http://tarballs.nixos.org/stdenv-linux/mips64el-n32/97d9c84e1df4397b43ecb39359f1bd003cd44585/busybox";
sha256 = "sha256-4N3G1qYA7vitjhsIW17pR6UixIuzrq4vZXa8F0/X4iI=";
executable = true;
};
bootstrapTools = import <nix/fetchurl.nix> {
url = "http://tarballs.nixos.org/stdenv-linux/mips64el-n32/97d9c84e1df4397b43ecb39359f1bd003cd44585/bootstrap-tools.tar.xz";
sha256 = "sha256-LWrpN6su2yNVurUyhZP34OiZyzgh7MfN13fIIbou8KI=";
};
}

View File

@@ -0,0 +1,25 @@
#
# Files came from this Hydra build:
#
# https://hydra.nixos.org/build/185311909
#
# Which used nixpkgs revision 5bd14b3cfe2f87a2e2b074645aba39c69563e4bc
# to instantiate:
#
# /nix/store/184fa520zv8ls9fzcqyfa5dmkp8kf6xr-stdenv-bootstrap-tools-mipsel-unknown-linux-gnu.drv
#
# and then built:
#
# /nix/store/i46mrzinxi9a5incliwhksmk947ff4wn-stdenv-bootstrap-tools-mipsel-unknown-linux-gnu
#
{
busybox = import <nix/fetchurl.nix> {
url = "http://tarballs.nixos.org/stdenv-linux/mipsel/5bd14b3cfe2f87a2e2b074645aba39c69563e4bc/busybox";
hash = "sha256-EhuzjL52VEIOfEcFdVGZaDMClQbMc9V9ISrTUNaA7HQ=";
executable = true;
};
bootstrapTools = import <nix/fetchurl.nix> {
url = "http://tarballs.nixos.org/stdenv-linux/mipsel/5bd14b3cfe2f87a2e2b074645aba39c69563e4bc/bootstrap-tools.tar.xz";
hash = "sha256-OEGgLJOLnV+aobsb+P8mY3Dp8qbeVODBH6x3aUE/MGM=";
};
}

View File

@@ -0,0 +1,21 @@
# Autogenerated by maintainers/scripts/bootstrap-files/refresh-tarballs.bash as:
# $ ./refresh-tarballs.bash --targets=powerpc64-unknown-linux-gnuabielfv1
#
# Metadata:
# - nixpkgs revision: 2ba17da62f2813a5b779ec2b13abe96baec8ea08
# - hydra build: https://hydra.nixos.org/job/nixpkgs/cross-trunk/bootstrapTools.powerpc64-unknown-linux-gnuabielfv1.build/latest
# - resolved hydra build: https://hydra.nixos.org/build/301750343
# - instantiated derivation: /nix/store/4djsi9i5fc3nc7qzf4gjljn4zzjiy226-stdenv-bootstrap-tools-powerpc64-unknown-linux-gnuabielfv1.drv
# - output directory: /nix/store/b8zndw2p8f82hn23a3ilkmfc6v26yian-stdenv-bootstrap-tools-powerpc64-unknown-linux-gnuabielfv1
# - build time: Fri, 04 Jul 2025 13:37:14 +0000
{
bootstrapTools = import <nix/fetchurl.nix> {
url = "http://tarballs.nixos.org/stdenv/powerpc64-unknown-linux-gnuabielfv1/2ba17da62f2813a5b779ec2b13abe96baec8ea08/bootstrap-tools.tar.xz";
hash = "sha256-OnjFUMRNFmGu0EFSM99loZ03Bx6htCyTiftCBO1enQM=";
};
busybox = import <nix/fetchurl.nix> {
url = "http://tarballs.nixos.org/stdenv/powerpc64-unknown-linux-gnuabielfv1/2ba17da62f2813a5b779ec2b13abe96baec8ea08/busybox";
hash = "sha256-f5U+O8oHTAfJpukjz+YmIf8QQVuMoh+kKhOw5Zf5QJY=";
executable = true;
};
}

View File

@@ -0,0 +1,21 @@
# Autogenerated by maintainers/scripts/bootstrap-files/refresh-tarballs.bash as:
# $ ./refresh-tarballs.bash --targets=powerpc64-unknown-linux-gnuabielfv2
#
# Metadata:
# - nixpkgs revision: 57cf2e0b24fb52344cc718913eaed78f389b1319
# - hydra build: https://hydra.nixos.org/job/nixpkgs/cross-trunk/bootstrapTools.powerpc64-unknown-linux-gnuabielfv2.build/latest
# - resolved hydra build: https://hydra.nixos.org/build/252872323
# - instantiated derivation: /nix/store/yaa735jz1r1n863gzv3c8szl77lsgg8d-stdenv-bootstrap-tools-powerpc64-unknown-linux-gnuabielfv2.drv
# - output directory: /nix/store/8frm8kk8gzpv31r289ai5jgkwfikmpm4-stdenv-bootstrap-tools-powerpc64-unknown-linux-gnuabielfv2
# - build time: Sat, 09 Mar 2024 11:26:00 +0000
{
bootstrapTools = import <nix/fetchurl.nix> {
url = "http://tarballs.nixos.org/stdenv/powerpc64-unknown-linux-gnuabielfv2/57cf2e0b24fb52344cc718913eaed78f389b1319/bootstrap-tools.tar.xz";
hash = "sha256-CvMRR2tUs5nzAkuS6cUYNjrNKxX3E+g9C7T7P48m2Ys=";
};
busybox = import <nix/fetchurl.nix> {
url = "http://tarballs.nixos.org/stdenv/powerpc64-unknown-linux-gnuabielfv2/57cf2e0b24fb52344cc718913eaed78f389b1319/busybox";
hash = "sha256-+vnQrVBHg793JIdQR4Y9KuqdmNZ+Ic0FZvVqrPOKnOY=";
executable = true;
};
}

View File

@@ -0,0 +1,25 @@
#
# Files came from this Hydra build:
#
# https://hydra.nixos.org/build/186237511
#
# Which used nixpkgs revision ac43c444780a80e789fd14fe2114acd4a3b5cf9d
# to instantiate:
#
# /nix/store/nhjbza9vlcyhp9zxfz6lwpc3m2ghrpzj-stdenv-bootstrap-tools-powerpc64le-unknown-linux-gnu.drv
#
# and then built:
#
# /nix/store/fklpm7fy6cp5wz55w0gd8wakyqvzapjx-stdenv-bootstrap-tools-powerpc64le-unknown-linux-gnu
#
{
busybox = import <nix/fetchurl.nix> {
url = "http://tarballs.nixos.org/stdenv-linux/powerpc64le/ac43c444780a80e789fd14fe2114acd4a3b5cf9d/busybox";
sha256 = "sha256-jtPEAsht4AUAG4MLK8xocQSfveUR4ppU1lS4bGI1VN4=";
executable = true;
};
bootstrapTools = import <nix/fetchurl.nix> {
url = "http://tarballs.nixos.org/stdenv-linux/powerpc64le/ac43c444780a80e789fd14fe2114acd4a3b5cf9d/bootstrap-tools.tar.xz";
sha256 = "sha256-MpIDnpZUK3M17qlnuoxfnK0EgxRosm3TMW1WfPZ1+jU=";
};
}

View File

@@ -0,0 +1,26 @@
#
# Files came from this Hydra build:
#
# https://hydra.nixos.org/build/246376732
#
# Which used nixpkgs revision 160cedc144aced7a35a91440b46b74ffacd52682
# to instantiate:
#
# /nix/store/cpiajh4l83b08pynwiwkpxj53d78pcxr-stdenv-bootstrap-tools-riscv64-unknown-linux-gnu.drv
#
# and then built:
#
# /nix/store/8a92pj40awdw585mcb9dvm4nyb03k3q3-stdenv-bootstrap-tools-riscv64-unknown-linux-gnu
#
{
busybox = import <nix/fetchurl.nix> {
url = "http://tarballs.nixos.org/stdenv-linux/riscv64/160cedc144aced7a35a91440b46b74ffacd52682/busybox";
sha256 = "sha256-OGO96QUzs2n5pGipn/V87AxzUY9OWKZl417nE8HdZIE=";
executable = true;
};
bootstrapTools = import <nix/fetchurl.nix> {
url = "http://tarballs.nixos.org/stdenv-linux/riscv64/160cedc144aced7a35a91440b46b74ffacd52682/bootstrap-tools.tar.xz";
sha256 = "sha256-0LxRd7fdafQezNJ+N2tuOfm0KEwgfRSts5fhP0e0r0s=";
};
}

View File

@@ -0,0 +1,21 @@
# Autogenerated by maintainers/scripts/bootstrap-files/refresh-tarballs.bash as:
# $ ./refresh-tarballs.bash --targets=s390x-unknown-linux-gnu
#
# Metadata:
# - nixpkgs revision: 0a7eaa55ccaa5103f44a9a4e3e0b06e5314a6401
# - hydra build: https://hydra.nixos.org/job/nixpkgs/cross-trunk/bootstrapTools.s390x-unknown-linux-gnu.build/latest
# - resolved hydra build: https://hydra.nixos.org/build/268609502
# - instantiated derivation: /nix/store/x66rrb9wv612n37bj6iggr2vg313hs77-stdenv-bootstrap-tools-s390x-unknown-linux-gnu.drv
# - output directory: /nix/store/ijkl5anf7mx1p3whdkxv4qs5crf6ic35-stdenv-bootstrap-tools-s390x-unknown-linux-gnu
# - build time: Mon, 05 Aug 2024 17:28:42 +0000
{
bootstrapTools = import <nix/fetchurl.nix> {
url = "http://tarballs.nixos.org/stdenv/s390x-unknown-linux-gnu/0a7eaa55ccaa5103f44a9a4e3e0b06e5314a6401/bootstrap-tools.tar.xz";
hash = "sha256-HYooNwkStp9Q1nZOw9celEiQPWwU7iSHP1iaxodBv1g=";
};
busybox = import <nix/fetchurl.nix> {
url = "http://tarballs.nixos.org/stdenv/s390x-unknown-linux-gnu/0a7eaa55ccaa5103f44a9a4e3e0b06e5314a6401/busybox";
hash = "sha256-8BUGvp0gm4v3qBemF/kTVVCsu3ydWLGRVPulBsAL+MI=";
executable = true;
};
}

View File

@@ -0,0 +1,21 @@
# Autogenerated by maintainers/scripts/bootstrap-files/refresh-tarballs.bash as:
# $ ./refresh-tarballs.bash --targets=x86_64-unknown-linux-gnu
#
# Metadata:
# - nixpkgs revision: 82b583ba2ba2e5706b35dbe23f31362e62be2a9d
# - hydra build: https://hydra.nixos.org/job/nixpkgs/trunk/stdenvBootstrapTools.x86_64-unknown-linux-gnu.build/latest
# - resolved hydra build: https://hydra.nixos.org/build/249165517
# - instantiated derivation: /nix/store/7g8mrv13mi4zrx66fw0hy4c46j752wfd-stdenv-bootstrap-tools.drv
# - output directory: /nix/store/dw6vr6m5w7ysrdrbs0s5wdgbjmbnr7gx-stdenv-bootstrap-tools
# - build time: Sat, 10 Feb 2024 01:29:55 +0000
{
bootstrapTools = import <nix/fetchurl.nix> {
url = "http://tarballs.nixos.org/stdenv/x86_64-unknown-linux-gnu/82b583ba2ba2e5706b35dbe23f31362e62be2a9d/bootstrap-tools.tar.xz";
hash = "sha256-YQlr088HPoVWBU2jpPhpIMyOyoEDZYDw1y60SGGbUM0=";
};
busybox = import <nix/fetchurl.nix> {
url = "http://tarballs.nixos.org/stdenv/x86_64-unknown-linux-gnu/82b583ba2ba2e5706b35dbe23f31362e62be2a9d/busybox";
hash = "sha256-QrTEnQTBM1Y/qV9odq8irZkQSD9uOMbs2Q5NgCvKCNQ=";
executable = true;
};
}

View File

@@ -0,0 +1,21 @@
# Autogenerated by maintainers/scripts/bootstrap-files/refresh-tarballs.bash as:
# $ ./refresh-tarballs.bash --targets=x86_64-unknown-linux-musl
#
# Metadata:
# - nixpkgs revision: 125cefd4cf8f857e5ff1aceaef9230ba578a033d
# - hydra build: https://hydra.nixos.org/job/nixpkgs/trunk/stdenvBootstrapTools.x86_64-unknown-linux-musl.build/latest
# - resolved hydra build: https://hydra.nixos.org/build/247890807
# - instantiated derivation: /nix/store/gqri9n85rsf2983r6m8lkz0h69k4n7xi-stdenv-bootstrap-tools.drv
# - output directory: /nix/store/b0x0qcbf1gsp50jzw52sbbgdp3jlwcjf-stdenv-bootstrap-tools
# - build time: Fri, 26 Jan 2024 22:09:22 +0000
{
bootstrapTools = import <nix/fetchurl.nix> {
url = "http://tarballs.nixos.org/stdenv/x86_64-unknown-linux-musl/125cefd4cf8f857e5ff1aceaef9230ba578a033d/bootstrap-tools.tar.xz";
hash = "sha256-t0W2MR7UwtPyYEGcRo9UOuXfaP4uUZKZXEmYGcBOuOA=";
};
busybox = import <nix/fetchurl.nix> {
url = "http://tarballs.nixos.org/stdenv/x86_64-unknown-linux-musl/125cefd4cf8f857e5ff1aceaef9230ba578a033d/busybox";
hash = "sha256-0U2r3EU61oqhs+oyzFABIFTCVqXOWSP0qEtnyHwjzm0=";
executable = true;
};
}

View File

@@ -0,0 +1,35 @@
{
lib,
libc,
config,
system,
bootstrapFiles,
isFromBootstrapFiles ? false,
}:
let
maybeDenoteProvenance = lib.optionalAttrs isFromBootstrapFiles {
passthru = {
inherit isFromBootstrapFiles;
};
};
maybeContentAddressed = lib.optionalAttrs config.contentAddressedByDefault {
__contentAddressed = true;
outputHashAlgo = "sha256";
outputHashMode = "recursive";
};
args = {
inherit system bootstrapFiles;
extraAttrs = maybeContentAddressed;
};
result =
if libc == "glibc" then
import ./glibc.nix args
else if libc == "musl" then
import ./musl.nix args
else
throw "unsupported libc";
in
result // maybeDenoteProvenance

View File

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

View File

@@ -0,0 +1,77 @@
# 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
# path to version-specific libraries, like libstdc++.so
LIBSTDCXX_SO_DIR=$(echo $out/lib/gcc/*/*)
# Move version-specific libraries out to avoid library mix when we
# upgrade gcc.
# TODO(trofi): update bootstrap tarball script and tarballs to put them
# into expected location directly.
LD_LIBRARY_PATH=$out/lib $LD_BINARY $out/bin/mv $out/lib/libstdc++.* $LIBSTDCXX_SO_DIR/
# 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 .
# Older versions of the bootstrap-files did not compile their
# patchelf with -static-libgcc, so we have to be very careful not to
# run patchelf on the same copy of libgcc_s that it links against.
LD_LIBRARY_PATH=$out/lib $LD_BINARY $out/bin/cp $out/lib/libgcc_s.so.1 .
LD_LIBRARY_PATH=.:$out/lib:$LIBSTDCXX_SO_DIR $LD_BINARY \
./patchelf --set-rpath $out/lib --force-rpath $out/lib/libgcc_s.so.1
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:$LIBSTDCXX_SO_DIR $LD_BINARY \
./patchelf --set-interpreter $LD_BINARY --set-rpath $out/lib:$LIBSTDCXX_SO_DIR --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,36 @@
{
system,
bootstrapFiles,
extraAttrs,
}:
derivation (
{
name = "bootstrap-tools";
builder = bootstrapFiles.busybox;
args = [
"ash"
"-e"
./musl/unpack-bootstrap-tools.sh
];
tarball = bootstrapFiles.bootstrapTools;
inherit system;
# Needed by the GCC wrapper.
langC = true;
langCC = true;
isGNU = true;
hardeningUnsupportedFlags = [
"fortify3"
"shadowstack"
"pacret"
"zerocallusedregs"
"trivialautovarinit"
];
}
// 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,951 @@
# This file constructs the standard build environment for the
# Linux 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.
#
# It starts from prebuilt seed bootstrapFiles and creates a series of
# nixpkgs instances (stages) to gradually rebuild stdenv, which
# is used to build all other packages (including the bootstrapFiles).
#
# Goals of the bootstrap process:
# 1. final stdenv must not reference any of the bootstrap files.
# 2. final stdenv must not contain any of the bootstrap files.
# 3. final stdenv must not contain any of the files directly
# generated by the bootstrap code generators (assembler, linker,
# compiler).
#
# These goals ensure that final packages and final stdenv are built
# exclusively using nixpkgs package definitions and don't depend
# on bootstrapTools (via direct references, inclusion
# of copied code, or code compiled directly by bootstrapTools).
#
# Stages are described below along with their definitions.
#
# Debugging stdenv dependency graph:
# A useful tool to explore dependencies across stages is to use
# '__bootPackages' attribute of 'stdenv. Examples of last 3 stages:
# - stdenv
# - stdenv.__bootPackages.stdenv
# - stdenv.__bootPackages.stdenv.__bootPackages.stdenv
# - ... and so on.
#
# To explore build-time dependencies in graphical form one can use
# the following:
# $ nix-store --query --graph $(nix-instantiate -A stdenv) |
# grep -P -v '[.]sh|[.]patch|bash|[.]tar' | # avoid clutter
# dot -Tsvg > stdenv-final.svg
#
# To find all the packages built by a particular stdenv instance:
# $ for stage in 0 1 2 3 4; do
# echo "stage${stage} used in:"
# nix-store --query --graph $(nix-instantiate -A stdenv) |
# grep -P ".*bootstrap-stage${stage}-stdenv.*->.*" |
# sed 's/"[0-9a-z]\{32\}-/"/g'
# done
#
# To verify which stdenv was used to build a given final package:
# $ nix-store --query --graph $(nix-instantiate -A stdenv) |
# grep -P -v '[.]sh|[.]patch|bash|[.]tar' |
# grep -P '.*stdenv.*->.*glibc-2'
# "...-bootstrap-stage2-stdenv-linux.drv" -> "...-glibc-2.35-224.drv";
#
# For a TUI (rather than CLI) view, you can use:
#
# $ nix-tree --derivation $(nix-instantiate -A stdenv)
{
lib,
localSystem,
crossSystem,
config,
overlays,
crossOverlays ? [ ],
bootstrapFiles ?
let
table = {
glibc = {
i686-linux = import ./bootstrap-files/i686-unknown-linux-gnu.nix;
x86_64-linux = import ./bootstrap-files/x86_64-unknown-linux-gnu.nix;
armv5tel-linux = import ./bootstrap-files/armv5tel-unknown-linux-gnueabi.nix;
armv6l-linux = import ./bootstrap-files/armv6l-unknown-linux-gnueabihf.nix;
armv7l-linux = import ./bootstrap-files/armv7l-unknown-linux-gnueabihf.nix;
aarch64-linux = import ./bootstrap-files/aarch64-unknown-linux-gnu.nix;
mipsel-linux = import ./bootstrap-files/mipsel-unknown-linux-gnu.nix;
mips64el-linux = import (
if localSystem.isMips64n32 then
./bootstrap-files/mips64el-unknown-linux-gnuabin32.nix
else
./bootstrap-files/mips64el-unknown-linux-gnuabi64.nix
);
powerpc64-linux = import (
if localSystem.isAbiElfv2 then
./bootstrap-files/powerpc64-unknown-linux-gnuabielfv2.nix
else
./bootstrap-files/powerpc64-unknown-linux-gnuabielfv1.nix
);
powerpc64le-linux = import ./bootstrap-files/powerpc64le-unknown-linux-gnu.nix;
riscv64-linux = import ./bootstrap-files/riscv64-unknown-linux-gnu.nix;
s390x-linux = import ./bootstrap-files/s390x-unknown-linux-gnu.nix;
loongarch64-linux = import ./bootstrap-files/loongarch64-unknown-linux-gnu.nix;
};
musl = {
aarch64-linux = import ./bootstrap-files/aarch64-unknown-linux-musl.nix;
armv6l-linux = import ./bootstrap-files/armv6l-unknown-linux-musleabihf.nix;
x86_64-linux = import ./bootstrap-files/x86_64-unknown-linux-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 (throw "unsupported libc for the pure Linux stdenv");
files =
archLookupTable.${localSystem.system} or (
if getCompatibleTools != null then
getCompatibleTools
else
(throw "unsupported platform for the pure Linux stdenv")
);
in
(config.replaceBootstrapFiles or lib.id) files,
}:
assert crossSystem == localSystem;
let
inherit (localSystem) system;
isFromNixpkgs = pkg: !(isFromBootstrapFiles pkg);
isFromBootstrapFiles = pkg: pkg.passthru.isFromBootstrapFiles or false;
isBuiltByNixpkgsCompiler = pkg: isFromNixpkgs pkg && isFromNixpkgs pkg.stdenv.cc.cc;
isBuiltByBootstrapFilesCompiler = pkg: isFromNixpkgs pkg && isFromBootstrapFiles pkg.stdenv.cc.cc;
commonGccOverrides = {
# Use a deterministically built compiler
# see https://github.com/NixOS/nixpkgs/issues/108475 for context
reproducibleBuild = true;
profiledCompiler = false;
# It appears that libcc1 (which is not a g++ plugin; it is a gdb plugin) gets linked against
# the libstdc++ from the compiler that *built* g++, not the libstdc++ which was just built.
# This causes a reference chain from stdenv to the bootstrapFiles:
#
# stdenv -> gcc-lib -> xgcc-lib -> bootstrapFiles
#
disableGdbPlugin = true;
};
commonPreHook = ''
export NIX_ENFORCE_PURITY="''${NIX_ENFORCE_PURITY-1}"
export NIX_ENFORCE_NO_NATIVE="''${NIX_ENFORCE_NO_NATIVE-1}"
'';
# 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 ./bootstrap-tools {
inherit (localSystem) libc system;
inherit lib bootstrapFiles config;
isFromBootstrapFiles = true;
};
# 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;
inherit (config) rewriteURL;
};
cc =
if prevStage.gcc-unwrapped == null then
null
else
(lib.makeOverridable (import ../../build-support/cc-wrapper) {
name = "${name}-gcc-wrapper";
nativeTools = false;
nativeLibc = false;
expand-response-params = lib.optionalString (
prevStage.stdenv.hasCC or false && prevStage.stdenv.cc != "/dev/null"
) prevStage.expand-response-params;
cc = prevStage.gcc-unwrapped;
bintools = prevStage.binutils;
isGNU = true;
inherit (prevStage) libc;
inherit lib;
inherit (prevStage) coreutils gnugrep;
stdenvNoCC = prevStage.ccWrapperStdenv;
fortify-headers = prevStage.fortify-headers;
runtimeShell = prevStage.ccWrapperStdenv.shell;
}).overrideAttrs
(
a:
lib.optionalAttrs (prevStage.gcc-unwrapped.passthru.isXgcc or false) {
# This affects only `xgcc` (the compiler which compiles the final compiler).
postFixup = (a.postFixup or "") + ''
echo "--sysroot=${lib.getDev prevStage.libc}" >> $out/nix-support/cc-cflags
'';
}
);
overrides = self: super: (overrides self super) // { fetchurl = thisStdenv.fetchurlBoot; };
};
in
{
inherit config overlays;
stdenv = thisStdenv;
};
in
assert bootstrapTools.passthru.isFromBootstrapFiles or false; # sanity check
[
(
{ }:
{
__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 = "bootstrapFiles";
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
'';
passthru.isFromBootstrapFiles = true;
};
gcc-unwrapped = bootstrapTools;
binutils = import ../../build-support/bintools-wrapper {
name = "bootstrap-stage0-binutils-wrapper";
nativeTools = false;
nativeLibc = false;
expand-response-params = "";
inherit lib;
inherit (self)
stdenvNoCC
coreutils
gnugrep
libc
;
bintools = bootstrapTools;
runtimeShell = "${bootstrapTools}/bin/bash";
};
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:
# previous stage0 stdenv:
assert isFromBootstrapFiles prevStage.binutils.bintools;
assert isFromBootstrapFiles prevStage."${localSystem.libc}";
assert isFromBootstrapFiles prevStage.libc;
assert isFromBootstrapFiles prevStage.gcc-unwrapped;
assert isFromBootstrapFiles prevStage.coreutils;
assert isFromBootstrapFiles prevStage.gnugrep;
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
binutils
;
${localSystem.libc} = prevStage.${localSystem.libc};
# 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;
enableCrypt = false;
};
# Let gettext "checking for working iconv" success without trying
# to convert between UTF-8 and EUC-JP which doesn't work here
# because of missing locale and gconv, same for libunistring below
gettext = super.gettext.overrideAttrs (attrs: {
env = attrs.env or { } // {
am_cv_func_iconv_works = "yes";
};
});
};
# `gettext` comes with obsolete config.sub/config.guess that don't recognize LoongArch64.
extraNativeBuildInputs = [ prevStage.updateAutotoolsGnuConfigScriptsHook ];
}
)
# First rebuild of gcc; this is linked against all sorts of junk
# from the bootstrap-files, but we only care about the code that
# this compiler *emits*. The `gcc` binary produced in this stage
# is not part of the final stdenv.
(
prevStage:
assert isBuiltByBootstrapFilesCompiler prevStage.binutils-unwrapped;
assert isFromBootstrapFiles prevStage."${localSystem.libc}";
assert isFromBootstrapFiles prevStage.libc;
assert isFromBootstrapFiles prevStage.gcc-unwrapped;
assert isFromBootstrapFiles prevStage.coreutils;
assert isFromBootstrapFiles prevStage.gnugrep;
assert isBuiltByBootstrapFilesCompiler prevStage.patchelf;
stageFun prevStage {
name = "bootstrap-stage-xgcc";
overrides = self: super: {
inherit (prevStage)
ccWrapperStdenv
coreutils
gnugrep
gettext
bison
texinfo
zlib
gnum4
perl
patchelf
;
${localSystem.libc} = prevStage.${localSystem.libc};
gmp = super.gmp.override { cxx = false; };
# This stage also rebuilds binutils which will of course be used only in the next stage.
# We inherit this until stage3, in stage4 it will be rebuilt using the adjacent bash/runtimeShell pkg.
# TODO(@sternenseemann): Can we already build the wrapper with the actual runtimeShell here?
# Historically, the wrapper didn't use runtimeShell, so the used shell had to be changed explicitly
# (or stdenvNoCC.shell would be used) which happened in stage4.
binutils = super.binutils.override {
runtimeShell = "${bootstrapTools}/bin/bash";
};
gcc-unwrapped =
(super.gcc-unwrapped.override (
commonGccOverrides
// {
# The most logical name for this package would be something like
# "gcc-stage1". Unfortunately "stage" is already reserved for the
# layers of stdenv, so using "stage" in the name of this package
# would cause massive confusion.
#
# Gcc calls its "stage1" compiler `xgcc` (--disable-bootstrap results
# in `xgcc` being copied to $prefix/bin/gcc). So we imitate that.
#
name = "xgcc";
# xgcc uses ld linked against nixpkgs' glibc and gcc built
# against bootstrapTools glibc. We can't allow loading
# $out/libexec/gcc/x86_64-unknown-linux-gnu/13.0.1/liblto_plugin.so
# to mix libc.so:
# ...-binutils-patchelfed-ld-2.40/bin/ld: ...-xgcc-13.0.0/libexec/gcc/x86_64-unknown-linux-gnu/13.0.1/liblto_plugin.so:
# error loading plugin: ...-bootstrap-tools/lib/libpthread.so.0: undefined symbol: __libc_vfork, version GLIBC_PRIVATE
enableLTO = false;
# relocatable libs may not be available in the bootstrap
# which will cause compilation to fail with
# configure: error: C compiler cannot create executables
enableDefaultPie = false;
}
)).overrideAttrs
(a: {
# This signals to cc-wrapper (as overridden above in this file) to add `--sysroot`
# to `$out/nix-support/cc-cflags`.
passthru = a.passthru // {
isXgcc = true;
};
# Gcc will look for the C library headers in
#
# ${with_build_sysroot}${native_system_header_dir}
#
# The ordinary gcc expression sets `--with-build-sysroot=/` and sets
# `native-system-header-dir` to `"${lib.getDev stdenv.cc.libc}/include`.
#
# Unfortunately the value of "--with-native-system-header-dir=" gets "burned in" to the
# compiler, and it is quite difficult to get the compiler to change or ignore it
# afterwards. On the other hand, the `sysroot` is very easy to change; you can just pass
# a `--sysroot` flag to `gcc`.
#
# So we override the expression to remove the default settings for these flags, and
# replace them such that the concatenated value will be the same as before, but we split
# the value between the two variables differently: `--native-system-header-dir=/include`,
# and `--with-build-sysroot=${lib.getDev stdenv.cc.libc}`.
#
configureFlags = (a.configureFlags or [ ]) ++ [
"--with-native-system-header-dir=/include"
"--with-build-sysroot=${lib.getDev self.stdenv.cc.libc}"
# Don't assume that `gettext` was built with iconv support, since we don't have
# our own `glibc` yet.
"--disable-nls"
];
# This is a separate phase because gcc assembles its phase scripts
# in bash instead of nix (we should fix that).
preFixupPhases = (a.preFixupPhases or [ ]) ++ [ "preFixupXgccPhase" ];
# This is needed to prevent "error: cycle detected in build of '...-xgcc-....drv'
# in the references of output 'lib' from output 'out'"
preFixupXgccPhase = ''
find $lib/lib/ -name \*.so\* -exec patchelf --shrink-rpath {} \; || true
'';
});
};
# `gettext` comes with obsolete config.sub/config.guess that don't recognize LoongArch64.
extraNativeBuildInputs = [ prevStage.updateAutotoolsGnuConfigScriptsHook ];
}
)
# 2nd stdenv that contains our own rebuilt binutils and is used for
# compiling our own Glibc.
#
(
prevStage:
# previous stage1 stdenv:
assert isBuiltByBootstrapFilesCompiler prevStage.binutils-unwrapped;
assert isFromBootstrapFiles prevStage."${localSystem.libc}";
assert isFromBootstrapFiles prevStage.libc;
assert isBuiltByBootstrapFilesCompiler prevStage.gcc-unwrapped;
assert isFromBootstrapFiles prevStage.coreutils;
assert isFromBootstrapFiles prevStage.gnugrep;
assert isBuiltByBootstrapFilesCompiler prevStage.patchelf;
stageFun prevStage {
name = "bootstrap-stage2";
overrides = self: super: {
inherit (prevStage)
ccWrapperStdenv
gettext
gcc-unwrapped
coreutils
gnugrep
perl
gnum4
bison
texinfo
which
;
dejagnu = super.dejagnu.overrideAttrs (a: {
doCheck = false;
});
# Avoids infinite recursion, as this is in the build-time dependencies of libc.
libiconv = self.libcIconv prevStage.libc;
# 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.
env = attrs.env or { } // {
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.
inherit (self) libc;
# 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 {
pname = prevStage.bintools.bintools.pname + "-patchelfed-ld";
inherit (prevStage.bintools.bintools) version;
passthru = { inherit (prevStage.bintools.passthru) isFromBootstrapFiles; };
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 '${self.libc}'/lib/ld*.so.? \
--set-rpath "${self.libc}/lib:$(patchelf --print-rpath "$out"/bin/ld.bfd)" \
"$out"/bin/ld.bfd
'';
};
};
# TODO(amjoseph): It is not yet entirely clear why this is necessary.
# Something strange is going on with xgcc and libstdc++ on pkgsMusl.
patchelf = super.patchelf.overrideAttrs (
previousAttrs:
lib.optionalAttrs super.stdenv.hostPlatform.isMusl {
NIX_CFLAGS_COMPILE = (previousAttrs.NIX_CFLAGS_COMPILE or "") + " -static-libstdc++";
}
);
};
# `gettext` comes with obsolete config.sub/config.guess that don't recognize LoongArch64.
# `libtool` comes with obsolete config.sub/config.guess that don't recognize Risc-V.
extraNativeBuildInputs = [ 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:
# previous stage2 stdenv:
assert isBuiltByNixpkgsCompiler prevStage.binutils-unwrapped;
assert isBuiltByNixpkgsCompiler prevStage.${localSystem.libc};
assert isBuiltByNixpkgsCompiler prevStage.libc;
assert isBuiltByBootstrapFilesCompiler prevStage.gcc-unwrapped;
assert isFromBootstrapFiles prevStage.coreutils;
assert isFromBootstrapFiles prevStage.gnugrep;
assert isBuiltByNixpkgsCompiler prevStage.patchelf;
assert lib.all isBuiltByNixpkgsCompiler [
prevStage.gmp
prevStage.isl_0_20
prevStage.libmpc
prevStage.mpfr
];
stageFun prevStage {
name = "bootstrap-stage3";
overrides =
self: super:
{
inherit (prevStage)
ccWrapperStdenv
binutils
coreutils
gnugrep
perl
patchelf
linuxHeaders
gnum4
bison
libidn2
libunistring
libxcrypt
;
# We build a special copy of libgmp which doesn't use libstdc++, because
# xgcc++'s libstdc++ references the bootstrap-files (which is what
# compiles xgcc++).
gmp = super.gmp.override { cxx = false; };
}
// {
${localSystem.libc} = prevStage.${localSystem.libc};
gcc-unwrapped =
(super.gcc-unwrapped.override (
commonGccOverrides
// {
inherit (prevStage) which;
}
)).overrideAttrs
(a: {
# so we can add them to allowedRequisites below
passthru = a.passthru // {
inherit (self)
gmp
mpfr
libmpc
isl
;
};
});
};
extraNativeBuildInputs = [
prevStage.patchelf
# Many tarballs come with obsolete config.sub/config.guess that don't recognize aarch64.
prevStage.updateAutotoolsGnuConfigScriptsHook
];
}
)
# Construct a fourth stdenv that uses the new GCC. But coreutils is
# still from the bootstrap tools.
#
(
prevStage:
# previous stage3 stdenv:
assert isBuiltByNixpkgsCompiler prevStage.binutils-unwrapped;
assert isBuiltByNixpkgsCompiler prevStage.${localSystem.libc};
assert isBuiltByNixpkgsCompiler prevStage.libc;
assert isBuiltByNixpkgsCompiler prevStage.gcc-unwrapped;
assert isFromBootstrapFiles prevStage.coreutils;
assert isFromBootstrapFiles prevStage.gnugrep;
assert isBuiltByNixpkgsCompiler prevStage.patchelf;
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
perl
texinfo
zlib
linuxHeaders
libidn2
libunistring
;
${localSystem.libc} = prevStage.${localSystem.libc};
# Since this is the first fresh build of binutils since stage2, our own runtimeShell will be used.
binutils = super.binutils.override {
# Build expand-response-params with last stage like below
inherit (prevStage) expand-response-params;
};
# To allow users' overrides inhibit dependencies too heavy for
# bootstrap, like guile: https://github.com/NixOS/nixpkgs/issues/181188
gnumake = super.gnumake.override { inBootstrap = true; };
gcc = lib.makeOverridable (import ../../build-support/cc-wrapper) {
nativeTools = false;
nativeLibc = false;
isGNU = true;
inherit (prevStage) expand-response-params;
cc = prevStage.gcc-unwrapped;
bintools = self.binutils;
inherit lib;
inherit (self)
stdenvNoCC
coreutils
gnugrep
runtimeShell
libc
;
fortify-headers = self.fortify-headers;
};
};
extraNativeBuildInputs = [
prevStage.patchelf
prevStage.xz
# Many tarballs come with obsolete config.sub/config.guess that don't recognize aarch64.
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:
# previous stage4 stdenv; see stage3 comment regarding gcc,
# which applies here as well.
assert isBuiltByNixpkgsCompiler prevStage.binutils-unwrapped;
assert isBuiltByNixpkgsCompiler prevStage.${localSystem.libc};
assert isBuiltByNixpkgsCompiler prevStage.libc;
assert isBuiltByNixpkgsCompiler prevStage.gcc-unwrapped;
assert isBuiltByNixpkgsCompiler prevStage.coreutils;
assert isBuiltByNixpkgsCompiler prevStage.gnugrep;
assert isBuiltByNixpkgsCompiler prevStage.patchelf;
{
inherit config overlays;
stdenv = import ../generic rec {
name = "stdenv-linux";
buildPlatform = localSystem;
hostPlatform = localSystem;
targetPlatform = localSystem;
inherit config;
preHook = commonPreHook;
initialPath = ((import ../generic/common-path.nix) { pkgs = prevStage; });
extraNativeBuildInputs = [
prevStage.patchelf
# Many tarballs come with obsolete config.sub/config.guess that don't recognize aarch64.
prevStage.updateAutotoolsGnuConfigScriptsHook
];
cc = prevStage.gcc;
shell = cc.shell;
inherit (prevStage.stdenv) fetchurlBoot;
extraAttrs = {
inherit bootstrapTools;
shellPackage = prevStage.bash;
};
disallowedRequisites = [ bootstrapTools.out ];
# Mainly avoid reference to bootstrap tools
allowedRequisites =
let
inherit (prevStage)
gzip
bzip2
xz
zlib
bashNonInteractive
binutils
coreutils
diffutils
findutils
gawk
gmp
gnumake
gnused
gnutar
gnugrep
gnupatch
patchelf
ed
file
glibc
attr
acl
libidn2
libunistring
linuxHeaders
gcc
fortify-headers
gcc-unwrapped
;
in
# Simple executable tools
lib.concatMap
(p: [
(lib.getBin p)
(lib.getLib p)
])
[
gzip
bzip2
xz
bashNonInteractive
binutils.bintools
coreutils
diffutils
findutils
gawk
gmp
gnumake
gnused
gnutar
gnugrep
gnupatch
patchelf
ed
file
]
# Library dependencies
++ map lib.getLib [
attr
acl
zlib
gnugrep.pcre2
libidn2
libunistring
]
# More complicated cases
++ (map (x: lib.getOutput x (prevStage.libc)) [
"out"
"dev"
"bin"
])
++ [
linuxHeaders # propagated from .dev
binutils
gcc
gcc.cc
gcc.cc.lib
gcc.expand-response-params # != (prevStage.)expand-response-params
gcc.cc.libgcc
glibc.passthru.libgcc
]
++ lib.optionals (localSystem.libc == "musl") [ fortify-headers ]
++ [
prevStage.updateAutotoolsGnuConfigScriptsHook
prevStage.gnu-config
]
++ [
gcc-unwrapped.gmp
gcc-unwrapped.libmpc
gcc-unwrapped.mpfr
gcc-unwrapped.isl
];
overrides =
self: super:
{
inherit (prevStage)
gzip
bzip2
xz
bashNonInteractive
coreutils
diffutils
findutils
gawk
gnused
gnutar
gnugrep
gnupatch
patchelf
attr
acl
zlib
libunistring
;
inherit (prevStage.gnugrep) pcre2;
${localSystem.libc} = prevStage.${localSystem.libc};
# Hack: avoid libidn2.{bin,dev} referencing bootstrap tools. There's a logical cycle.
libidn2 = import ../../development/libraries/libidn2/no-bootstrap-reference.nix {
inherit lib;
inherit (prevStage) libidn2;
inherit (self)
stdenv
runCommandLocal
patchelf
libunistring
;
};
gnumake = super.gnumake.override { inBootstrap = false; };
}
// lib.optionalAttrs (super.stdenv.targetPlatform == localSystem) {
# Need to get rid of these when cross-compiling.
inherit (prevStage) binutils binutils-unwrapped;
gcc = cc;
};
};
}
)
# This "no-op" stage is just a place to put the assertions about stage5.
(
prevStage:
# previous stage5 stdenv; see stage3 comment regarding gcc,
# which applies here as well.
assert isBuiltByNixpkgsCompiler prevStage.binutils-unwrapped;
assert isBuiltByNixpkgsCompiler prevStage.${localSystem.libc};
assert isBuiltByNixpkgsCompiler prevStage.libc;
assert isBuiltByNixpkgsCompiler prevStage.gcc-unwrapped;
assert isBuiltByNixpkgsCompiler prevStage.coreutils;
assert isBuiltByNixpkgsCompiler prevStage.gnugrep;
assert isBuiltByNixpkgsCompiler prevStage.patchelf;
{
inherit (prevStage) config overlays stdenv;
}
)
]

View File

@@ -0,0 +1,48 @@
{
system ? builtins.currentSystem,
}:
let
inherit (releaseLib) lib;
releaseLib = import ../../top-level/release-lib.nix {
# We're not using any functions from release-lib.nix that look at
# supportedSystems.
supportedSystems = [ ];
};
make =
crossSystem:
import ./make-bootstrap-tools.nix {
pkgs = releaseLib.pkgsForCross crossSystem system;
};
in
lib.mapAttrs (n: make) (
with lib.systems.examples;
{
# NOTE: Only add platforms for which there are files in `./bootstrap-files`
# or for which you plan to request the tarball upload soon. See the
# maintainers/scripts/bootstrap-files/README.md
# on how to request an upload.
# Sort following the sorting in `./default.nix` `bootstrapFiles` argument.
armv5tel-unknown-linux-gnueabi = sheevaplug;
armv6l-unknown-linux-gnueabihf = raspberryPi;
armv7l-unknown-linux-gnueabihf = armv7l-hf-multiplatform;
aarch64-unknown-linux-gnu = aarch64-multiplatform;
mipsel-unknown-linux-gnu = mipsel-linux-gnu;
mips64el-unknown-linux-gnuabin32 = mips64el-linux-gnuabin32;
mips64el-unknown-linux-gnuabi64 = mips64el-linux-gnuabi64;
powerpc64-unknown-linux-gnuabielfv1 = ppc64-elfv1;
powerpc64-unknown-linux-gnuabielfv2 = ppc64-elfv2;
powerpc64le-unknown-linux-gnu = powernv;
riscv64-unknown-linux-gnu = riscv64;
s390x-unknown-linux-gnu = s390x;
loongarch64-unknown-linux-gnu = loongarch64-linux;
# musl
aarch64-unknown-linux-musl = aarch64-multiplatform-musl;
armv6l-unknown-linux-musleabihf = muslpi;
riscv64-unknown-linux-musl = riscv64-musl;
x86_64-unknown-linux-musl = musl64;
}
)

View File

@@ -0,0 +1,98 @@
{
pkgs ? import ../../.. { },
}:
let
inherit (pkgs)
lib
stdenv
config
libc
;
patchelf = pkgs.patchelf.overrideAttrs (previousAttrs: {
NIX_CFLAGS_COMPILE = (previousAttrs.NIX_CFLAGS_COMPILE or [ ]) ++ [
"-static-libgcc"
"-static-libstdc++"
];
NIX_CFLAGS_LINK = (previousAttrs.NIX_CFLAGS_LINK or [ ]) ++ [
"-static-libgcc"
"-static-libstdc++"
];
});
in
rec {
coreutilsMinimal = pkgs.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 = pkgs.gnutar.override { acl = null; };
busyboxMinimal = pkgs.busybox.override {
useMusl = lib.meta.availableOn stdenv.hostPlatform pkgs.musl;
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 =
(pkgs.gcc.cc.override {
enableLTO = false;
isl = null;
}).overrideAttrs
(old: {
patches = old.patches or [ ] ++ [
(pkgs.fetchpatch {
# c++tools: Don't check --enable-default-pie.
# --enable-default-pie breaks bootstrap gcc otherwise, because libiberty.a is not found
url = "https://github.com/gcc-mirror/gcc/commit/3f1f99ef82a65d66e3aaa429bf4fb746b93da0db.patch";
hash = "sha256-wKVuwrW22gSN1woYFYxsyVk49oYmbogIN6FWbU8cVds=";
})
];
});
bootBinutils = pkgs.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 = pkgs.callPackage ./stdenv-bootstrap-tools.nix {
inherit
bootBinutils
coreutilsMinimal
tarMinimal
busyboxMinimal
bootGCC
libc
patchelf
;
};
inherit (build) bootstrapFiles;
bootstrapTools = import ./bootstrap-tools {
inherit (stdenv.buildPlatform) system; # Used to determine where to build
inherit (stdenv.hostPlatform) libc;
inherit lib bootstrapFiles config;
};
test = pkgs.callPackage ./test-bootstrap-tools.nix {
inherit bootstrapTools;
inherit (bootstrapFiles) busybox;
};
}

View File

@@ -0,0 +1,218 @@
{
lib,
stdenv,
bashNonInteractive,
binutils,
bootBinutils,
bootGCC,
buildPackages,
busyboxMinimal,
bzip2,
coreutilsMinimal,
diffutils,
findutils,
gawk,
gmpxx,
gnugrep,
gnumake,
gnused,
gzip,
libc,
libmpc,
mpfr,
patch,
patchelf,
runCommand,
tarMinimal,
zlib,
}:
let
# ${libc.src}/sysdeps/unix/sysv/linux/loongarch/lp64/libnsl.abilist does not exist!
withLibnsl = !stdenv.hostPlatform.isLoongArch64;
in
stdenv.mkDerivation (finalAttrs: {
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
''
+ lib.optionalString withLibnsl ''
cp -d ${libc.out}/lib/libnsl*.so* $out/lib
''
+ ''
cp -d ${libc.out}/lib/libnss*.so* $out/lib
cp -d ${libc.out}/lib/libresolv*.so* $out/lib
# Copy all runtime files to enable non-PIE, PIE, static PIE and profile-generated builds
cp -d ${libc.out}/lib/*.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 ${bashNonInteractive.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-wrapped $out/bin/gzip
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.pcre2.out}/lib/libpcre2*.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 ${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
''
+ 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 = [ ];
passthru = {
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 ${finalAttrs.finalPackage}/on-server/busybox $out";
bootstrapTools =
runCommand "bootstrap-tools.tar.xz" { }
"cp ${finalAttrs.finalPackage}/on-server/bootstrap-tools.tar.xz $out";
};
};
})

View File

@@ -0,0 +1,70 @@
{
lib,
stdenv,
binutils,
busybox,
bootstrapTools,
hello,
}:
derivation {
name = "test-bootstrap-tools";
inherit (stdenv.hostPlatform) system; # We cannot "cross test"
builder = 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") ''
rtld=$(echo ${bootstrapTools}/lib/${builtins.unsafeDiscardStringContext # only basename
(baseNameOf binutils.dynamicLinker)})
libc_includes=${bootstrapTools}/include-glibc
''
+ lib.optionalString (stdenv.hostPlatform.libc == "musl") ''
rtld=$(echo ${bootstrapTools}/lib/ld-musl*.so.?)
libc_includes=${bootstrapTools}/include-libc
''
+ ''
# path to version-specific libraries, like libstdc++.so
cxx_libs=$(echo ${bootstrapTools}/lib/gcc/*/*)
export CPP="cpp -idirafter $libc_includes -B${bootstrapTools}"
export CC="gcc -idirafter $libc_includes -B${bootstrapTools} -Wl,-dynamic-linker,$rtld -Wl,-rpath,${bootstrapTools}/lib -Wl,-rpath,$cxx_libs"
export CXX="g++ -idirafter $libc_includes -B${bootstrapTools} -Wl,-dynamic-linker,$rtld -Wl,-rpath,${bootstrapTools}/lib -Wl,-rpath,$cxx_libs"
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,226 @@
{
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 =
(lib.optionals (system == "i686-solaris") [ "/usr/gnu" ])
++ (lib.optionals (system == "i686-netbsd") [ "/usr/pkg" ])
++ (lib.optionals (system == "x86_64-solaris") [ "/opt/local/gnu" ])
++ [
"/"
"/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;
inherit (config) hashedMirrors rewriteURL;
};
}
)
# First build a stdenv based only on tools outside the store.
(prevStage: {
inherit config overlays;
stdenv =
makeStdenv {
inherit (prevStage) cc fetchurl;
overrides = self: super: { inherit (prevStage) 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) fetchurl xz; };
extraNativeBuildInputs = if localSystem.isLinux then [ prevStage.patchelf ] else [ ];
};
})
]

View File

@@ -0,0 +1,73 @@
{
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 ../generic/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
;
};
};
})
]

View File

@@ -0,0 +1,14 @@
{ stdenv }:
stdenv.mkDerivation {
name = "stdenv-test-succeedOnFailure";
succeedOnFailure = true;
passAsFile = [ "buildCommand" ];
buildCommand = ''
mkdir $out
echo foo > $out/foo
exit 1
'';
}