forked from lix-project/lix
Fix build hook error for libstore library users
A library shouldn't require changes to the caller's argument handling, especially if it doesn't have to, and indeed we don't have to. This changes the lookup order to prioritize the hardcoded path to nix if it exists. The static executable still finds itself through /proc and the like.
This commit is contained in:
parent
9c6ede85fc
commit
d2696cdd1e
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -89,6 +89,7 @@ perl/Makefile.config
|
||||||
/tests/ca/config.nix
|
/tests/ca/config.nix
|
||||||
/tests/dyn-drv/config.nix
|
/tests/dyn-drv/config.nix
|
||||||
/tests/repl-result-out
|
/tests/repl-result-out
|
||||||
|
/tests/test-libstoreconsumer/test-libstoreconsumer
|
||||||
|
|
||||||
# /tests/lang/
|
# /tests/lang/
|
||||||
/tests/lang/*.out
|
/tests/lang/*.out
|
||||||
|
|
1
Makefile
1
Makefile
|
@ -27,6 +27,7 @@ makefiles += \
|
||||||
src/libstore/tests/local.mk \
|
src/libstore/tests/local.mk \
|
||||||
src/libexpr/tests/local.mk \
|
src/libexpr/tests/local.mk \
|
||||||
tests/local.mk \
|
tests/local.mk \
|
||||||
|
tests/test-libstoreconsumer/local.mk \
|
||||||
tests/plugins/local.mk
|
tests/plugins/local.mk
|
||||||
else
|
else
|
||||||
makefiles += \
|
makefiles += \
|
||||||
|
|
|
@ -77,7 +77,30 @@ Settings::Settings()
|
||||||
allowedImpureHostPrefixes = tokenizeString<StringSet>("/System/Library /usr/lib /dev /bin/sh");
|
allowedImpureHostPrefixes = tokenizeString<StringSet>("/System/Library /usr/lib /dev /bin/sh");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
buildHook = getSelfExe().value_or("nix") + " __build-remote";
|
/* 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()
|
void loadConfFile()
|
||||||
|
|
|
@ -134,6 +134,7 @@ nix_tests = \
|
||||||
flakes/show.sh \
|
flakes/show.sh \
|
||||||
impure-derivations.sh \
|
impure-derivations.sh \
|
||||||
path-from-hash-part.sh \
|
path-from-hash-part.sh \
|
||||||
|
test-libstoreconsumer.sh \
|
||||||
toString-path.sh
|
toString-path.sh
|
||||||
|
|
||||||
ifeq ($(HAVE_LIBCPUID), 1)
|
ifeq ($(HAVE_LIBCPUID), 1)
|
||||||
|
@ -152,6 +153,7 @@ test-deps += \
|
||||||
tests/common/vars-and-functions.sh \
|
tests/common/vars-and-functions.sh \
|
||||||
tests/config.nix \
|
tests/config.nix \
|
||||||
tests/ca/config.nix \
|
tests/ca/config.nix \
|
||||||
|
tests/test-libstoreconsumer/test-libstoreconsumer \
|
||||||
tests/dyn-drv/config.nix
|
tests/dyn-drv/config.nix
|
||||||
|
|
||||||
ifeq ($(BUILD_SHARED_LIBS), 1)
|
ifeq ($(BUILD_SHARED_LIBS), 1)
|
||||||
|
|
6
tests/test-libstoreconsumer.sh
Normal file
6
tests/test-libstoreconsumer.sh
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
source common.sh
|
||||||
|
|
||||||
|
drv="$(nix-instantiate simple.nix)"
|
||||||
|
cat "$drv"
|
||||||
|
out="$(./test-libstoreconsumer/test-libstoreconsumer "$drv")"
|
||||||
|
cat "$out/hello" | grep -F "Hello World!"
|
6
tests/test-libstoreconsumer/README.md
Normal file
6
tests/test-libstoreconsumer/README.md
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
|
||||||
|
A very simple C++ consumer of the libstore library.
|
||||||
|
|
||||||
|
- Keep it simple. Library consumers expect something simple.
|
||||||
|
- No build hook, or any other reinvocations.
|
||||||
|
- No more global state than necessary.
|
12
tests/test-libstoreconsumer/local.mk
Normal file
12
tests/test-libstoreconsumer/local.mk
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
programs += test-libstoreconsumer
|
||||||
|
|
||||||
|
test-libstoreconsumer_DIR := $(d)
|
||||||
|
|
||||||
|
test-libstoreconsumer_SOURCES := \
|
||||||
|
$(wildcard $(d)/*.cc) \
|
||||||
|
|
||||||
|
test-libstoreconsumer_CXXFLAGS += -I src/libutil -I src/libstore
|
||||||
|
|
||||||
|
test-libstoreconsumer_LIBS = libstore libutil
|
||||||
|
|
||||||
|
test-libstoreconsumer_LDFLAGS = -pthread $(SODIUM_LIBS) $(EDITLINE_LIBS) $(BOOST_LDFLAGS) $(LOWDOWN_LIBS)
|
45
tests/test-libstoreconsumer/main.cc
Normal file
45
tests/test-libstoreconsumer/main.cc
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
#include "globals.hh"
|
||||||
|
#include "store-api.hh"
|
||||||
|
#include "build-result.hh"
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
using namespace nix;
|
||||||
|
|
||||||
|
int main (int argc, char **argv)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
if (argc != 2) {
|
||||||
|
std::cerr << "Usage: " << argv[0] << " store/path/to/something.drv\n";
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string drvPath = argv[1];
|
||||||
|
|
||||||
|
initLibStore();
|
||||||
|
|
||||||
|
auto store = nix::openStore();
|
||||||
|
|
||||||
|
// build the derivation
|
||||||
|
|
||||||
|
std::vector<DerivedPath> paths {
|
||||||
|
DerivedPath::Built {
|
||||||
|
.drvPath = store->parseStorePath(drvPath),
|
||||||
|
.outputs = OutputsSpec::Names{"out"}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const auto results = store->buildPathsWithResults(paths, bmNormal, store);
|
||||||
|
|
||||||
|
for (const auto & result : results) {
|
||||||
|
for (const auto & [outputName, realisation] : result.builtOutputs) {
|
||||||
|
std::cout << store->printStorePath(realisation.outPath) << "\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
} catch (const std::exception & e) {
|
||||||
|
std::cerr << "Error: " << e.what() << "\n";
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue