From fe836f35644a152c5a38d09e162694fec9755b6b Mon Sep 17 00:00:00 2001 From: sternenseemann Date: Tue, 26 Apr 2022 22:08:44 +0200 Subject: [PATCH 1/6] lib/systems/parse: don't consider mode switching CPUs compatible Since we (exclusively) use isCompatible to gauge whether platform a can execute binaries built for platform b, mode switching CPUs are not to be considered compatible for our purposes: Switching the mode of a CPU usually requires a reset. At the very least we can't execute a mix of executables for the two modes which would usually be the case in nixpkgs where we may want to execute buildInputs for the hostPlatform in addition to nativeBuildInputs for the buildPlatform. --- lib/systems/parse.nix | 19 ++++++------------- 1 file changed, 6 insertions(+), 13 deletions(-) diff --git a/lib/systems/parse.nix b/lib/systems/parse.nix index bf436ec8db5..9d2571c993a 100644 --- a/lib/systems/parse.nix +++ b/lib/systems/parse.nix @@ -148,8 +148,10 @@ rec { # Every CPU is compatible with itself. # - (transitivity) # If A is compatible with B and B is compatible with C then A is compatible with C. - # - (compatible under multiple endianness) - # CPUs with multiple modes of endianness are pairwise compatible. + # + # Note: Since 22.11 the archs of a mode switching CPU are no longer considered + # pairwise compatible. Mode switching implies that binaries built for A + # and B respectively can't be executed at the same time. isCompatible = a: b: with cpuTypes; lib.any lib.id [ # x86 (b == i386 && isCompatible a i486) @@ -191,22 +193,13 @@ rec { (b == aarch64 && a == armv8a) (b == armv8a && isCompatible a aarch64) - (b == aarch64 && a == aarch64_be) - (b == aarch64_be && isCompatible a aarch64) - # PowerPC (b == powerpc && isCompatible a powerpc64) - (b == powerpcle && isCompatible a powerpc) - (b == powerpc && a == powerpcle) - (b == powerpc64le && isCompatible a powerpc64) - (b == powerpc64 && a == powerpc64le) + (b == powerpcle && isCompatible a powerpc64le) # MIPS (b == mips && isCompatible a mips64) - (b == mips && a == mipsel) - (b == mipsel && isCompatible a mips) - (b == mips64 && a == mips64el) - (b == mips64el && isCompatible a mips64) + (b == mipsel && isCompatible a mips64el) # RISCV (b == riscv32 && isCompatible a riscv64) From acb063701a6a209a514bbdefacc9bce22332ef60 Mon Sep 17 00:00:00 2001 From: sternenseemann Date: Tue, 26 Apr 2022 22:17:48 +0200 Subject: [PATCH 2/6] lib.systems.elaborate: expose canExecute predicate over isCompatible canExecute is like isCompatible, but also checks that the Kernels are _equal_, i.e. that both platforms use the same syscall interface. This is crucial in order to actually be able to execute binaries for the other platform. isCompatible is dropped, since it has changed semantically and there's no use case left in nixpkgs. --- lib/systems/default.nix | 6 ++++-- pkgs/development/libraries/capnproto/default.nix | 4 ++-- pkgs/stdenv/linux/default.nix | 2 +- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/lib/systems/default.nix b/lib/systems/default.nix index e02890b1138..74f84914faa 100644 --- a/lib/systems/default.nix +++ b/lib/systems/default.nix @@ -34,8 +34,10 @@ rec { # Either of these can be losslessly-extracted from `parsed` iff parsing succeeds. system = parse.doubleFromSystem final.parsed; config = parse.tripleFromSystem final.parsed; - # Determine whether we are compatible with the provided CPU - isCompatible = platform: parse.isCompatible final.parsed.cpu platform.parsed.cpu; + # Determine whether we can execute binaries built for the provided platform. + canExecute = platform: + parse.isCompatible final.parsed.cpu platform.parsed.cpu + && final.parsed.kernel == platform.parsed.kernel; # Derived meta-data libc = /**/ if final.isDarwin then "libSystem" diff --git a/pkgs/development/libraries/capnproto/default.nix b/pkgs/development/libraries/capnproto/default.nix index 75b5f14d67c..aeb9728af82 100644 --- a/pkgs/development/libraries/capnproto/default.nix +++ b/pkgs/development/libraries/capnproto/default.nix @@ -17,9 +17,9 @@ stdenv.mkDerivation rec { }; nativeBuildInputs = [ cmake ] - ++ lib.optional (!(stdenv.hostPlatform.isCompatible stdenv.buildPlatform)) capnproto; + ++ lib.optional (!(stdenv.buildPlatform.canExecute stdenv.hostPlatform)) capnproto; - cmakeFlags = lib.optional (!(stdenv.hostPlatform.isCompatible stdenv.buildPlatform)) "-DEXTERNAL_CAPNP"; + cmakeFlags = lib.optional (!(stdenv.buildPlatform.canExecute stdenv.hostPlatform)) "-DEXTERNAL_CAPNP"; # Upstream 77ac9154440bcc216fda1092fd5bb51da62ae09c, modified to apply to v0.9.1. Drop on update. patches = lib.optional stdenv.hostPlatform.isMusl ./musl-no-fibers.patch; diff --git a/pkgs/stdenv/linux/default.nix b/pkgs/stdenv/linux/default.nix index 5c5ca64b1e9..ace0d704b72 100644 --- a/pkgs/stdenv/linux/default.nix +++ b/pkgs/stdenv/linux/default.nix @@ -31,7 +31,7 @@ # compatible with or current architecture. getCompatibleTools = lib.foldl (v: system: if v != null then v - else if localSystem.isCompatible (lib.systems.elaborate { inherit system; }) then archLookupTable.${system} + else if localSystem.canExecute (lib.systems.elaborate { inherit system; }) then archLookupTable.${system} else null) null (lib.attrNames archLookupTable); archLookupTable = table.${localSystem.libc} From 41485e7337baca768dc542c553a9d66030df7b33 Mon Sep 17 00:00:00 2001 From: sternenseemann Date: Sat, 2 Oct 2021 14:02:47 +0200 Subject: [PATCH 3/6] stdenv.mkDerivation: be less strict about check execution for cross Instead of requiring the platforms be equal, use `isCompatible` to determine if we can execute tests. The upside of this is that we now can execute tests for natively cross compiled package sets like pkgsStatic, pkgsLLVM and pkgsCross.musl64 etc. --- pkgs/stdenv/generic/make-derivation.nix | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/stdenv/generic/make-derivation.nix b/pkgs/stdenv/generic/make-derivation.nix index ed457019c55..395c1586a26 100644 --- a/pkgs/stdenv/generic/make-derivation.nix +++ b/pkgs/stdenv/generic/make-derivation.nix @@ -167,8 +167,8 @@ makeOverlayable (overrideAttrs: let # TODO(@oxij, @Ericson2314): This is here to keep the old semantics, remove when # no package has `doCheck = true`. - doCheck' = doCheck && stdenv.hostPlatform == stdenv.buildPlatform; - doInstallCheck' = doInstallCheck && stdenv.hostPlatform == stdenv.buildPlatform; + doCheck' = doCheck && stdenv.buildPlatform.canExecute stdenv.hostPlatform; + doInstallCheck' = doInstallCheck && stdenv.buildPlatform.canExecute stdenv.hostPlatform; separateDebugInfo' = separateDebugInfo && stdenv.hostPlatform.isLinux && !(stdenv.hostPlatform.useLLVM or false); outputs' = outputs ++ lib.optional separateDebugInfo' "debug"; From c6cbef9aece79e7dc2957368eceed0840c386638 Mon Sep 17 00:00:00 2001 From: sternenseemann Date: Thu, 28 Apr 2022 14:33:55 +0200 Subject: [PATCH 4/6] libffi: disable tests if linked statically TCL 8.6 which dejagnu requires can't be linked statically. --- pkgs/development/libraries/libffi/default.nix | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/pkgs/development/libraries/libffi/default.nix b/pkgs/development/libraries/libffi/default.nix index 6a22d585fbc..125beae01ef 100644 --- a/pkgs/development/libraries/libffi/default.nix +++ b/pkgs/development/libraries/libffi/default.nix @@ -1,7 +1,9 @@ { lib, stdenv, fetchurl, fetchpatch , autoreconfHook -, doCheck ? true # test suite depends on dejagnu which cannot be used during bootstrapping + # test suite depends on dejagnu which cannot be used during bootstrapping + # dejagnu also requires tcl which can't be built statically at the moment +, doCheck ? !(stdenv.hostPlatform.isStatic) , dejagnu }: From 1f8bae43e49e3147028cd42b8e789454bede2975 Mon Sep 17 00:00:00 2001 From: sternenseemann Date: Thu, 28 Apr 2022 16:52:25 +0200 Subject: [PATCH 5/6] nixos/doc/rl-2211.section.md: changes w.r.t. cross check execution --- .../from_md/release-notes/rl-2211.section.xml | 33 ++++++++++++++++--- .../manual/release-notes/rl-2211.section.md | 20 +++++++++-- 2 files changed, 47 insertions(+), 6 deletions(-) diff --git a/nixos/doc/manual/from_md/release-notes/rl-2211.section.xml b/nixos/doc/manual/from_md/release-notes/rl-2211.section.xml index b34d182183c..4abcf0165a4 100644 --- a/nixos/doc/manual/from_md/release-notes/rl-2211.section.xml +++ b/nixos/doc/manual/from_md/release-notes/rl-2211.section.xml @@ -13,8 +13,22 @@ - Please remove this line when you add the first item since - docbook requires the section to be non-empty + During cross-compilation, tests are now executed if the test + suite can be executed by the build platform. This is the case + when doing “native” cross-compilation where the build and host + platforms are largely the same, but the nixpkgs’ cross + compilation infrastructure is used, e.g. + pkgsStatic and pkgsLLVM. + Another possibility is that the build platform is a superset + of the host platform, e.g. when cross-compiling from + x86_64-unknown-linux to + i686-unknown-linux. The predicate gating + test suite execution is the newly added + canExecute predicate: You can e.g. check if + stdenv.buildPlatform can execute binaries + built for stdenv.hostPlatform (i.e. + produced by stdenv.cc) by evaluating + stdenv.buildPlatform.canExecute stdenv.hostPlatform. @@ -35,8 +49,19 @@ - Please remove this line when you add the first item since - docbook requires the section to be non-empty + The isCompatible predicate checking CPU + compatibility is no longer exposed by the platform sets + generated using lib.systems.elaborate. In + most cases you will want to use the new + canExecute predicate instead which also + considers the kernel / syscall interface. It is briefly + described in the release’s + highlights + section. + lib.systems.parse.isCompatible still + exists, but has changed semantically: Architectures with + differing endianness modes are no longer considered + compatible. diff --git a/nixos/doc/manual/release-notes/rl-2211.section.md b/nixos/doc/manual/release-notes/rl-2211.section.md index a795c09dcf1..6dec063f403 100644 --- a/nixos/doc/manual/release-notes/rl-2211.section.md +++ b/nixos/doc/manual/release-notes/rl-2211.section.md @@ -6,7 +6,16 @@ Support is planned until the end of June 2023, handing over to 23.05. In addition to numerous new and upgraded packages, this release has the following highlights: -- Please remove this line when you add the first item since docbook requires the section to be non-empty +- During cross-compilation, tests are now executed if the test suite can be executed + by the build platform. This is the case when doing “native” cross-compilation + where the build and host platforms are largely the same, but the nixpkgs' cross + compilation infrastructure is used, e.g. `pkgsStatic` and `pkgsLLVM`. Another + possibility is that the build platform is a superset of the host platform, e.g. when + cross-compiling from `x86_64-unknown-linux` to `i686-unknown-linux`. + The predicate gating test suite execution is the newly added `canExecute` + predicate: You can e.g. check if `stdenv.buildPlatform` can execute binaries + built for `stdenv.hostPlatform` (i.e. produced by `stdenv.cc`) by evaluating + `stdenv.buildPlatform.canExecute stdenv.hostPlatform`. @@ -18,7 +27,14 @@ In addition to numerous new and upgraded packages, this release has the followin ## Backward Incompatibilities {#sec-release-22.11-incompatibilities} -- Please remove this line when you add the first item since docbook requires the section to be non-empty +- The `isCompatible` predicate checking CPU compatibility is no longer exposed + by the platform sets generated using `lib.systems.elaborate`. In most cases + you will want to use the new `canExecute` predicate instead which also + considers the kernel / syscall interface. It is briefly described in the + release's [highlights section](#sec-release-22.11-highlights). + `lib.systems.parse.isCompatible` still exists, but has changed semantically: + Architectures with differing endianness modes are *no longer considered compatible*. + ## Other Notable Changes {#sec-release-22.11-notable-changes} From 82c434b3ded704e249374e96e6819760735a76fa Mon Sep 17 00:00:00 2001 From: sternenseemann Date: Mon, 23 May 2022 21:23:17 +0200 Subject: [PATCH 6/6] lib.systems: inform isCompatible users about removal --- lib/systems/default.nix | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/systems/default.nix b/lib/systems/default.nix index 74f84914faa..4d5f97aeda0 100644 --- a/lib/systems/default.nix +++ b/lib/systems/default.nix @@ -38,6 +38,7 @@ rec { canExecute = platform: parse.isCompatible final.parsed.cpu platform.parsed.cpu && final.parsed.kernel == platform.parsed.kernel; + isCompatible = _: throw "2022-05-23: isCompatible has been removed in favor of canExecute, refer to the 22.11 changelog for details"; # Derived meta-data libc = /**/ if final.isDarwin then "libSystem"