1
0
Fork 0
mirror of https://github.com/NixOS/nix synced 2025-07-05 16:31:47 +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

@ -60,7 +60,7 @@ OsString ExecutablePath::render() const
}
std::optional<fs::path>
ExecutablePath::find(const OsString & exe, std::function<bool(const fs::path &)> isExecutable) const
ExecutablePath::findName(const OsString & exe, std::function<bool(const fs::path &)> isExecutable) const
{
// "If the pathname being sought contains a <slash>, the search
// through the path prefixes shall not be performed."
@ -76,4 +76,20 @@ ExecutablePath::find(const OsString & exe, std::function<bool(const fs::path &)>
return std::nullopt;
}
fs::path ExecutablePath::findPath(const fs::path & exe, std::function<bool(const fs::path &)> isExecutable) const
{
// "If the pathname being sought contains a <slash>, the search
// through the path prefixes shall not be performed."
// https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap08.html#tag_08_03
if (exe.filename() == exe) {
auto resOpt = findName(exe, isExecutable);
if (resOpt)
return *resOpt;
else
throw ExecutableLookupError("Could not find executable '%s'", exe.native());
} else {
return exe;
}
}
} // namespace nix

View file

@ -5,6 +5,8 @@
namespace nix {
MakeError(ExecutableLookupError, Error);
struct ExecutablePath
{
std::vector<std::filesystem::path> directories;
@ -54,10 +56,21 @@ struct ExecutablePath
*
* @return path to a resolved executable
*/
std::optional<std::filesystem::path> find(
std::optional<std::filesystem::path> findName(
const OsString & exe,
std::function<bool(const std::filesystem::path &)> isExecutableFile = isExecutableFileAmbient) const;
/**
* Like the `findName` but also allows a file path as input.
*
* This implements the full POSIX spec: if the path is just a name,
* it searches like the above. Otherwise, it returns the path as is.
* If (in the name case) the search fails, an exception is thrown.
*/
std::filesystem::path findPath(
const std::filesystem::path & exe,
std::function<bool(const std::filesystem::path &)> isExecutable = isExecutableFileAmbient) const;
bool operator==(const ExecutablePath &) const = default;
};