From 7bf2a70a4ffd976d50638d3b9f2ec409763157df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludovic=20Court=C3=A8s?= Date: Tue, 9 Jan 2018 17:04:02 +0100 Subject: [PATCH] daemon: Always try to execute the builder regardless of the platform. * nix/libstore/build.cc (runChild): Move platform check after 'execve' call. Check specifically for ENOEXEC. --- nix/libstore/build.cc | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/nix/libstore/build.cc b/nix/libstore/build.cc index 275d6a5f7c..34647e6774 100644 --- a/nix/libstore/build.cc +++ b/nix/libstore/build.cc @@ -1682,15 +1682,6 @@ void DerivationGoal::startBuilder() f.exceptions(boost::io::all_error_bits ^ boost::io::too_many_args_bit); startNest(nest, lvlInfo, f % showPaths(missingPaths) % curRound % nrRounds); - /* Right platform? */ - if (!canBuildLocally(drv.platform)) { - if (settings.printBuildTrace) - printMsg(lvlError, format("@ unsupported-platform %1% %2%") % drvPath % drv.platform); - throw Error( - format("a `%1%' is required to build `%3%', but I am a `%2%'") - % drv.platform % settings.thisSystem % drvPath); - } - /* Note: built-in builders are *not* running in a chroot environment so that we can easily implement them in Guile without having it as a derivation input (they are running under a separate build user, @@ -2311,6 +2302,20 @@ void DerivationGoal::runChild() execve(drv.builder.c_str(), stringsToCharPtrs(args).data(), stringsToCharPtrs(envStrs).data()); + int error = errno; + + /* Right platform? Check this after we've tried 'execve' to allow for + transparent emulation of different platforms with binfmt_misc + handlers that invoke QEMU. */ + if (error == ENOEXEC && !canBuildLocally(drv.platform)) { + if (settings.printBuildTrace) + printMsg(lvlError, format("@ unsupported-platform %1% %2%") % drvPath % drv.platform); + throw Error( + format("a `%1%' is required to build `%3%', but I am a `%2%'") + % drv.platform % settings.thisSystem % drvPath); + } + + errno = error; throw SysError(format("executing `%1%'") % drv.builder); } catch (std::exception & e) {