Skip to content

Commit

Permalink
Merge pull request #8517 from hercules-ci/fix-build-hook-error-for-li…
Browse files Browse the repository at this point in the history
…b-users

Fix build hook error for libstore library users
  • Loading branch information
edolstra authored Jun 16, 2023
2 parents 0932014 + d2696cd commit 7138361
Show file tree
Hide file tree
Showing 8 changed files with 97 additions and 1 deletion.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -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 += \
Expand Down
25 changes: 24 additions & 1 deletion src/libstore/globals.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down
2 changes: 2 additions & 0 deletions tests/local.mk
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,7 @@ nix_tests = \
flakes/show.sh \
impure-derivations.sh \
path-from-hash-part.sh \
test-libstoreconsumer.sh \
toString-path.sh

ifeq ($(HAVE_LIBCPUID), 1)
Expand All @@ -153,6 +154,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)
Expand Down
6 changes: 6 additions & 0 deletions tests/test-libstoreconsumer.sh
Original file line number Diff line number Diff line change
@@ -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 changes: 6 additions & 0 deletions tests/test-libstoreconsumer/README.md
Original file line number Diff line number Diff line change
@@ -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 changes: 12 additions & 0 deletions tests/test-libstoreconsumer/local.mk
Original file line number Diff line number Diff line change
@@ -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 changes: 45 additions & 0 deletions tests/test-libstoreconsumer/main.cc
Original file line number Diff line number Diff line change
@@ -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;
}
}

0 comments on commit 7138361

Please sign in to comment.