lib: Consolidate platform configurations (used for crossSystem)

This is good for maintenance and education.
This commit is contained in:
John Ericson 2017-05-23 18:04:15 -04:00
parent b20f20d3eb
commit 20e756a093
6 changed files with 200 additions and 173 deletions

View File

@ -85,7 +85,8 @@
This field is obsolete and will soon disappear—please do not use it. This field is obsolete and will soon disappear—please do not use it.
</para></note> </para></note>
<para> <para>
The exact scheme these fields is a bit ill-defined due to a long and convoluted evolution, but this is slowly being cleaned up. The exact schema these fields follow is a bit ill-defined due to a long and convoluted evolution, but this is slowly being cleaned up.
You can see examples of ones used in practice in <literal>lib.systems.examples</literal>; note how they are not all very consistent.
For now, here are few fields can count on them containing: For now, here are few fields can count on them containing:
</para> </para>
<variablelist> <variablelist>
@ -118,8 +119,27 @@
This is a nix representation of a parsed LLVM target triple with white-listed components. This is a nix representation of a parsed LLVM target triple with white-listed components.
This can be specified directly, or actually parsed from the <varname>config</varname>. This can be specified directly, or actually parsed from the <varname>config</varname>.
[Technically, only one need be specified and the others can be inferred, though the precision of inference may not be very good.] [Technically, only one need be specified and the others can be inferred, though the precision of inference may not be very good.]
See <literal>lib.systems.parse</literal> for the exact representation, along with some <literal>is*</literal>predicates. See <literal>lib.systems.parse</literal> for the exact representation.
These predicates are superior to the ones in <varname>stdenv</varname> as they aren't tied to the build platform (host, as previously discussed, would be a saner default). </para>
</listitem>
</varlistentry>
<varlistentry>
<term><varname>libc</varname></term>
<listitem>
<para>
This is a string identifying the standard C library used.
Valid identifiers include "glibc" for GNU libc, "libsystem" for Darwin's Libsystem, and "uclibc" for µClibc.
It should probably be refactored to use the module system, like <varname>parse</varname>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><varname>is*</varname></term>
<listitem>
<para>
These predicates are defined in <literal>lib.systems.inspect</literal>, and slapped on every platform.
They are superior to the ones in <varname>stdenv</varname> as they force the user to be explicit about which platform they are inspecting.
Please use these instead of those.
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
@ -128,7 +148,7 @@
<listitem> <listitem>
<para> <para>
This is, quite frankly, a dumping ground of ad-hoc settings (it's an attribute set). This is, quite frankly, a dumping ground of ad-hoc settings (it's an attribute set).
See <literal>lib.systems.platforms</literal> for examples—there's hopefully one in there that will work verbatim for each platform one is working. See <literal>lib.systems.platforms</literal> for examples—there's hopefully one in there that will work verbatim for each platform that is working.
Please help us triage these flags and give them better homes! Please help us triage these flags and give them better homes!
</para> </para>
</listitem> </listitem>
@ -184,11 +204,27 @@
More information needs to moved from the old wiki, especially <link xlink:href="https://nixos.org/wiki/CrossCompiling" />, for this section. More information needs to moved from the old wiki, especially <link xlink:href="https://nixos.org/wiki/CrossCompiling" />, for this section.
</para></note> </para></note>
<para> <para>
Many sources (manual, wiki, etc) probably mention passing <varname>system</varname>, <varname>platform</varname>, and, optionally, <varname>crossSystem</varname> to nixpkgs: Nixpkgs can be instantiated with <varname>localSystem</varname> alone, in which case there is no cross compiling and everything is built by and for that system,
<literal>import &lt;nixpkgs&gt; { system = ..; platform = ..; crossSystem = ..; }</literal>. or also with <varname>crossSystem</varname>, in which case packages run on the latter, but all building happens on the former.
<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. Both parameters take the same schema as the 3 (build, host, and target) platforms defined in the previous section.
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. As mentioned above, <literal>lib.systems.examples</literal> has some platforms which are used as arguments for these parameters in practice.
You can use them programmatically, or on the command line like <command>nix-build &lt;nixpkgs&gt; --arg crossSystem '(import &lt;nixpkgs/lib&gt;).systems.examples.fooBarBaz'</command>.
</para> </para>
<para>
While one is free to pass both parameters in full, there's a lot of logic to fill in missing fields.
As discussed in the previous section, only one of <varname>system</varname>, <varname>config</varname>, and <varname>parsed</varname> is needed to infer the other two.
Additionally, <varname>libc</varname> will be inferred from <varname>parse</varname>.
Finally, <literal>localSystem.system</literal> is also <emphasis>impurely</emphasis> inferred based on the platform evaluation occurs.
This means it is often not necessary to pass <varname>localSystem</varname> at all, as in the command-line example in the previous paragraph.
</para>
<note>
<para>
Many sources (manual, wiki, etc) probably mention passing <varname>system</varname>, <varname>platform</varname>, along with the optional <varname>crossSystem</varname> to nixpkgs:
<literal>import &lt;nixpkgs&gt; { system = ..; platform = ..; crossSystem = ..; }</literal>.
Passing those two instead of <varname>localSystem</varname> is still supported for compatibility, but is discouraged.
Indeed, much of the inference we do for these parameters is motivated by compatibility as much as convenience.
</para>
</note>
<para> <para>
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). 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: Actually, those identifiers are purposefully not used here to draw a subtle but important distinction:

