Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cross lib foundation #25099

Merged
merged 3 commits into from
Apr 23, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
5 changes: 5 additions & 0 deletions doc/cross-compilation.xml
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand Down
41 changes: 36 additions & 5 deletions pkgs/stdenv/booter.nix
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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
6 changes: 5 additions & 1 deletion pkgs/top-level/splice.nix
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
13 changes: 12 additions & 1 deletion pkgs/top-level/stage.nix
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -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)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using null here seems kind of forced—what’s the difference to []?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Err it would normally be an attribute set. I wanted to distinguish { .. } --- the target package set is different and contains these packages , from null -- the target package set is the same as the regular package set. This allows me to avoid splicing, which is expensive.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I fixed wording

// { recurseForDerivations = false; };
inherit stdenv
buildPlatform hostPlatform targetPlatform;
};
Expand Down