aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorShea Levy <shea@shealevy.com>2015-04-18 16:56:02 -0400
committerShea Levy <shea@shealevy.com>2015-04-18 16:56:02 -0400
commit4d652875bdd87c3f1aa08111c63c0719f1ee0c1a (patch)
treebf2e1a7008341c874e2b156517d582f0c12e7201 /src
parentfd6774e285760b384b0d8a0946b8ba8001b67b82 (diff)
Add the pre-build hook.
This hook can be used to set system-specific per-derivation build settings that don't fit into the derivation model and are too complex or volatile to be hard-coded into nix. Currently, the pre-build hook can only add chroot dirs/files through the interface, but it also has full access to the chroot root. The specific use case for this is systems where the operating system ABI is more complex than just the kernel-support system calls. For example, on OS X there is a set of system-provided frameworks that can reliably be accessed by any program linked to them, no matter the version the program is running on. Unfortunately, those frameworks do not necessarily live in the same locations on each version of OS X, nor do their dependencies, and thus nix needs to know the specific version of OS X currently running in order to make those frameworks available. The pre-build hook is a perfect mechanism for doing just that.
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 1fc5d4181..08b647cd6 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 052ca45cc..d5615d93c 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 195558dd3..60b11afe6 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;