View File

@ -5,6 +5,7 @@ rec {
parse = import ./parse.nix; parse = import ./parse.nix;
inspect = import ./inspect.nix; inspect = import ./inspect.nix;
platforms = import ./platforms.nix; platforms = import ./platforms.nix;
examples = import ./examples.nix;
# Elaborate a `localSystem` or `crossSystem` so that it contains everything # Elaborate a `localSystem` or `crossSystem` so that it contains everything
# necessary. # necessary.

130
lib/systems/examples.nix Normal file
View File

@ -0,0 +1,130 @@
# These can be passed to nixpkgs as either the `localSystem` or
# `crossSystem`. They are put here for user convenience, but also used by cross
# tests and linux cross stdenv building, so handle with care!
let platforms = import ./platforms.nix; in
rec {
#
# Linux
#
sheevaplug = rec {
config = "armv5te-unknown-linux-gnueabi";
bigEndian = false;
arch = "armv5te";
float = "soft";
withTLS = true;
libc = "glibc";
platform = platforms.sheevaplug;
openssl.system = "linux-generic32";
inherit (platform) gcc;
};
raspberryPi = rec {
config = "armv6l-unknown-linux-gnueabihf";
bigEndian = false;
arch = "armv6l";
float = "hard";
fpu = "vfp";
withTLS = true;
libc = "glibc";
platform = platforms.raspberrypi;
openssl.system = "linux-generic32";
inherit (platform) gcc;
};
armv7l-hf-multiplatform = rec {
config = "arm-unknown-linux-gnueabihf";
bigEndian = false;
arch = "armv7-a";
float = "hard";
fpu = "vfpv3-d16";
withTLS = true;
libc = "glibc";
platform = platforms.armv7l-hf-multiplatform;
openssl.system = "linux-generic32";
inherit (platform) gcc;
};
aarch64-multiplatform = rec {
config = "aarch64-unknown-linux-gnu";
bigEndian = false;
arch = "aarch64";
withTLS = true;
libc = "glibc";
platform = platforms.aarch64-multiplatform;
inherit (platform) gcc;
};
scaleway-c1 = armv7l-hf-multiplatform // rec {
platform = platforms.scaleway-c1;
inherit (platform) gcc;
inherit (gcc) fpu;
};
pogoplug4 = rec {
arch = "armv5tel";
config = "armv5tel-softfloat-linux-gnueabi";
float = "soft";
platform = platforms.pogoplug4;
inherit (platform) gcc;
libc = "glibc";
withTLS = true;
openssl.system = "linux-generic32";
};
fuloongminipc = rec {
config = "mips64el-unknown-linux-gnu";
bigEndian = false;
arch = "mips";
float = "hard";
withTLS = true;
libc = "glibc";
platform = platforms.fuloong2f_n32;
openssl.system = "linux-generic32";
inherit (platform) gcc;
};
#
# Darwin
#
iphone64 = {
config = "aarch64-apple-darwin14";
arch = "arm64";
libc = "libsystem";
platform = {};
};
iphone32 = {
config = "arm-apple-darwin10";
arch = "armv7-a";
libc = "libsystem";
platform = {};
};
#
# Windows
#
# 32 bit mingw-w64
mingw32 = {
config = "i686-pc-mingw32";
arch = "x86"; # Irrelevant
libc = "msvcrt"; # This distinguishes the mingw (non posix) toolchain
platform = {};
};
# 64 bit mingw-w64
mingwW64 = {
# That's the triplet they use in the mingw-w64 docs.
config = "x86_64-pc-mingw32";
arch = "x86_64"; # Irrelevant
libc = "msvcrt"; # This distinguishes the mingw (non posix) toolchain
platform = {};
};
}

