aboutsummaryrefslogtreecommitdiff
path: root/nix/libstore/build.cc
diff options
context:
space:
mode:
Diffstat (limited to 'nix/libstore/build.cc')
-rw-r--r--nix/libstore/build.cc83
1 files changed, 69 insertions, 14 deletions
diff --git a/nix/libstore/build.cc b/nix/libstore/build.cc
index d68e8b2bc0..34647e6774 100644
--- a/nix/libstore/build.cc
+++ b/nix/libstore/build.cc
@@ -31,7 +31,11 @@
#include <pwd.h>
#include <grp.h>
-#include <bzlib.h>
+#include <zlib.h>
+
+#if HAVE_BZLIB_H
+# include <bzlib.h>
+#endif
/* Includes required for chroot support. */
#if HAVE_SYS_PARAM_H
@@ -744,7 +748,10 @@ private:
/* File descriptor for the log file. */
FILE * fLogFile;
+ gzFile gzLogFile;
+#if HAVE_BZLIB_H
BZFILE * bzLogFile;
+#endif
AutoCloseFD fdLogFile;
/* Number of bytes received from the builder's stdout/stderr. */
@@ -892,7 +899,10 @@ DerivationGoal::DerivationGoal(const Path & drvPath, const StringSet & wantedOut
, needRestart(false)
, retrySubstitution(false)
, fLogFile(0)
+ , gzLogFile(0)
+#if HAVE_BZLIB_H
, bzLogFile(0)
+#endif
, useChroot(false)
, buildMode(buildMode)
{
@@ -1672,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,
@@ -2301,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) {
@@ -2599,8 +2614,26 @@ Path DerivationGoal::openLogFile()
Path dir = (format("%1%/%2%/%3%/") % settings.nixLogDir % drvsLogDir % string(baseName, 0, 2)).str();
createDirs(dir);
- if (settings.compressLog) {
+ switch (settings.logCompression)
+ {
+ case COMPRESSION_GZIP: {
+ Path logFileName = (format("%1%/%2%.gz") % dir % string(baseName, 2)).str();
+ AutoCloseFD fd = open(logFileName.c_str(), O_CREAT | O_WRONLY | O_TRUNC, 0666);
+ if (fd == -1) throw SysError(format("creating log file `%1%'") % logFileName);
+ closeOnExec(fd);
+
+ /* Note: FD will be closed by 'gzclose'. */
+ if (!(gzLogFile = gzdopen(fd.borrow(), "w")))
+ throw Error(format("cannot open compressed log file `%1%'") % logFileName);
+
+ gzbuffer(gzLogFile, 32768);
+ gzsetparams(gzLogFile, Z_BEST_COMPRESSION, Z_DEFAULT_STRATEGY);
+ return logFileName;
+ }
+
+#if HAVE_BZLIB_H
+ case COMPRESSION_BZIP2: {
Path logFileName = (format("%1%/%2%.bz2") % dir % string(baseName, 2)).str();
AutoCloseFD fd = open(logFileName.c_str(), O_CREAT | O_WRONLY | O_TRUNC, 0666);
if (fd == -1) throw SysError(format("creating log file `%1%'") % logFileName);
@@ -2614,25 +2647,38 @@ Path DerivationGoal::openLogFile()
throw Error(format("cannot open compressed log file `%1%'") % logFileName);
return logFileName;
+ }
+#endif
- } else {
+ case COMPRESSION_NONE: {
Path logFileName = (format("%1%/%2%") % dir % string(baseName, 2)).str();
fdLogFile = open(logFileName.c_str(), O_CREAT | O_WRONLY | O_TRUNC, 0666);
if (fdLogFile == -1) throw SysError(format("creating log file `%1%'") % logFileName);
closeOnExec(fdLogFile);
return logFileName;
+ }
}
+
+ abort();
}
void DerivationGoal::closeLogFile()
{
- if (bzLogFile) {
+ if (gzLogFile) {
+ int err;
+ err = gzclose(gzLogFile);
+ gzLogFile = NULL;
+ if (err != Z_OK) throw Error(format("cannot close compressed log file (gzip error = %1%)") % err);
+ }
+#if HAVE_BZLIB_H
+ else if (bzLogFile) {
int err;
BZ2_bzWriteClose(&err, bzLogFile, 0, 0, 0);
bzLogFile = 0;
if (err != BZ_OK) throw Error(format("cannot close compressed log file (BZip2 error = %1%)") % err);
}
+#endif
if (fLogFile) {
fclose(fLogFile);
@@ -2695,10 +2741,19 @@ void DerivationGoal::handleChildOutput(int fd, const string & data)
}
if (verbosity >= settings.buildVerbosity)
writeToStderr(data);
- if (bzLogFile) {
+
+ if (gzLogFile) {
+ if (data.size() > 0) {
+ int count, err;
+ count = gzwrite(gzLogFile, data.data(), data.size());
+ if (count == 0) throw Error(format("cannot write to compressed log file (gzip error = %1%)") % gzerror(gzLogFile, &err));
+ }
+#if HAVE_BZLIB_H
+ } else if (bzLogFile) {
int err;
BZ2_bzWrite(&err, bzLogFile, (unsigned char *) data.data(), data.size());
if (err != BZ_OK) throw Error(format("cannot write to compressed log file (BZip2 error = %1%)") % err);
+#endif
} else if (fdLogFile != -1)
writeFull(fdLogFile, data);
}