From 72b3badb6197a042c52397fcea467f630628c75c Mon Sep 17 00:00:00 2001 From: Ryan Burns Date: Fri, 29 Jan 2021 19:23:04 -0800 Subject: [PATCH 1/4] lib.systems: add powerpc64-linux PPC64 supports two ABIs: ELF v1 and v2. ELFv1 is historically what GCC and most packages expect, but this is changing because musl outright does not work with ELFv1. So any distro which uses musl must use ELFv2. Many other platforms are moving to ELFv2 too, such as FreeBSD (as of v13) and Gentoo (as of late 2020). Since we use musl extensively, let's default to ELFv2. Nix gives us the power to specify this declaratively for the entire system, so ELFv1 is not dropped entirely. It can be specified explicitly in the target config, e.g. "powerpc64-unknown-linux-elfv1". Otherwise the default is "powerpc64-unknown-linux-elfv2". For musl, "powerpc64-unknown-linux-musl" must use elfv2 internally to function. --- lib/systems/doubles.nix | 5 +++-- lib/systems/examples.nix | 13 +++++++++++++ lib/systems/parse.nix | 9 +++++++++ lib/tests/systems.nix | 2 +- 4 files changed, 26 insertions(+), 3 deletions(-) diff --git a/lib/systems/doubles.nix b/lib/systems/doubles.nix index b0bc7dd1188..07327fa2273 100644 --- a/lib/systems/doubles.nix +++ b/lib/systems/doubles.nix @@ -24,6 +24,7 @@ let "x86_64-redox" + "powerpc64-linux" "powerpc64le-linux" "riscv32-linux" "riscv64-linux" @@ -72,7 +73,7 @@ in { darwin = filterDoubles predicates.isDarwin; freebsd = filterDoubles predicates.isFreeBSD; # Should be better, but MinGW is unclear. - gnu = filterDoubles (matchAttrs { kernel = parse.kernels.linux; abi = parse.abis.gnu; }) ++ filterDoubles (matchAttrs { kernel = parse.kernels.linux; abi = parse.abis.gnueabi; }) ++ filterDoubles (matchAttrs { kernel = parse.kernels.linux; abi = parse.abis.gnueabihf; }); + gnu = filterDoubles (matchAttrs { kernel = parse.kernels.linux; abi = parse.abis.gnu; }) ++ filterDoubles (matchAttrs { kernel = parse.kernels.linux; abi = parse.abis.gnueabi; }) ++ filterDoubles (matchAttrs { kernel = parse.kernels.linux; abi = parse.abis.gnueabihf; }) ++ filterDoubles (matchAttrs { kernel = parse.kernels.linux; abi = parse.abis.elfv1; }) ++ filterDoubles (matchAttrs { kernel = parse.kernels.linux; abi = parse.abis.elfv2; }); illumos = filterDoubles predicates.isSunOS; linux = filterDoubles predicates.isLinux; netbsd = filterDoubles predicates.isNetBSD; @@ -85,5 +86,5 @@ in { embedded = filterDoubles predicates.isNone; - mesaPlatforms = ["i686-linux" "x86_64-linux" "x86_64-darwin" "armv5tel-linux" "armv6l-linux" "armv7l-linux" "armv7a-linux" "aarch64-linux" "powerpc64le-linux"]; + mesaPlatforms = ["i686-linux" "x86_64-linux" "x86_64-darwin" "armv5tel-linux" "armv6l-linux" "armv7l-linux" "armv7a-linux" "aarch64-linux" "powerpc64-linux" "powerpc64le-linux"]; } diff --git a/lib/systems/examples.nix b/lib/systems/examples.nix index e8cf15479c0..fbb697f1fe1 100644 --- a/lib/systems/examples.nix +++ b/lib/systems/examples.nix @@ -21,6 +21,19 @@ rec { config = "powerpc64le-unknown-linux-musl"; }; + ppc64-elfv1 = { + config = "powerpc64-unknown-linux-elfv1"; + }; + ppc64-elfv2 = { + config = "powerpc64-unknown-linux-elfv2"; + }; + ppc64 = ppc64-elfv2; # default to modern elfv2 + + ppc64-musl = { + config = "powerpc64-unknown-linux-musl"; + gcc = { abi = "elfv2"; }; # for gcc configuration + }; + sheevaplug = { config = "armv5tel-unknown-linux-gnueabi"; } // platforms.sheevaplug; diff --git a/lib/systems/parse.nix b/lib/systems/parse.nix index a06ac0d11f7..8e012622ccd 100644 --- a/lib/systems/parse.nix +++ b/lib/systems/parse.nix @@ -337,10 +337,18 @@ rec { The "gnu" ABI is ambiguous on 32-bit ARM. Use "gnueabi" or "gnueabihf" instead. ''; } + { assertion = platform: platform.system != "powerpc64-linux"; + message = '' + The "gnu" ABI is ambiguous on big-endian 64-bit PPC. Use "elfv1" or "elfv2" instead. + ''; + } ]; }; gnuabi64 = { abi = "64"; }; + elfv1 = { abi = "elfv1"; }; + elfv2 = { abi = "elfv2"; }; + musleabi = { float = "soft"; }; musleabihf = { float = "hard"; }; musl = {}; @@ -444,6 +452,7 @@ rec { if lib.versionAtLeast (parsed.cpu.version or "0") "6" then abis.gnueabihf else abis.gnueabi + else if cpu == "powerpc64" then abis.elfv2 else abis.gnu else abis.unknown; }; diff --git a/lib/tests/systems.nix b/lib/tests/systems.nix index eed7ee725bc..c0800df25ed 100644 --- a/lib/tests/systems.nix +++ b/lib/tests/systems.nix @@ -28,7 +28,7 @@ with lib.systems.doubles; lib.runTests { testredox = mseteq redox [ "x86_64-redox" ]; testgnu = mseteq gnu (linux /* ++ kfreebsd ++ ... */); testillumos = mseteq illumos [ "x86_64-solaris" ]; - testlinux = mseteq linux [ "aarch64-linux" "armv5tel-linux" "armv6l-linux" "armv7a-linux" "armv7l-linux" "i686-linux" "mipsel-linux" "riscv32-linux" "riscv64-linux" "x86_64-linux" "powerpc64le-linux" ]; + testlinux = mseteq linux [ "aarch64-linux" "armv5tel-linux" "armv6l-linux" "armv7a-linux" "armv7l-linux" "i686-linux" "mipsel-linux" "riscv32-linux" "riscv64-linux" "x86_64-linux" "powerpc64-linux" "powerpc64le-linux" ]; testnetbsd = mseteq netbsd [ "i686-netbsd" "x86_64-netbsd" ]; testopenbsd = mseteq openbsd [ "i686-openbsd" "x86_64-openbsd" ]; testwindows = mseteq windows [ "i686-cygwin" "x86_64-cygwin" "i686-windows" "x86_64-windows" ]; From c17abf8111471184446370e0761736b2519b04fd Mon Sep 17 00:00:00 2001 From: Ryan Burns Date: Fri, 29 Jan 2021 19:23:10 -0800 Subject: [PATCH 2/4] stdenv: add powerpc64-linux --- pkgs/stdenv/default.nix | 1 + 1 file changed, 1 insertion(+) diff --git a/pkgs/stdenv/default.nix b/pkgs/stdenv/default.nix index b0db1be5f44..d9eadf26804 100644 --- a/pkgs/stdenv/default.nix +++ b/pkgs/stdenv/default.nix @@ -54,6 +54,7 @@ in aarch64-linux = stagesLinux; mipsel-linux = stagesLinux; powerpc-linux = /* stagesLinux */ stagesNative; + powerpc64-linux = stagesLinux; powerpc64le-linux = stagesLinux; x86_64-darwin = stagesDarwin; x86_64-solaris = stagesNix; From 76fc6d2870ff4e79e227c409dfae9378d4b12573 Mon Sep 17 00:00:00 2001 From: Ryan Burns Date: Fri, 29 Jan 2021 20:08:42 -0800 Subject: [PATCH 3/4] bootstrap-tools-cross: add powerpc64-linux Also check for powerpc64-linux-elfv1, which does not support musl. --- pkgs/stdenv/linux/make-bootstrap-tools-cross.nix | 2 ++ pkgs/stdenv/linux/make-bootstrap-tools.nix | 3 ++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/pkgs/stdenv/linux/make-bootstrap-tools-cross.nix b/pkgs/stdenv/linux/make-bootstrap-tools-cross.nix index d1ee317a2bc..d8ab96952b7 100644 --- a/pkgs/stdenv/linux/make-bootstrap-tools-cross.nix +++ b/pkgs/stdenv/linux/make-bootstrap-tools-cross.nix @@ -17,6 +17,8 @@ in lib.mapAttrs (n: make) (with lib.systems.examples; { armv6l-musl = muslpi; aarch64-musl = aarch64-multiplatform-musl; riscv64 = riscv64; + powerpc64 = ppc64; + powerpc64-musl = ppc64-musl; powerpc64le = powernv; powerpc64le-musl = musl-power; }) diff --git a/pkgs/stdenv/linux/make-bootstrap-tools.nix b/pkgs/stdenv/linux/make-bootstrap-tools.nix index 25cde589a92..d99edc962b5 100644 --- a/pkgs/stdenv/linux/make-bootstrap-tools.nix +++ b/pkgs/stdenv/linux/make-bootstrap-tools.nix @@ -19,7 +19,8 @@ in with pkgs; rec { tarMinimal = gnutar.override { acl = null; }; busyboxMinimal = busybox.override { - useMusl = !stdenv.targetPlatform.isRiscV; + useMusl = with stdenv.targetPlatform; !isRiscV && + (system == "powerpc64-linux" -> parsed.abi.name != "elfv1"); enableStatic = true; enableMinimal = true; extraConfig = '' From 5530a3adbe9be842f22cd83b59b06cdd5a94308e Mon Sep 17 00:00:00 2001 From: Ryan Burns Date: Fri, 29 Jan 2021 19:23:17 -0800 Subject: [PATCH 4/4] gcc: fix powerpc64-linux Long-double-128 is a hardware feature independent of endianness --- pkgs/development/compilers/gcc/common/platform-flags.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkgs/development/compilers/gcc/common/platform-flags.nix b/pkgs/development/compilers/gcc/common/platform-flags.nix index 66af8c4a4cc..bd5a72f9603 100644 --- a/pkgs/development/compilers/gcc/common/platform-flags.nix +++ b/pkgs/development/compilers/gcc/common/platform-flags.nix @@ -11,6 +11,6 @@ in lib.concatLists [ (lib.optional (p ? float) "--with-float=${p.float}") (lib.optional (p ? mode) "--with-mode=${p.mode}") (lib.optional - (let tp = targetPlatform; in tp.isPower && tp.libc == "glibc" && tp.is64bit && tp.isLittleEndian) + (let tp = targetPlatform; in tp.isPower && tp.libc == "glibc" && tp.is64bit) "--with-long-double-128") ]