diff options
-rw-r--r-- | doc/manual/command-ref/conf-file.xml | 34 | ||||
-rw-r--r-- | src/libstore/build.cc | 36 | ||||
-rw-r--r-- | src/libstore/globals.cc | 1 | ||||
-rw-r--r-- | src/libstore/globals.hh | 4 |
4 files changed, 75 insertions, 0 deletions
diff --git a/doc/manual/command-ref/conf-file.xml b/doc/manual/command-ref/conf-file.xml index 89b8aac7834f..ec96f750ea8c 100644 --- a/doc/manual/command-ref/conf-file.xml +++ b/doc/manual/command-ref/conf-file.xml @@ -562,6 +562,40 @@ flag, e.g. <literal>--option gc-keep-outputs false</literal>.</para> </varlistentry> + <varlistentry xml:id="conf-pre-build-hook"><term><literal>pre-build-hook</literal></term> + + <listitem> + + + <para>If set, the path to a program that can set extra + derivation-specific settings for this system. This is used for settings + that can't be captured by the derivation model itself and are too variable + between different versions of the same system to be hard-coded into nix. + </para> + + <para>The hook is passed the derivation path and, if chroots are enabled, + the chroot directory. It can then modify the chroot and send a series of + commands to modify various settings to stdout. The currently recognized + commands are:</para> + + <variablelist> + <varlistentry xml:id="extra-chroot-dirs"><term><literal>extra-chroot-dirs</literal></term> + + <listitem> + + <para>Pass a list of files and directories to be included in the + chroot for this build. One entry per line, terminated by an empty + line. Entries have the same format as build-chroot-dirs.</para> + + </listitem> + + </varlistentry> + </variablelist> + </listitem> + + </varlistentry> + + </variablelist> </para> 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; |