Skip to content
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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 17 additions & 3 deletions doc/cross-compilation.xml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
<!--============================================================-->

<section xml:id="sec-cross-packaging">
<title>Packing in a cross-friendly manner</title>
<title>Packaging in a cross-friendly manner</title>

<section>
<title>Platform parameters</title>
Expand Down Expand Up @@ -132,9 +132,23 @@

<section xml:id="sec-cross-usage">
<title>Cross-building packages</title>
<note><para>
More information needs to moved from the old wiki, especially <link xlink:href="https://nixos.org/wiki/CrossCompiling" />, for this section.
</para></note>
<para>
Many sources (manual, wiki, etc) probably mention passing <varname>system</varname>, <varname>platform</varname>, and, optionally, <varname>crossSystem</varname> to nixpkgs:
<literal>import &lt;nixpkgs&gt; { system = ..; platform = ..; crossSystem = ..; }</literal>.
<varname>system</varname> and <varname>platform</varname> together determine the system on which packages are built, and <varname>crossSystem</varname> specifies the platform on which packages are ultimately intended to run, if it is different.
This still works, but with more recent changes, one can alternatively pass <varname>localSystem</varname>, containing <varname>system</varname> and <varname>platform</varname>, for symmetry.
</para>
<para>
To be written.
This is basically unchanged so see the old wiki for now.
One would think that <varname>localSystem</varname> and <varname>crossSystem</varname> overlap horribly with the three <varname>*Platforms</varname> (<varname>buildPlatform</varname>, <varname>hostPlatform,</varname> and <varname>targetPlatform</varname>; see <varname>stage.nix</varname> or the manual).
Actually, those identifiers are purposefully not used here to draw a subtle but important distinction:
While the granularity of having 3 platforms is necessary to properly *build* packages, it is overkill for specifying the user's *intent* when making a build plan or package set.
A simple "build vs deploy" dichotomy is adequate: the sliding window principle described in the previous section shows how to interpolate between the these two "end points" to get the 3 platform triple for each bootstrapping stage.
That means for any package a given package set, even those not bound on the top level but only reachable via dependencies or <varname>buildPackages</varname>, the three platforms will be defined as one of <varname>localSystem</varname> or <varname>crossSystem</varname>, with the former replacing the latter as one traverses build-time dependencies.
A last simple difference then is <varname>crossSystem</varname> should be null when one doesn't want to cross-compile, while the <varname>*Platform</varname>s are always non-null.
<varname>localSystem</varname> is always non-null.
</para>
</section>

Expand Down
6 changes: 4 additions & 2 deletions pkgs/top-level/all-packages.nix
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,10 @@ with pkgs;

# Override system. This is useful to build i686 packages on x86_64-linux.
forceSystem = system: kernel: nixpkgsFun {
inherit system;
platform = platform // { kernelArch = kernel; };
localSystem = {
inherit system;
platform = platform // { kernelArch = kernel; };
};
};

# Used by wine, firefox with debugging version of Flash, ...
Expand Down
47 changes: 17 additions & 30 deletions pkgs/top-level/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,14 @@
evaluation is taking place, and the configuration from environment variables
or dot-files. */

{ # The system (e.g., `i686-linux') for which to build the packages.
system
{ # The system packages will be built on. See the manual for the
# subtle division of labor between these two `*System`s and the three
# `*Platform`s.
localSystem

# The system packages will ultimately be run on. Null if the two should be the
# same.
, crossSystem ? null

, # Allow a configuration attribute set to be passed in as an argument.
config ? {}
Expand All @@ -27,12 +33,9 @@
overlays ? []

, # A function booting the final package set for a specific standard
# environment. See below for the arguments given to that function,
# the type of list it returns.
# environment. See below for the arguments given to that function, the type of
Copy link
Member

Choose a reason for hiding this comment

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

Why is this change made?

Copy link
Member Author

Choose a reason for hiding this comment

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

80 char consistency.

# list it returns.
stdenvStages ? import ../stdenv

, crossSystem ? null
, platform ? assert false; null
} @ args:

let # Rename the function arguments
Expand All @@ -51,10 +54,10 @@ in let

# Allow setting the platform in the config file. Otherwise, let's use a
# reasonable default.
platform =
args.platform
or ( config.platform
or ((import ./platforms.nix).selectPlatformBySystem system) );
localSystem =
{ platform = (import ./platforms.nix).selectPlatformBySystem args.localSystem.system; }
// builtins.intersectAttrs { platform = null; } config
// args.localSystem;

# A few packages make a new package set to draw their dependencies from.
# (Currently to get a cross tool chain, or forced-i686 package.) Rather than
Expand All @@ -71,7 +74,8 @@ in let
# To put this in concrete terms, this function is basically just used today to
# use package for a different platform for the current platform (namely cross
# compiling toolchains and 32-bit packages on x86_64). In both those cases we
# want the provided non-native `system` argument to affect the stdenv chosen.
# want the provided non-native `localSystem` argument to affect the stdenv
# chosen.
nixpkgsFun = newArgs: import ./. (args // newArgs);

# Partially apply some arguments for building bootstraping stage pkgs
Expand All @@ -83,24 +87,7 @@ in let
boot = import ../stdenv/booter.nix { inherit lib allPackages; };

stages = stdenvStages {
# One would think that `localSystem` and `crossSystem` overlap horribly with
# the three `*Platforms` (`buildPlatform`, `hostPlatform,` and
# `targetPlatform`; see `stage.nix` or the manual). Actually, those
# identifiers I, @Ericson2314, purposefully not used here to draw a subtle
# but important distinction:
#
# While the granularity of having 3 platforms is necessary to properly
# *build* packages, it is overkill for specifying the user's *intent* when
# making a build plan or package set. A simple "build vs deploy" dichotomy
# is adequate: the "sliding window" principle described in the manual shows
# how to interpolate between the these two "end points" to get the 3
# platform triple for each bootstrapping stage.
#
# Also, less philosophically but quite practically, `crossSystem` should be
# null when one doesn't want to cross-compile, while the `*Platform`s are
# always non-null. `localSystem` is always non-null.
localSystem = { inherit system platform; };
inherit lib crossSystem config overlays;
inherit lib localSystem crossSystem config overlays;
};

pkgs = boot stages;
Expand Down
19 changes: 15 additions & 4 deletions pkgs/top-level/impure.nix
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,11 @@ let

in

{ # Fallback: Assume we are building packages for the current (host, in GNU
# Autotools parlance) system.
system ? builtins.currentSystem
{ # We combine legacy `system` and `platform` into `localSystem`, if
# `localSystem` was not passed. Strictly speaking, this is pure desugar, but
# it is most convient to do so before the impure `localSystem.system` default,
# so we do it now.
localSystem ? builtins.intersectAttrs { system = null; platform = null; } args

, # Fallback: The contents of the configuration file found at $NIXPKGS_CONFIG or
# $HOME/.config/nixpkgs/config.nix.
Expand Down Expand Up @@ -49,4 +51,13 @@ in
, ...
} @ args:

import ./. (args // { inherit system config overlays; })
# If `localSystem` was explicitly passed, legacy `system` and `platform` should
# not be passed.
assert args ? localSystem -> !(args ? system || args ? platform);

import ./. (builtins.removeAttrs args [ "system" "platform" ] // {
inherit config overlays;
# Fallback: Assume we are building packages on the current (build, in GNU
# Autotools parlance) system.
localSystem = { system = builtins.currentSystem; } // localSystem;
})