Merge pull request #25099 from obsidiansystems/cross-lib-foundation

Changes to nixpkgs infra to prepare to better package some pesky cross-compilers

No hashes (native or cross) should be changed
This commit is contained in:
John Ericson 2017-04-23 14:12:42 -04:00 committed by GitHub
commit b59fdc4289
4 changed files with 58 additions and 7 deletions

View File

@ -167,6 +167,11 @@
Because of this, a best-of-both-worlds solution is in the works with no splicing or explicit access of <varname>buildPackages</varname> needed.
For now, feel free to use either method.
</para>
<note><para>
There is also a "backlink" <varname>__targetPackages</varname>, yielding a package set whose <varname>buildPackages</varname> is the current package set.
This is a hack, though, to accommodate compilers with lousy build systems.
Please do not use this unless you are absolutely sure you are packaging such a compiler and there is no other way.
</para></note>
</section>
</section>

View File

@ -41,6 +41,35 @@
# 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, `fold op lnul rnul [x_0 x_1 x_2 ... x_n-1]` is the
same as
let
f_-1 = lnul;
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;
in
f_0
*/
dfold = op: lnul: rnul: list:
let
len = builtins.length list;
go = pred: n:
if n == len
then rnul
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;
in go lnul 0;
# 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.
@ -55,19 +84,21 @@ stageFuns: let
# Adds the stdenv to the arguments, and sticks in it the previous stage for
# debugging purposes.
folder = stageFun: finalSoFar: let
args = stageFun finalSoFar;
folder = nextStage: stageFun: prevStage: let
args = stageFun prevStage;
args' = args // {
stdenv = args.stdenv // {
# For debugging
__bootPackages = finalSoFar;
__bootPackages = prevStage;
__hatPackages = nextStage;
};
};
in
if args.__raw or false
then args'
else allPackages ((builtins.removeAttrs args' ["selfBuild"]) // {
buildPackages = if args.selfBuild or true then null else finalSoFar;
buildPackages = if args.selfBuild or true then null else prevStage;
__targetPackages = if args.selfBuild or true then null else nextStage;
});
in lib.lists.fold folder {} withAllowCustomOverrides
in dfold folder {} {} withAllowCustomOverrides

View File

@ -64,7 +64,11 @@ let
splicedPackages =
if actuallySplice
then splicer defaultBuildScope defaultRunScope
then splicer defaultBuildScope defaultRunScope // {
# These should never be spliced under any circumstances
inherit (pkgs) pkgs buildPackages __targetPackages
buildPlatform targetPlatform hostPlatform;
}
else pkgs // pkgs.xorg;
in

View File

@ -46,9 +46,18 @@
##
, # The package set used at build-time. If null, `buildPackages` will
# be defined internally as the produced package set as itself.
# be defined internally as the final produced package set itself. This allows
# us to avoid expensive splicing.
buildPackages
, # The package set used in the next stage. If null, `__targetPackages` will be
# defined internally as the final produced package set itself, just like with
# `buildPackages` and for the same reasons.
#
# THIS IS A HACK for compilers that don't think critically about cross-
# compilation. Please do *not* use unless you really know what you are doing.
__targetPackages
, # The standard environment to use for building packages.
stdenv
@ -87,6 +96,8 @@ let
stdenvBootstappingAndPlatforms = self: super: {
buildPackages = (if buildPackages == null then self else buildPackages)
// { recurseForDerivations = false; };
__targetPackages = (if __targetPackages == null then self else __targetPackages)
// { recurseForDerivations = false; };
inherit stdenv
buildPlatform hostPlatform targetPlatform;
};