aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore1
-rw-r--r--Makefile1
-rw-r--r--src/libstore/globals.cc25
-rw-r--r--tests/local.mk2
-rw-r--r--tests/test-libstoreconsumer.sh6
-rw-r--r--tests/test-libstoreconsumer/README.md6
-rw-r--r--tests/test-libstoreconsumer/local.mk12
-rw-r--r--tests/test-libstoreconsumer/main.cc45
8 files changed, 97 insertions, 1 deletions
diff --git a/.gitignore b/.gitignore
index 7ae1071d0..29d9106ae 100644
--- a/.gitignore
+++ b/.gitignore
@@ -89,6 +89,7 @@ perl/Makefile.config
/tests/ca/config.nix
/tests/dyn-drv/config.nix
/tests/repl-result-out
+/tests/test-libstoreconsumer/test-libstoreconsumer
# /tests/lang/
/tests/lang/*.out
diff --git a/Makefile b/Makefile
index d6b49473a..c6220482a 100644
--- a/Makefile
+++ b/Makefile
@@ -27,6 +27,7 @@ makefiles += \
src/libstore/tests/local.mk \
src/libexpr/tests/local.mk \
tests/local.mk \
+ tests/test-libstoreconsumer/local.mk \
tests/plugins/local.mk
else
makefiles += \
diff --git a/src/libstore/globals.cc b/src/libstore/globals.cc
index 32e9a6ea9..d53377239 100644
--- a/src/libstore/globals.cc
+++ b/src/libstore/globals.cc
@@ -77,7 +77,30 @@ Settings::Settings()
allowedImpureHostPrefixes = tokenizeString<StringSet>("/System/Library /usr/lib /dev /bin/sh");
#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()
diff --git a/tests/local.mk b/tests/local.mk
index 9e340e2e2..a37365efe 100644
--- a/tests/local.mk
+++ b/tests/local.mk
@@ -134,6 +134,7 @@ nix_tests = \
flakes/show.sh \
impure-derivations.sh \
path-from-hash-part.sh \
+ test-libstoreconsumer.sh \
toString-path.sh
ifeq ($(HAVE_LIBCPUID), 1)
@@ -152,6 +153,7 @@ test-deps += \
tests/common/vars-and-functions.sh \
tests/config.nix \
tests/ca/config.nix \
+ tests/test-libstoreconsumer/test-libstoreconsumer \
tests/dyn-drv/config.nix
ifeq ($(BUILD_SHARED_LIBS), 1)
diff --git a/tests/test-libstoreconsumer.sh b/tests/test-libstoreconsumer.sh
new file mode 100644
index 000000000..8a77cf5a1
--- /dev/null
+++ b/tests/test-libstoreconsumer.sh
@@ -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!"
diff --git a/tests/test-libstoreconsumer/README.md b/tests/test-libstoreconsumer/README.md
new file mode 100644
index 000000000..ded69850f
--- /dev/null
+++ b/tests/test-libstoreconsumer/README.md
@@ -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.
diff --git a/tests/test-libstoreconsumer/local.mk b/tests/test-libstoreconsumer/local.mk
new file mode 100644
index 000000000..cd2d0c7f8
--- /dev/null
+++ b/tests/test-libstoreconsumer/local.mk
@@ -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)
diff --git a/tests/test-libstoreconsumer/main.cc b/tests/test-libstoreconsumer/main.cc
new file mode 100644
index 000000000..31b6d8ef1
--- /dev/null
+++ b/tests/test-libstoreconsumer/main.cc
@@ -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;
+ }
+}