about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/libmain/shared.cc2
-rw-r--r--src/libstore/build.cc49
-rw-r--r--src/libstore/globals.cc1
-rw-r--r--src/libstore/globals.hh16
-rw-r--r--src/libstore/remote-store.cc5
-rw-r--r--src/nix-worker/nix-worker.cc5
6 files changed, 71 insertions, 7 deletions
diff --git a/src/libmain/shared.cc b/src/libmain/shared.cc
index 4725d1ed1047..dee9a5320cc8 100644
--- a/src/libmain/shared.cc
+++ b/src/libmain/shared.cc
@@ -220,6 +220,8 @@ static void initAndRun(int argc, char * * argv)
             ; /* !!! obsolete - remove eventually */
         else if (arg == "--no-build-output" || arg == "-Q")
             buildVerbosity = lvlVomit;
+        else if (arg == "--print-build-trace")
+            printBuildTrace = true;
         else if (arg == "--help") {
             printHelp();
             return;
diff --git a/src/libstore/build.cc b/src/libstore/build.cc
index 3cd281fc839f..436cf4762ddd 100644
--- a/src/libstore/build.cc
+++ b/src/libstore/build.cc
@@ -778,7 +778,7 @@ private:
     void computeClosure();
 
     /* Open a log file and a pipe to it. */
-    void openLogFile();
+    Path openLogFile();
 
     /* Common initialisation to be performed in child processes (i.e.,
        both in builders and in build hooks). */
@@ -1081,6 +1081,10 @@ void DerivationGoal::tryToBuild()
 
     } catch (BuildError & e) {
         printMsg(lvlError, e.msg());
+        if (printBuildTrace) {
+            printMsg(lvlError, format("@ build-failed %1% %2% %3% %4%")
+                % drvPath % drv.outputs["out"].path % 0 % e.msg());
+        }
         amDone(ecFailed);
         return;
     }
@@ -1171,9 +1175,13 @@ void DerivationGoal::buildDone()
         /* Compute the FS closure of the outputs and register them as
            being valid. */
         computeClosure();
-        
+
     } catch (BuildError & e) {
         printMsg(lvlError, e.msg());
+        if (printBuildTrace) {
+            printMsg(lvlError, format("@ build-failed %1% %2% %3% %4%")
+                % drvPath % drv.outputs["out"].path % status % e.msg());
+        }
         amDone(ecFailed);
         return;
     }
@@ -1181,6 +1189,11 @@ void DerivationGoal::buildDone()
     /* Release the build user, if applicable. */
     buildUser.release();
 
+    if (printBuildTrace) {
+        printMsg(lvlError, format("@ build-succeeded %1% %2%")
+            % drvPath % drv.outputs["out"].path);
+    }
+    
     amDone(ecSuccess);
 }
 
@@ -1250,7 +1263,7 @@ DerivationGoal::HookReply DerivationGoal::tryBuildHook()
     tmpDir = createTempDir();
     
     /* Create the log file and pipe. */
-    openLogFile();
+    Path logFile = openLogFile();
 
     /* Create the communication pipes. */
     toHook.create();
@@ -1369,6 +1382,11 @@ DerivationGoal::HookReply DerivationGoal::tryBuildHook()
         /* Tell the hook to proceed. */ 
         writeLine(toHook.writeSide, "okay");
 
+        if (printBuildTrace) {
+            printMsg(lvlError, format("@ build-started %1% %2% %3% %4%")
+                % drvPath % drv.outputs["out"].path % drv.platform % logFile);
+        }
+        
         return rpAccept;
     }
 
@@ -1774,7 +1792,7 @@ void DerivationGoal::startBuilder()
         drv.builder);
 
     /* Create the log file and pipe. */
-    openLogFile();
+    Path logFile = openLogFile();
     
     /* Fork a child to build the package.  Note that while we
        currently use forks to run and wait for the children, it
@@ -1878,6 +1896,11 @@ void DerivationGoal::startBuilder()
     logPipe.writeSide.close();
     worker.childStarted(shared_from_this(), pid,
         singleton<set<int> >(logPipe.readSide), true);
+
+    if (printBuildTrace) {
+        printMsg(lvlError, format("@ build-started %1% %2% %3% %4%")
+            % drvPath % drv.outputs["out"].path % drv.platform % logFile);
+    }
 }
 
 
@@ -2023,7 +2046,7 @@ void DerivationGoal::computeClosure()
 string drvsLogDir = "drvs";
 
 
-void DerivationGoal::openLogFile()
+Path DerivationGoal::openLogFile()
 {
     /* Create a log file. */
     Path dir = (format("%1%/%2%") % nixLogDir % drvsLogDir).str();
