From 20e756a0936fb75ce8f9d9ef0b7a511198bf7eea Mon Sep 17 00:00:00 2001 From: John Ericson Date: Tue, 23 May 2017 18:04:15 -0400 Subject: [PATCH] lib: Consolidate platform configurations (used for crossSystem) This is good for maintenance and education. --- doc/cross-compilation.xml | 52 +++++-- lib/systems/default.nix | 1 + lib/systems/examples.nix | 130 ++++++++++++++++++ lib/systems/platforms.nix | 9 +- .../linux/make-bootstrap-tools-cross.nix | 92 ++----------- pkgs/top-level/release-cross.nix | 89 +----------- 6 files changed, 200 insertions(+), 173 deletions(-) create mode 100644 lib/systems/examples.nix diff --git a/doc/cross-compilation.xml b/doc/cross-compilation.xml index de1b9b80d30..e99e90bac9c 100644 --- a/doc/cross-compilation.xml +++ b/doc/cross-compilation.xml @@ -85,7 +85,8 @@ This field is obsolete and will soon disappear—please do not use it. - 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 lib.systems.examples; note how they are not all very consistent. For now, here are few fields can count on them containing: @@ -118,8 +119,27 @@ 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 config. [Technically, only one need be specified and the others can be inferred, though the precision of inference may not be very good.] - See lib.systems.parse for the exact representation, along with some is*predicates. - These predicates are superior to the ones in stdenv as they aren't tied to the build platform (host, as previously discussed, would be a saner default). + See lib.systems.parse for the exact representation. + + + + + libc + + + 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 parse. + + + + + is* + + + These predicates are defined in lib.systems.inspect, and slapped on every platform. + They are superior to the ones in stdenv as they force the user to be explicit about which platform they are inspecting. + Please use these instead of those. @@ -128,7 +148,7 @@ This is, quite frankly, a dumping ground of ad-hoc settings (it's an attribute set). - See lib.systems.platforms for examples—there's hopefully one in there that will work verbatim for each platform one is working. + See lib.systems.platforms 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! @@ -184,11 +204,27 @@ More information needs to moved from the old wiki, especially , for this section. - Many sources (manual, wiki, etc) probably mention passing system, platform, and, optionally, crossSystem to nixpkgs: - import <nixpkgs> { system = ..; platform = ..; crossSystem = ..; }. - system and platform together determine the system on which packages are built, and crossSystem 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 localSystem, containing system and platform, for symmetry. + Nixpkgs can be instantiated with localSystem alone, in which case there is no cross compiling and everything is built by and for that system, + or also with crossSystem, in which case packages run on the latter, but all building happens on the former. + Both parameters take the same schema as the 3 (build, host, and target) platforms defined in the previous section. + As mentioned above, lib.systems.examples has some platforms which are used as arguments for these parameters in practice. + You can use them programmatically, or on the command line like nix-build <nixpkgs> --arg crossSystem '(import <nixpkgs/lib>).systems.examples.fooBarBaz'. + + 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 system, config, and parsed is needed to infer the other two. + Additionally, libc will be inferred from parse. + Finally, localSystem.system is also impurely inferred based on the platform evaluation occurs. + This means it is often not necessary to pass localSystem at all, as in the command-line example in the previous paragraph. + + + + Many sources (manual, wiki, etc) probably mention passing system, platform, along with the optional crossSystem to nixpkgs: + import <nixpkgs> { system = ..; platform = ..; crossSystem = ..; }. + Passing those two instead of localSystem 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. + + 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 are purposefully not used here to draw a subtle but important distinction: diff --git a/lib/systems/default.nix b/lib/systems/default.nix index c37b6be2523..c22c9956196 100644 --- a/lib/systems/default.nix +++ b/lib/systems/default.nix @@ -5,6 +5,7 @@ rec { parse = import ./parse.nix; inspect = import ./inspect.nix; platforms = import ./platforms.nix; + examples = import ./examples.nix; # Elaborate a `localSystem` or `crossSystem` so that it contains everything # necessary. diff --git a/lib/systems/examples.nix b/lib/systems/examples.nix new file mode 100644 index 00000000000..da9b95a6454 --- /dev/null +++ b/lib/systems/examples.nix @@ -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 = {}; + }; +} diff --git a/lib/systems/platforms.nix b/lib/systems/platforms.nix index 0bea38ab419..ae4fc355c71 100644 --- a/lib/systems/platforms.nix +++ b/lib/systems/platforms.nix @@ -255,6 +255,10 @@ rec { arch = "armv6"; fpu = "vfp"; 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"; uboot = null; - gcc.arch = "loongson2f"; + gcc = { + arch = "loongson2f"; + abi = "n32"; + }; }; beaglebone = armv7l-hf-multiplatform // { diff --git a/pkgs/stdenv/linux/make-bootstrap-tools-cross.nix b/pkgs/stdenv/linux/make-bootstrap-tools-cross.nix index 50fd563e7c2..0378891b27a 100644 --- a/pkgs/stdenv/linux/make-bootstrap-tools-cross.nix +++ b/pkgs/stdenv/linux/make-bootstrap-tools-cross.nix @@ -6,91 +6,19 @@ let lib = import ../../../lib; pkgsFun = import ../../..; - sheevaplugCrossSystem = { - crossSystem = rec { - config = "arm-linux-gnueabi"; - 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"; - }; + inherit (lib.systems.examples) + sheevaplug raspberryPi armv7l-hf-multiplatform + aarch64-multiplatform scaleway-c1 pogoplug4; selectedCrossSystem = - if toolsArch == "armv5tel" then sheevaplugCrossSystem else - if toolsArch == "scaleway" then scaleway-c1-crossSystem else - if toolsArch == "pogoplug4" then pogoplug4-crossSystem else - if toolsArch == "armv6l" then raspberrypiCrossSystem else - if toolsArch == "armv7l" then armv7l-hf-multiplatform-crossSystem else - if toolsArch == "aarch64" then aarch64-multiplatform-crossSystem else null; + if toolsArch == "armv5tel" then sheevaplug else + if toolsArch == "scaleway" then scaleway-c1 else + if toolsArch == "pogoplug4" then pogoplug4 else + if toolsArch == "armv6l" then raspberryPi else + if toolsArch == "armv7l" then armv7l-hf-multiplatform else + if toolsArch == "aarch64" then aarch64-multiplatform else null; - pkgs = pkgsFun ({inherit system;} // selectedCrossSystem); + pkgs = pkgsFun ({ inherit system; crossSystem = selectedCrossSystem; }); glibc = pkgs.libcCross; bash = pkgs.bash; diff --git a/pkgs/top-level/release-cross.nix b/pkgs/top-level/release-cross.nix index c81d65ad0e0..94c1e6c7ad2 100644 --- a/pkgs/top-level/release-cross.nix +++ b/pkgs/top-level/release-cross.nix @@ -89,101 +89,26 @@ in guile = nativePlatforms; }; - darwinToAarch64 = let - crossSystem = { - config = "aarch64-apple-darwin14"; - arch = "arm64"; - libc = "libSystem"; - }; - in mapTestOnCross crossSystem darwinCommon; + crossIphone64 = mapTestOnCross lib.systems.examples.iphone64 darwinCommon; - darwinToArm = let - crossSystem = { - config = "arm-apple-darwin10"; - arch = "armv7-a"; - libc = "libSystem"; - }; - in mapTestOnCross crossSystem darwinCommon; + crossIphone32 = mapTestOnCross lib.systems.examples.iphone32 darwinCommon; /* Test some cross builds to the Sheevaplug */ - crossSheevaplugLinux = let - 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 // { + crossSheevaplugLinux = mapTestOnCross lib.systems.examples.sheevaplug (linuxCommon // { ubootSheevaplug = nativePlatforms; }); - /* Test some cross builds on 32 bit mingw-w64 */ - crossMingw32 = let - crossSystem = { - config = "i686-pc-mingw32"; - arch = "x86"; # Irrelevant - libc = "msvcrt"; # This distinguishes the mingw (non posix) toolchain - platform = {}; - }; - in mapTestOnCross crossSystem windowsCommon; - + crossMingw32 = mapTestOnCross lib.systems.examples.mingw32 windowsCommon; /* Test some cross builds on 64 bit mingw-w64 */ - crossMingwW64 = let - 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; - + crossMingwW64 = mapTestOnCross lib.systems.examples.mingwW64 windowsCommon; /* Linux on the fuloong */ - fuloongminipc = let - 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; - + fuloongminipc = mapTestOnCross lib.systems.examples.fuloongminipc linuxCommon; /* Linux on Raspberrypi */ - rpi = let - 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 // { + rpi = mapTestOnCross lib.systems.examples.raspberryPi (linuxCommon // { vim = nativePlatforms; unzip = nativePlatforms; ddrescue = nativePlatforms;