diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/libexpr/eval.cc | 6 | ||||
-rw-r--r-- | src/libexpr/parser.y | 2 | ||||
-rw-r--r-- | src/libexpr/primops.cc | 22 | ||||
-rw-r--r-- | src/libexpr/symbol-table.hh | 7 | ||||
-rw-r--r-- | src/libstore/build.cc | 34 | ||||
-rw-r--r-- | src/libstore/gc.cc | 7 | ||||
-rw-r--r-- | src/libstore/machines.cc | 9 | ||||
-rw-r--r-- | src/libstore/store-api.hh | 1 | ||||
-rw-r--r-- | src/libutil/util.cc | 3 | ||||
-rw-r--r-- | src/libutil/util.hh | 4 |
10 files changed, 80 insertions, 15 deletions
diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index 211f7a55f737..d8e10d9f20e1 100644 --- a/src/libexpr/eval.cc +++ b/src/libexpr/eval.cc @@ -1811,6 +1811,7 @@ void EvalState::printStats() gc.attr("totalBytes", totalBytes); } #endif + if (countCalls) { { auto obj = topObj.object("primops"); @@ -1846,6 +1847,11 @@ void EvalState::printStats() } } } + + if (getEnv("NIX_SHOW_SYMBOLS", "0") != "0") { + auto list = topObj.list("symbols"); + symbols.dump([&](const std::string & s) { list.elem(s); }); + } } } diff --git a/src/libexpr/parser.y b/src/libexpr/parser.y index cbd576d7d126..7870393076b8 100644 --- a/src/libexpr/parser.y +++ b/src/libexpr/parser.y @@ -1,7 +1,7 @@ %glr-parser %pure-parser %locations -%error-verbose +%define parse.error verbose %defines /* %no-lines */ %parse-param { void * scanner } diff --git a/src/libexpr/primops.cc b/src/libexpr/primops.cc index 6b0c55e72cd9..06f577f36fce 100644 --- a/src/libexpr/primops.cc +++ b/src/libexpr/primops.cc @@ -315,6 +315,12 @@ static void prim_isBool(EvalState & state, const Pos & pos, Value * * args, Valu mkBool(v, args[0]->type == tBool); } +/* Determine whether the argument is a path. */ +static void prim_isPath(EvalState & state, const Pos & pos, Value * * args, Value & v) +{ + state.forceValue(*args[0]); + mkBool(v, args[0]->type == tPath); +} struct CompareValues { @@ -917,6 +923,20 @@ static void prim_findFile(EvalState & state, const Pos & pos, Value * * args, Va mkPath(v, state.checkSourcePath(state.findFile(searchPath, path, pos)).c_str()); } +/* Return the cryptographic hash of a file in base-16. */ +static void prim_hashFile(EvalState & state, const Pos & pos, Value * * args, Value & v) +{ + string type = state.forceStringNoCtx(*args[0], pos); + HashType ht = parseHashType(type); + if (ht == htUnknown) + throw Error(format("unknown hash type '%1%', at %2%") % type % pos); + + PathSet context; // discarded + Path p = state.coerceToPath(pos, *args[1], context); + + mkString(v, hashFile(ht, state.checkSourcePath(p)).to_string(Base16, false), context); +} + /* Read a directory (without . or ..) */ static void prim_readDir(EvalState & state, const Pos & pos, Value * * args, Value & v) { @@ -2169,6 +2189,7 @@ void EvalState::createBaseEnv() addPrimOp("__isInt", 1, prim_isInt); addPrimOp("__isFloat", 1, prim_isFloat); addPrimOp("__isBool", 1, prim_isBool); + addPrimOp("__isPath", 1, prim_isPath); addPrimOp("__genericClosure", 1, prim_genericClosure); addPrimOp("abort", 1, prim_abort); addPrimOp("__addErrorContext", 2, prim_addErrorContext); @@ -2195,6 +2216,7 @@ void EvalState::createBaseEnv() addPrimOp("__readFile", 1, prim_readFile); addPrimOp("__readDir", 1, prim_readDir); addPrimOp("__findFile", 2, prim_findFile); + addPrimOp("__hashFile", 2, prim_hashFile); // Creating files addPrimOp("__toXML", 1, prim_toXML); diff --git a/src/libexpr/symbol-table.hh b/src/libexpr/symbol-table.hh index 44929f7eea06..91faea122ce1 100644 --- a/src/libexpr/symbol-table.hh +++ b/src/libexpr/symbol-table.hh @@ -75,6 +75,13 @@ public: } size_t totalSize() const; + + template<typename T> + void dump(T callback) + { + for (auto & s : symbols) + callback(s); + } }; } diff --git a/src/libstore/build.cc b/src/libstore/build.cc index 6b88b1307303..91eb97dfb873 100644 --- a/src/libstore/build.cc +++ b/src/libstore/build.cc @@ -12,6 +12,7 @@ #include "json.hh" #include "nar-info.hh" #include "parsed-derivations.hh" +#include "machines.hh" #include <algorithm> #include <iostream> @@ -802,6 +803,9 @@ private: /* Whether we're currently doing a chroot build. */ bool useChroot = false; + /* Whether we need to perform hash rewriting if there are valid output paths. */ + bool needsHashRewrite; + Path chrootRootDir; /* RAII object to delete the chroot directory. */ @@ -993,6 +997,13 @@ DerivationGoal::DerivationGoal(const Path & drvPath, const StringSet & wantedOut , wantedOutputs(wantedOutputs) , buildMode(buildMode) { +#if __linux__ + needsHashRewrite = !useChroot; +#else + /* Darwin requires hash rewriting even when sandboxing is enabled. */ + needsHashRewrite = true; +#endif + state = &DerivationGoal::getDerivation; name = (format("building of '%1%'") % drvPath).str(); trace("created"); @@ -2072,7 +2083,7 @@ void DerivationGoal::startBuilder() #endif } - else { + if (needsHashRewrite) { if (pathExists(homeDir)) throw Error(format("directory '%1%' exists; please remove it") % homeDir); @@ -2499,17 +2510,17 @@ void setupSeccomp() seccomp_release(ctx); }); - if (settings.thisSystem == "x86_64-linux" && + if (nativeSystem == "x86_64-linux" && seccomp_arch_add(ctx, SCMP_ARCH_X86) != 0) throw SysError("unable to add 32-bit seccomp architecture"); - if (settings.thisSystem == "x86_64-linux" && + if (nativeSystem == "x86_64-linux" && seccomp_arch_add(ctx, SCMP_ARCH_X32) != 0) throw SysError("unable to add X32 seccomp architecture"); - if (settings.thisSystem == "aarch64-linux" && + if (nativeSystem == "aarch64-linux" && seccomp_arch_add(ctx, SCMP_ARCH_ARM) != 0) - printError("unsable to add ARM seccomp architecture; this may result in spurious build failures if running 32-bit ARM processes."); + printError("unable to add ARM seccomp architecture; this may result in spurious build failures if running 32-bit ARM processes"); /* Prevent builders from creating setuid/setgid binaries. */ for (int perm : { S_ISUID, S_ISGID }) { @@ -2872,6 +2883,10 @@ void DerivationGoal::runChild() for (auto & i : missingPaths) { sandboxProfile += (format("\t(subpath \"%1%\")\n") % i.c_str()).str(); } + /* Also add redirected outputs to the chroot */ + for (auto & i : redirectedOutputs) { + sandboxProfile += (format("\t(subpath \"%1%\")\n") % i.second.c_str()).str(); + } sandboxProfile += ")\n"; /* Our inputs (transitive dependencies and any impurities computed above) @@ -3050,7 +3065,9 @@ void DerivationGoal::registerOutputs() throw SysError(format("moving build output '%1%' from the sandbox to the Nix store") % path); } if (buildMode != bmCheck) actualPath = worker.store.toRealPath(path); - } else { + } + + if (needsHashRewrite) { Path redirected = redirectedOutputs[path]; if (buildMode == bmRepair && redirectedBadOutputs.find(path) != redirectedBadOutputs.end() @@ -4411,6 +4428,11 @@ static void primeCache(Store & store, const PathSet & paths) PathSet willBuild, willSubstitute, unknown; unsigned long long downloadSize, narSize; store.queryMissing(paths, willBuild, willSubstitute, unknown, downloadSize, narSize); + + if (!willBuild.empty() && 0 == settings.maxBuildJobs && getMachines().empty()) + throw Error( + "%d derivations need to be built, but neither local builds ('--max-jobs') " + "nor remote builds ('--builders') are enabled", willBuild.size()); } diff --git a/src/libstore/gc.cc b/src/libstore/gc.cc index d8a5da0d49e2..26e2b0dca7ca 100644 --- a/src/libstore/gc.cc +++ b/src/libstore/gc.cc @@ -326,10 +326,9 @@ void LocalStore::findRootsNoTemp(Roots & roots, bool censor) findRoots(stateDir + "/" + gcRootsDir, DT_UNKNOWN, roots); findRoots(stateDir + "/profiles", DT_UNKNOWN, roots); - /* Add additional roots returned by the program specified by the - NIX_ROOT_FINDER environment variable. This is typically used - to add running programs to the set of roots (to prevent them - from being garbage collected). */ + /* Add additional roots returned by different platforms-specific + heuristics. This is typically used to add running programs to + the set of roots (to prevent them from being garbage collected). */ findRuntimeRoots(roots, censor); } diff --git a/src/libstore/machines.cc b/src/libstore/machines.cc index edd03d147832..f848582dafd4 100644 --- a/src/libstore/machines.cc +++ b/src/libstore/machines.cc @@ -89,10 +89,11 @@ void parseMachines(const std::string & s, Machines & machines) Machines getMachines() { - Machines machines; - - parseMachines(settings.builders, machines); - + static auto machines = [&]() { + Machines machines; + parseMachines(settings.builders, machines); + return machines; + }(); return machines; } diff --git a/src/libstore/store-api.hh b/src/libstore/store-api.hh index 40887b6aa3a0..7a1b31d0ff59 100644 --- a/src/libstore/store-api.hh +++ b/src/libstore/store-api.hh @@ -11,6 +11,7 @@ #include <atomic> #include <limits> #include <map> +#include <unordered_map> #include <unordered_set> #include <memory> #include <string> diff --git a/src/libutil/util.cc b/src/libutil/util.cc index e3dcd246c681..a7170566533e 100644 --- a/src/libutil/util.cc +++ b/src/libutil/util.cc @@ -38,6 +38,9 @@ extern char * * environ; namespace nix { +const std::string nativeSystem = SYSTEM; + + BaseError & BaseError::addPrefix(const FormatOrString & fs) { prefix_ = fs.s + prefix_; diff --git a/src/libutil/util.hh b/src/libutil/util.hh index 9f239bff371a..54936a5cb10b 100644 --- a/src/libutil/util.hh +++ b/src/libutil/util.hh @@ -30,6 +30,10 @@ struct Sink; struct Source; +/* The system for which Nix is compiled. */ +extern const std::string nativeSystem; + + /* Return an environment variable. */ string getEnv(const string & key, const string & def = ""); |