mirror of
https://github.com/NixOS/nixpkgs.git
synced 2024-11-25 16:33:15 +00:00
top-level: Introduce targetPackages and a "double link fold"
Each bootstrapping stage ought to just depend on the previous stage, but poorly-written compilers break this elegence. This provides an easy-enough way to depend on the next stage: targetPackages. PLEASE DO NOT USE IT UNLESS YOU MUST! I'm hoping someday in a pleasant future I can revert this commit :)
This commit is contained in:
parent
d59e4fbb75
commit
863d79b364
@ -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.
|
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.
|
For now, feel free to use either method.
|
||||||
</para>
|
</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>
|
||||||
|
|
||||||
</section>
|
</section>
|
||||||
|
@ -41,6 +41,35 @@
|
|||||||
# other words, this does a foldr not foldl.
|
# other words, this does a foldr not foldl.
|
||||||
stageFuns: let
|
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,
|
# 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
|
# and allow it in the final flag. Only defaults this boolean field if it
|
||||||
# isn't already set.
|
# isn't already set.
|
||||||
@ -55,19 +84,21 @@ stageFuns: let
|
|||||||
|
|
||||||
# Adds the stdenv to the arguments, and sticks in it the previous stage for
|
# Adds the stdenv to the arguments, and sticks in it the previous stage for
|
||||||
# debugging purposes.
|
# debugging purposes.
|
||||||
folder = stageFun: finalSoFar: let
|
folder = nextStage: stageFun: prevStage: let
|
||||||
args = stageFun finalSoFar;
|
args = stageFun prevStage;
|
||||||
args' = args // {
|
args' = args // {
|
||||||
stdenv = args.stdenv // {
|
stdenv = args.stdenv // {
|
||||||
# For debugging
|
# For debugging
|
||||||
__bootPackages = finalSoFar;
|
__bootPackages = prevStage;
|
||||||
|
__hatPackages = nextStage;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
in
|
in
|
||||||
if args.__raw or false
|
if args.__raw or false
|
||||||
then args'
|
then args'
|
||||||
else allPackages ((builtins.removeAttrs args' ["selfBuild"]) // {
|
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
|
||||||
|
@ -66,7 +66,7 @@ let
|
|||||||
if actuallySplice
|
if actuallySplice
|
||||||
then splicer defaultBuildScope defaultRunScope // {
|
then splicer defaultBuildScope defaultRunScope // {
|
||||||
# These should never be spliced under any circumstances
|
# These should never be spliced under any circumstances
|
||||||
inherit (pkgs) pkgs buildPackages
|
inherit (pkgs) pkgs buildPackages __targetPackages
|
||||||
buildPlatform targetPlatform hostPlatform;
|
buildPlatform targetPlatform hostPlatform;
|
||||||
}
|
}
|
||||||
else pkgs // pkgs.xorg;
|
else pkgs // pkgs.xorg;
|
||||||
|
@ -50,6 +50,14 @@
|
|||||||
# us to avoid expensive splicing.
|
# us to avoid expensive splicing.
|
||||||
buildPackages
|
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.
|
, # The standard environment to use for building packages.
|
||||||
stdenv
|
stdenv
|
||||||
|
|
||||||
@ -88,6 +96,8 @@ let
|
|||||||
stdenvBootstappingAndPlatforms = self: super: {
|
stdenvBootstappingAndPlatforms = self: super: {
|
||||||
buildPackages = (if buildPackages == null then self else buildPackages)
|
buildPackages = (if buildPackages == null then self else buildPackages)
|
||||||
// { recurseForDerivations = false; };
|
// { recurseForDerivations = false; };
|
||||||
|
__targetPackages = (if __targetPackages == null then self else __targetPackages)
|
||||||
|
// { recurseForDerivations = false; };
|
||||||
inherit stdenv
|
inherit stdenv
|
||||||
buildPlatform hostPlatform targetPlatform;
|
buildPlatform hostPlatform targetPlatform;
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user