From eb03a296c1a538111056ce0d554911410c4ccb48 Mon Sep 17 00:00:00 2001 From: Linus Heckemann Date: Tue, 20 Feb 2018 12:34:50 +0000 Subject: [PATCH 1/4] Add build-extra-platforms setting This allows specifying additional systems that a machine is able to build for. This may apply on some armv7-capable aarch64 processors, or on systems using qemu-user with binfmt-misc to support transparent execution of foreign-arch programs. This removes the previous hard-coded assumptions about which systems are ABI-compatible with which other systems, and instead relies on the user to specify any additional platforms that they have ensured compatibility for and wish to build for locally. NixOS should probably add i686-linux on x86_64-linux systems for this setting by default. --- src/libstore/derivations.cc | 12 ++---------- src/libstore/globals.hh | 3 +++ 2 files changed, 5 insertions(+), 10 deletions(-) diff --git a/src/libstore/derivations.cc b/src/libstore/derivations.cc index a0a0d78b7..74b861281 100644 --- a/src/libstore/derivations.cc +++ b/src/libstore/derivations.cc @@ -57,16 +57,8 @@ bool BasicDerivation::isBuiltin() const bool BasicDerivation::canBuildLocally() const { return platform == settings.thisSystem - || isBuiltin() -#if __linux__ - || (platform == "i686-linux" && settings.thisSystem == "x86_64-linux") - || (platform == "armv6l-linux" && settings.thisSystem == "armv7l-linux") - || (platform == "armv5tel-linux" && (settings.thisSystem == "armv7l-linux" || settings.thisSystem == "armv6l-linux")) -#elif __FreeBSD__ - || (platform == "i686-linux" && settings.thisSystem == "x86_64-freebsd") - || (platform == "i686-linux" && settings.thisSystem == "i686-freebsd") -#endif - ; + || settings.extraPlatforms.get().count(platform) > 0 + || isBuiltin(); } diff --git a/src/libstore/globals.hh b/src/libstore/globals.hh index dd01f832d..b382da01e 100644 --- a/src/libstore/globals.hh +++ b/src/libstore/globals.hh @@ -295,6 +295,9 @@ public: "Nix store has a valid signature (that is, one signed using a key " "listed in 'trusted-public-keys'."}; + Setting extraPlatforms{this, StringSet{}, "build-extra-platforms", + "Additional platforms that can be built on the local system, e.g. using qemu-user."}; + Setting substituters{this, nixStore == "/nix/store" ? Strings{"https://cache.nixos.org/"} : Strings(), "substituters", From 919c3c20b3ebbf8b83b8de28b612d09270e7a2a6 Mon Sep 17 00:00:00 2001 From: Linus Heckemann Date: Tue, 20 Feb 2018 12:30:03 +0000 Subject: [PATCH 2/4] seccomp: add 32-bit ARM on aarch64-linux This allows building armv[67]l-linux derivations on compatible aarch64 machines. Failure to add the architecture may result from missing hardware support, in which case we can't run 32-bit binaries and don't need to restrict them with seccomp anyway, --- src/libstore/build.cc | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/libstore/build.cc b/src/libstore/build.cc index 1d611ffba..2466f9bd6 100644 --- a/src/libstore/build.cc +++ b/src/libstore/build.cc @@ -2491,6 +2491,10 @@ void setupSeccomp() seccomp_arch_add(ctx, SCMP_ARCH_X32) != 0) throw SysError("unable to add X32 seccomp architecture"); + if (settings.thisSystem == "aarch64-linux" && + seccomp_arch_add(ctx, SCMP_ARCH_ARM) != 0) + printError("unsable to add ARM seccomp architecture; this may result in spurious build failures if running 32-bit ARM processes."); + /* Prevent builders from creating setuid/setgid binaries. */ for (int perm : { S_ISUID, S_ISGID }) { if (seccomp_rule_add(ctx, SCMP_ACT_ERRNO(EPERM), SCMP_SYS(chmod), 1, From 637701b6047bff23a7dea4e02bebf94660b8cb4c Mon Sep 17 00:00:00 2001 From: Linus Heckemann Date: Fri, 16 Mar 2018 22:50:27 +0000 Subject: [PATCH 3/4] rename build-extra-platforms -> extra-platforms also document it --- doc/manual/command-ref/conf-file.xml | 19 +++++++++++++++++++ src/libstore/globals.hh | 8 ++++++-- 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/doc/manual/command-ref/conf-file.xml b/doc/manual/command-ref/conf-file.xml index c76640c97..5c21a40a1 100644 --- a/doc/manual/command-ref/conf-file.xml +++ b/doc/manual/command-ref/conf-file.xml @@ -254,6 +254,25 @@ false. + extra-platforms + + Platforms other than the native one which + this machine is capable of building for. This can be useful for + supporting additional architectures on compatible machines: + i686-linux can be built on x86_64-linux machines (and the default + for this setting reflects this); armv7 is backwards-compatible with + armv6 and armv5tel; some aarch64 machines can also natively run + 32-bit ARM code; and qemu-user may be used to support non-native + platforms (though this may be slow and buggy). Most values for this + are not enabled by default because build systems will often + misdetect the target platform and generate incompatible code, so you + may wish to cross-check the results of using this option against + proper natively-built versions of your + derivations. + + + + extra-substituters Additional binary caches appended to those diff --git a/src/libstore/globals.hh b/src/libstore/globals.hh index b382da01e..897d53b7b 100644 --- a/src/libstore/globals.hh +++ b/src/libstore/globals.hh @@ -295,8 +295,12 @@ public: "Nix store has a valid signature (that is, one signed using a key " "listed in 'trusted-public-keys'."}; - Setting extraPlatforms{this, StringSet{}, "build-extra-platforms", - "Additional platforms that can be built on the local system, e.g. using qemu-user."}; + Setting extraPlatforms{this, + SYSTEM == "x86_64-linux" ? StringSet{"i686-linux"} : StringSet{}, + "extra-platforms", + "Additional platforms that can be built on the local system. " + "These may be supported natively (e.g. armv7 on some aarch64 CPUs " + "or using hacks like qemu-user."}; Setting substituters{this, nixStore == "/nix/store" ? Strings{"https://cache.nixos.org/"} : Strings(), From 639c166647ae733e927ae589864d996bb2d95b88 Mon Sep 17 00:00:00 2001 From: Linus Heckemann Date: Fri, 16 Mar 2018 22:50:57 +0000 Subject: [PATCH 4/4] build-remote: take extra-platforms into account --- src/build-remote/build-remote.cc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/build-remote/build-remote.cc b/src/build-remote/build-remote.cc index dbf8fe1b8..5ec49b525 100644 --- a/src/build-remote/build-remote.cc +++ b/src/build-remote/build-remote.cc @@ -98,7 +98,9 @@ int main (int argc, char * * argv) source >> drvPath; auto requiredFeatures = readStrings>(source); - auto canBuildLocally = amWilling && (neededSystem == settings.thisSystem); + auto canBuildLocally = amWilling + && ( neededSystem == settings.thisSystem + || settings.extraPlatforms.get().count(neededSystem) > 0); /* Error ignored here, will be caught later */ mkdir(currentLoad.c_str(), 0777);