summary refs log tree commit diff
path: root/nix/libstore/build.cc
diff options
context:
space:
mode:
Diffstat (limited to 'nix/libstore/build.cc')
-rw-r--r--nix/libstore/build.cc33
1 files changed, 23 insertions, 10 deletions
diff --git a/nix/libstore/build.cc b/nix/libstore/build.cc
index 88f8d11103..c894d72bda 100644
--- a/nix/libstore/build.cc
+++ b/nix/libstore/build.cc
@@ -1386,11 +1386,6 @@ void DerivationGoal::buildDone()
            being valid. */
         registerOutputs();
 
-        if (buildMode == bmCheck) {
-            done(BuildResult::Built);
-            return;
-        }
-
         /* Delete unused redirected outputs (when doing hash rewriting). */
         foreach (RedirectedOutputs::iterator, i, redirectedOutputs)
             if (pathExists(i->second)) deletePath(i->second);
@@ -1946,6 +1941,15 @@ void DerivationGoal::startBuilder()
 
 }
 
+/* Return true if the operating system kernel part of SYSTEM1 and SYSTEM2 (the
+   bit that comes after the hyphen in system types such as "i686-linux") is
+   the same.  */
+static bool sameOperatingSystemKernel(const std::string& system1, const std::string& system2)
+{
+    auto os1 = system1.substr(system1.find("-"));
+    auto os2 = system2.substr(system2.find("-"));
+    return os1 == os2;
+}
 
 void DerivationGoal::runChild()
 {
@@ -2208,9 +2212,20 @@ void DerivationGoal::runChild()
         foreach (Strings::iterator, i, drv.args)
             args.push_back(rewriteHashes(*i, rewritesToTmp));
 
-        execve(drv.builder.c_str(), stringsToCharPtrs(args).data(), stringsToCharPtrs(envStrs).data());
-
-	int error = errno;
+	/* If DRV targets the same operating system kernel, try to execute it:
+	   there might be binfmt_misc set up for user-land emulation of other
+	   architectures.  However, if it targets a different operating
+	   system--e.g., "i586-gnu" vs. "x86_64-linux"--do not try executing
+	   it: the ELF file for that OS is likely indistinguishable from a
+	   native ELF binary and it would just crash at run time.  */
+	int error;
+	if (sameOperatingSystemKernel(drv.platform, settings.thisSystem)) {
+	    execve(drv.builder.c_str(), stringsToCharPtrs(args).data(),
+		   stringsToCharPtrs(envStrs).data());
+	    error = errno;
+	} else {
+	    error = ENOEXEC;
+	}
 
 	/* Right platform?  Check this after we've tried 'execve' to allow for
 	   transparent emulation of different platforms with binfmt_misc
@@ -2465,8 +2480,6 @@ void DerivationGoal::registerOutputs()
         infos.push_back(info);
     }
 
-    if (buildMode == bmCheck) return;
-
     /* Compare the result with the previous round, and report which
        path is different, if any.*/
     if (curRound > 1 && prevInfos != infos) {