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.
This commit is contained in:
parent
fd6774e285
commit
4d652875bd
4 changed files with 75 additions and 0 deletions
|
@ -562,6 +562,40 @@ flag, e.g. <literal>--option gc-keep-outputs false</literal>.</para>
|
||||||
</varlistentry>
|
</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>
|
</variablelist>
|
||||||
|
|
||||||
</para>
|
</para>
|
||||||
|
|
|
@ -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. */
|
/* Run the builder. */
|
||||||
printMsg(lvlChatty, format("executing builder ‘%1%’") % drv.builder);
|
printMsg(lvlChatty, format("executing builder ‘%1%’") % drv.builder);
|
||||||
|
|
|
@ -182,6 +182,7 @@ void Settings::update()
|
||||||
_get(logServers, "log-servers");
|
_get(logServers, "log-servers");
|
||||||
_get(enableImportNative, "allow-unsafe-native-code-during-evaluation");
|
_get(enableImportNative, "allow-unsafe-native-code-during-evaluation");
|
||||||
_get(useCaseHack, "use-case-hack");
|
_get(useCaseHack, "use-case-hack");
|
||||||
|
_get(preBuildHook, "pre-build-hook");
|
||||||
|
|
||||||
string subs = getEnv("NIX_SUBSTITUTERS", "default");
|
string subs = getEnv("NIX_SUBSTITUTERS", "default");
|
||||||
if (subs == "default") {
|
if (subs == "default") {
|
||||||
|
|
|
@ -206,6 +206,10 @@ struct Settings {
|
||||||
/* Whether the importNative primop should be enabled */
|
/* Whether the importNative primop should be enabled */
|
||||||
bool enableImportNative;
|
bool enableImportNative;
|
||||||
|
|
||||||
|
/* The hook to run just before a build to set derivation-specific
|
||||||
|
build settings */
|
||||||
|
Path preBuildHook;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
SettingsMap settings, overrides;
|
SettingsMap settings, overrides;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue