1
0
Fork 0
mirror of https://github.com/NixOS/nix synced 2025-06-28 22:01:15 +02:00

Move NIX_BIN_DIR and all logic using it to the Nix executable itself

This is because with the split packages of the Meson build, we simply
have no idea what directory the binaries will be installed in when we
build the library.

In the process of doing so, consolidate and make more sophisticated the
logic to cope with a few corner cases (e.g. `NIX_BIN_DIR` exists, but no
binaries are inside it).

Co-authored-by: Robert Hensing <roberth@users.noreply.github.com>
This commit is contained in:
John Ericson 2024-07-24 23:14:36 -04:00
parent 18485d2d53
commit 58b03ef1cd
21 changed files with 227 additions and 82 deletions

View file

@ -64,7 +64,6 @@ Settings::Settings()
, nixStateDir(canonPath(getEnvNonEmpty("NIX_STATE_DIR").value_or(NIX_STATE_DIR)))
, nixConfDir(canonPath(getEnvNonEmpty("NIX_CONF_DIR").value_or(NIX_CONF_DIR)))
, nixUserConfFiles(getUserConfigFiles())
, nixBinDir(canonPath(getEnvNonEmpty("NIX_BIN_DIR").value_or(NIX_BIN_DIR)))
, nixManDir(canonPath(NIX_MAN_DIR))
, nixDaemonSocketFile(canonPath(getEnvNonEmpty("NIX_DAEMON_SOCKET_PATH").value_or(nixStateDir + DEFAULT_SOCKET_PATH)))
{
@ -95,34 +94,6 @@ Settings::Settings()
sandboxPaths = tokenizeString<StringSet>("/System/Library/Frameworks /System/Library/PrivateFrameworks /bin/sh /bin/bash /private/tmp /private/var/tmp /usr/lib");
allowedImpureHostPrefixes = tokenizeString<StringSet>("/System/Library /usr/lib /dev /bin/sh");
#endif
/* Set the build hook location
For builds we perform a self-invocation, so Nix has to be self-aware.
That is, it has to know where it is installed. We don't think it's sentient.
Normally, nix is installed according to `nixBinDir`, which is set at compile time,
but can be overridden. This makes for a great default that works even if this
code is linked as a library into some other program whose main is not aware
that it might need to be a build remote hook.
However, it may not have been installed at all. For example, if it's a static build,
there's a good chance that it has been moved out of its installation directory.
That makes `nixBinDir` useless. Instead, we'll query the OS for the path to the
current executable, using `getSelfExe()`.
As a last resort, we resort to `PATH`. Hopefully we find a `nix` there that's compatible.
If you're porting Nix to a new platform, that might be good enough for a while, but
you'll want to improve `getSelfExe()` to work on your platform.
*/
std::string nixExePath = nixBinDir + "/nix";
if (!pathExists(nixExePath)) {
nixExePath = getSelfExe().value_or("nix");
}
buildHook = {
nixExePath,
"__build-remote",
};
}
void loadConfFile(AbstractConfig & config)

View file

@ -84,11 +84,6 @@ public:
*/
std::vector<Path> nixUserConfFiles;
/**
* The directory where the main programs are stored.
*/
Path nixBinDir;
/**
* The directory where the man pages are stored.
*/
@ -246,7 +241,7 @@ public:
)",
{"build-timeout"}};
Setting<Strings> buildHook{this, {}, "build-hook",
Setting<Strings> buildHook{this, {"nix", "__build-remote"}, "build-hook",
R"(
The path to the helper program that executes remote builds.

View file

@ -71,7 +71,6 @@ libstore_CXXFLAGS += \
-DNIX_STATE_DIR=\"$(NIX_ROOT)$(localstatedir)/nix\" \
-DNIX_LOG_DIR=\"$(NIX_ROOT)$(localstatedir)/log/nix\" \
-DNIX_CONF_DIR=\"$(NIX_ROOT)$(sysconfdir)/nix\" \
-DNIX_BIN_DIR=\"$(NIX_ROOT)$(bindir)\" \
-DNIX_MAN_DIR=\"$(NIX_ROOT)$(mandir)\" \
-DLSOF=\"$(NIX_ROOT)$(lsof)\"

View file

@ -328,7 +328,6 @@ prefix = get_option('prefix')
path_opts = [
# Meson built-ins.
'datadir',
'bindir',
'mandir',
'libdir',
'includedir',
@ -373,7 +372,6 @@ cpp_str_defines = {
'NIX_STATE_DIR': state_dir / 'nix',
'NIX_LOG_DIR': log_dir,
'NIX_CONF_DIR': sysconfdir / 'nix',
'NIX_BIN_DIR': bindir,
'NIX_MAN_DIR': mandir,
}

View file

@ -4,6 +4,7 @@
#include "file-system.hh"
#include "child.hh"
#include "strings.hh"
#include "executable-path.hh"
namespace nix {
@ -16,11 +17,18 @@ HookInstance::HookInstance()
if (buildHookArgs.empty())
throw Error("'build-hook' setting is empty");
auto buildHook = canonPath(buildHookArgs.front());
std::filesystem::path buildHook = buildHookArgs.front();
buildHookArgs.pop_front();
try {
buildHook = ExecutablePath::load().findPath(buildHook);
} catch (ExecutableLookupError & e) {
e.addTrace(nullptr, "while resolving the 'build-hook' setting'");
throw;
}
Strings args;
args.push_back(std::string(baseNameOf(buildHook)));
args.push_back(buildHook.filename().string());
for (auto & arg : buildHookArgs)
args.push_back(arg);
@ -59,7 +67,7 @@ HookInstance::HookInstance()
if (dup2(builderOut.readSide.get(), 5) == -1)
throw SysError("dupping builder's stdout/stderr");
execv(buildHook.c_str(), stringsToCharPtrs(args).data());
execv(buildHook.native().c_str(), stringsToCharPtrs(args).data());
throw SysError("executing '%s'", buildHook);
});