@@ -2037,6 +2060,8 @@ void DerivationGoal::openLogFile()
 
     /* Create a pipe to get the output of the child. */
     logPipe.create();
+
+    return logFileName;
 }
 
 
@@ -2367,6 +2392,11 @@ void SubstitutionGoal::tryToRun()
         pid, singleton<set<int> >(logPipe.readSide), true);
 
     state = &SubstitutionGoal::finished;
+
+    if (printBuildTrace) {
+        printMsg(lvlError, format("@ substituter-started %1% %2%")
+            % storePath % sub);
+    }
 }
 
 
@@ -2406,6 +2436,11 @@ void SubstitutionGoal::finished()
             format("substitution of path `%1%' using substituter `%2%' failed: %3%")
             % storePath % sub % e.msg());
         
+        if (printBuildTrace) {
+            printMsg(lvlError, format("@ substituter-failed %1% %2% %3%")
+                % storePath % status % e.msg());
+        }
+        
         /* Try the next substitute. */
         state = &SubstitutionGoal::tryNext;
         worker.wakeUp(shared_from_this());
@@ -2424,6 +2459,10 @@ void SubstitutionGoal::finished()
     printMsg(lvlChatty,
         format("substitution of path `%1%' succeeded") % storePath);
 
+    if (printBuildTrace) {
+        printMsg(lvlError, format("@ substituter-succeeded %1%") % storePath);
+    }
+    
     amDone(ecSuccess);
 }
 
diff --git a/src/libstore/globals.cc b/src/libstore/globals.cc
index 7228fc19364d..19087f657d56 100644
--- a/src/libstore/globals.cc
+++ b/src/libstore/globals.cc
@@ -28,6 +28,7 @@ string thisSystem = "unset";
 unsigned int maxSilentTime = 0;
 Paths substituters;
 bool useBuildHook = true;
+bool printBuildTrace = false;
 
 
 static bool settingsRead = false;
diff --git a/src/libstore/globals.hh b/src/libstore/globals.hh
index a97aa6d8b5ec..2eb68625a6f5 100644
--- a/src/libstore/globals.hh
+++ b/src/libstore/globals.hh
@@ -82,6 +82,22 @@ extern Paths substituters;
    users want to disable this from the command-line. */
 extern bool useBuildHook;
 
+/* Whether buildDerivations() should print out lines on stderr in a
+   fixed format to allow its progress to be monitored.  Each line
+   starts with a "@".  The following are defined:
+
+   @ build-started <drvpath> <outpath> <system> <logfile>
+   @ build-failed <drvpath> <outpath> <exitcode> <error text>
+   @ build-succeeded <drvpath> <outpath>
+   @ substituter-started <outpath> <substituter>
+   @ substituter-failed <outpath> <exitcode> <error text>
+   @ substituter-succeeded <outpath>
+
+   Best combined with --no-build-output, otherwise stderr might
+   conceivably contain lines in this format printed by the builders.
+*/
+extern bool printBuildTrace;
+
 
 Strings querySetting(const string & name, const Strings & def);
 
diff --git a/src/libstore/remote-store.cc b/src/libstore/remote-store.cc
index b896734416d1..7e5fa2d865d9 100644
--- a/src/libstore/remote-store.cc
+++ b/src/libstore/remote-store.cc
@@ -183,8 +183,11 @@ void RemoteStore::setOptions()
     writeInt(maxSilentTime, to);
     if (GET_PROTOCOL_MINOR(daemonVersion) >= 2)
         writeInt(useBuildHook, to);
-    if (GET_PROTOCOL_MINOR(daemonVersion) >= 4)
+    if (GET_PROTOCOL_MINOR(daemonVersion) >= 4) {
         writeInt(buildVerbosity, to);
+        writeInt(logType, to);
+        writeInt(printBuildTrace, to);
+    }
     processStderr();
 }
 
diff --git a/src/nix-worker/nix-worker.cc b/src/nix-worker/nix-worker.cc
index ddc58c024b91..7511b1c2c1e7 100644
--- a/src/nix-worker/nix-worker.cc
+++ b/src/nix-worker/nix-worker.cc
@@ -426,8 +426,11 @@ static void performOp(unsigned int clientVersion,
         maxSilentTime = readInt(from);
         if (GET_PROTOCOL_MINOR(clientVersion) >= 2)
             useBuildHook = readInt(from) != 0;
-        if (GET_PROTOCOL_MINOR(clientVersion) >= 4)
+        if (GET_PROTOCOL_MINOR(clientVersion) >= 4) {
             buildVerbosity = (Verbosity) readInt(from);
+            logType = (LogType) readInt(from);
+            printBuildTrace = readInt(from) != 0;
+        }
         startWork();
         stopWork();
         break;