View File

@ -255,6 +255,10 @@ rec {
arch = "armv6"; arch = "armv6";
fpu = "vfp"; fpu = "vfp";
float = "hard"; float = "hard";
# TODO(@Ericson2314) what is this and is it a good idea? It was
# used in some cross compilation examples but not others.
#
# abi = "aapcs-linux";
}; };
}; };
@ -460,7 +464,10 @@ rec {
''; '';
kernelTarget = "vmlinux"; kernelTarget = "vmlinux";
uboot = null; uboot = null;
gcc.arch = "loongson2f"; gcc = {
arch = "loongson2f";
abi = "n32";
};
}; };
beaglebone = armv7l-hf-multiplatform // { beaglebone = armv7l-hf-multiplatform // {

View File

@ -6,91 +6,19 @@ let
lib = import ../../../lib; lib = import ../../../lib;
pkgsFun = import ../../..; pkgsFun = import ../../..;
sheevaplugCrossSystem = { inherit (lib.systems.examples)
crossSystem = rec { sheevaplug raspberryPi armv7l-hf-multiplatform
config = "arm-linux-gnueabi"; aarch64-multiplatform scaleway-c1 pogoplug4;
bigEndian = false;
arch = "armv5te";
float = "soft";
withTLS = true;
libc = "glibc";
platform = lib.systems.platforms.sheevaplug;
openssl.system = "linux-generic32";
inherit (platform) gcc;
};
};
raspberrypiCrossSystem = {
crossSystem = rec {
config = "arm-linux-gnueabihf";
bigEndian = false;
arch = "armv6";
float = "hard";
fpu = "vfp";
withTLS = true;
libc = "glibc";
platform = lib.systems.platforms.raspberrypi;
openssl.system = "linux-generic32";
inherit (platform) gcc;
};
};
armv7l-hf-multiplatform-crossSystem = {
crossSystem = rec {
config = "arm-linux-gnueabihf";
bigEndian = false;
arch = "armv7-a";
float = "hard";
fpu = "vfpv3-d16";
withTLS = true;
libc = "glibc";
platform = lib.systems.platforms.armv7l-hf-multiplatform;
openssl.system = "linux-generic32";
inherit (platform) gcc;
};
};
aarch64-multiplatform-crossSystem = {
crossSystem = rec {
config = "aarch64-linux-gnu";
bigEndian = false;
arch = "aarch64";
withTLS = true;
libc = "glibc";
platform = lib.systems.platforms.aarch64-multiplatform;
inherit (platform) gcc;
};
};
scaleway-c1-crossSystem.crossSystem = armv7l-hf-multiplatform-crossSystem.crossSystem // rec {
platform = lib.systems.platforms.scaleway-c1;
inherit (platform) gcc;
inherit (gcc) fpu;
};
pogoplug4-crossSystem.crossSystem = {
arch = "armv5tel";
config = "armv5tel-softfloat-linux-gnueabi";
float = "soft";
platform = lib.systems.platforms.pogoplug4;
inherit (lib.systems.platforms.pogoplug4) gcc;
libc = "glibc";
withTLS = true;
openssl.system = "linux-generic32";
};
selectedCrossSystem = selectedCrossSystem =
if toolsArch == "armv5tel" then sheevaplugCrossSystem else if toolsArch == "armv5tel" then sheevaplug else
if toolsArch == "scaleway" then scaleway-c1-crossSystem else if toolsArch == "scaleway" then scaleway-c1 else
if toolsArch == "pogoplug4" then pogoplug4-crossSystem else if toolsArch == "pogoplug4" then pogoplug4 else
if toolsArch == "armv6l" then raspberrypiCrossSystem else if toolsArch == "armv6l" then raspberryPi else
if toolsArch == "armv7l" then armv7l-hf-multiplatform-crossSystem else if toolsArch == "armv7l" then armv7l-hf-multiplatform else
if toolsArch == "aarch64" then aarch64-multiplatform-crossSystem else null; if toolsArch == "aarch64" then aarch64-multiplatform else null;
pkgs = pkgsFun ({inherit system;} // selectedCrossSystem); pkgs = pkgsFun ({ inherit system; crossSystem = selectedCrossSystem; });
glibc = pkgs.libcCross; glibc = pkgs.libcCross;
bash = pkgs.bash; bash = pkgs.bash;

View File

@ -89,101 +89,26 @@ in
guile = nativePlatforms; guile = nativePlatforms;
}; };
darwinToAarch64 = let crossIphone64 = mapTestOnCross lib.systems.examples.iphone64 darwinCommon;
crossSystem = {
config = "aarch64-apple-darwin14";
arch = "arm64";
libc = "libSystem";
};
in mapTestOnCross crossSystem darwinCommon;
darwinToArm = let crossIphone32 = mapTestOnCross lib.systems.examples.iphone32 darwinCommon;
crossSystem = {
config = "arm-apple-darwin10";
arch = "armv7-a";
libc = "libSystem";
};
in mapTestOnCross crossSystem darwinCommon;
/* Test some cross builds to the Sheevaplug */ /* Test some cross builds to the Sheevaplug */
crossSheevaplugLinux = let crossSheevaplugLinux = mapTestOnCross lib.systems.examples.sheevaplug (linuxCommon // {
crossSystem = {
config = "armv5tel-unknown-linux-gnueabi";
bigEndian = false;
arch = "arm";
float = "soft";
withTLS = true;
platform = lib.systems.platforms.sheevaplug;
libc = "glibc";
openssl.system = "linux-generic32";
};
in mapTestOnCross crossSystem (linuxCommon // {
ubootSheevaplug = nativePlatforms; ubootSheevaplug = nativePlatforms;
}); });
/* Test some cross builds on 32 bit mingw-w64 */ /* Test some cross builds on 32 bit mingw-w64 */
crossMingw32 = let crossMingw32 = mapTestOnCross lib.systems.examples.mingw32 windowsCommon;
crossSystem = {
config = "i686-pc-mingw32";
arch = "x86"; # Irrelevant
libc = "msvcrt"; # This distinguishes the mingw (non posix) toolchain
platform = {};
};
in mapTestOnCross crossSystem windowsCommon;
/* Test some cross builds on 64 bit mingw-w64 */ /* Test some cross builds on 64 bit mingw-w64 */
crossMingwW64 = let crossMingwW64 = mapTestOnCross lib.systems.examples.mingwW64 windowsCommon;
crossSystem = {
# That's the triplet they use in the mingw-w64 docs.
config = "x86_64-pc-mingw32";
arch = "x86_64"; # Irrelevant
libc = "msvcrt"; # This distinguishes the mingw (non posix) toolchain
platform = {};
};
in mapTestOnCross crossSystem windowsCommon;
/* Linux on the fuloong */ /* Linux on the fuloong */
fuloongminipc = let fuloongminipc = mapTestOnCross lib.systems.examples.fuloongminipc linuxCommon;
crossSystem = {
config = "mips64el-unknown-linux-gnu";
bigEndian = false;
arch = "mips";
float = "hard";
withTLS = true;
libc = "glibc";
platform = lib.systems.platforms.fuloong2f_n32;
openssl.system = "linux-generic32";
gcc = {
arch = "loongson2f";
abi = "n32";
};
};
in mapTestOnCross crossSystem linuxCommon;
/* Linux on Raspberrypi */ /* Linux on Raspberrypi */
rpi = let rpi = mapTestOnCross lib.systems.examples.raspberryPi (linuxCommon // {
crossSystem = {
config = "armv6l-unknown-linux-gnueabi";
bigEndian = false;
arch = "arm";
float = "hard";
fpu = "vfp";
withTLS = true;
libc = "glibc";
platform = lib.systems.platforms.raspberrypi;
openssl.system = "linux-generic32";
gcc = {
arch = "armv6";
fpu = "vfp";
float = "softfp";
abi = "aapcs-linux";
};
};
in mapTestOnCross crossSystem (linuxCommon // {
vim = nativePlatforms; vim = nativePlatforms;
unzip = nativePlatforms; unzip = nativePlatforms;
ddrescue = nativePlatforms; ddrescue = nativePlatforms;