about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/libstore/build.cc36
-rw-r--r--src/libstore/globals.cc1
-rw-r--r--src/libstore/globals.hh4
3 files changed, 41 insertions, 0 deletions
diff --git a/src/libstore/build.cc b/src/libstore/build.cc
index 1fc5d4181d57..08b647cd6192 100644
--- a/src/libstore/build.cc
+++ b/src/libstore/build.cc
@@ -1969,6 +1969,42 @@ void DerivationGoal::startBuilder()
                 }
     }
 
+    if (settings.preBuildHook != "") {
+        printMsg(lvlChatty, format("executing pre-build hook ‘%1%’")
+            % settings.preBuildHook);
+        auto args = useChroot ? Strings({drvPath, chrootRootDir}) :
+            Strings({ drvPath });
+        enum BuildHookState {
+            stBegin,
+            stExtraChrootDirs
+        };
+        auto state = stBegin;
+        auto lines = runProgram(settings.preBuildHook, false, args);
+        auto lastPos = std::string::size_type{0};
+        for (auto nlPos = lines.find('\n'); nlPos != string::npos;
+                nlPos = lines.find('\n', lastPos)) {
+            auto line = std::string{lines, lastPos, nlPos};
+            lastPos = nlPos + 1;
+            if (state == stBegin) {
+                if (line == "extra-chroot-dirs") {
+                    state = stExtraChrootDirs;
+                } else {
+                    throw Error(format("unknown pre-build hook command ‘%1%’")
+                        % line);
+                }
+            } else if (state == stExtraChrootDirs) {
+                if (line == "") {
+                    state = stBegin;
+                } else {
+                    auto p = line.find('=');
+                    if (p == string::npos)
+                        dirsInChroot[line] = line;
+                    else
+                        dirsInChroot[string(line, 0, p)] = string(line, p + 1);
+                }
+            }
+        }
+    }
 
     /* Run the builder. */
     printMsg(lvlChatty, format("executing builder ‘%1%’") % drv.builder);
diff --git a/src/libstore/globals.cc b/src/libstore/globals.cc
index 052ca45ccc46..d5615d93c7d0 100644
--- a/src/libstore/globals.cc
+++ b/src/libstore/globals.cc
@@ -182,6 +182,7 @@ void Settings::update()
     _get(logServers, "log-servers");
     _get(enableImportNative, "allow-unsafe-native-code-during-evaluation");
     _get(useCaseHack, "use-case-hack");
+    _get(preBuildHook, "pre-build-hook");
 
     string subs = getEnv("NIX_SUBSTITUTERS", "default");
     if (subs == "default") {
diff --git a/src/libstore/globals.hh b/src/libstore/globals.hh
index 195558dd3e99..60b11afe6088 100644
--- a/src/libstore/globals.hh
+++ b/src/libstore/globals.hh
@@ -206,6 +206,10 @@ struct Settings {
     /* Whether the importNative primop should be enabled */
     bool enableImportNative;
 
+    /* The hook to run just before a build to set derivation-specific
+       build settings */
+    Path preBuildHook;
+
 private:
     SettingsMap settings, overrides;