diff options
author | Eelco Dolstra <e.dolstra@tudelft.nl> | 2009-02-02T17·24+0000 |
---|---|---|
committer | Eelco Dolstra <e.dolstra@tudelft.nl> | 2009-02-02T17·24+0000 |
commit | b682fae9d93037af65282e02b88a9ce34129026e (patch) | |
tree | 2e349a7480d315561bf40864e405b51f9c3ee16d /src | |
parent | 6f8c96d12399b747b5f41b5211a635d2801247c8 (diff) |
* Build hooks: use nix-store --import. This prevents a redundant
scan for runtime dependencies (i.e. the local machine shouldn't do a scan that the remote machine has already done). Also pipe directly into `nix-store --import': don't use a temporary file.
Diffstat (limited to 'src')
-rw-r--r-- | src/libstore/build.cc | 27 | ||||
-rw-r--r-- | src/libstore/local-store.cc | 9 |
2 files changed, 27 insertions, 9 deletions
diff --git a/src/libstore/build.cc b/src/libstore/build.cc index 6b1bc55f95df..d44dcf0ff0e4 100644 --- a/src/libstore/build.cc +++ b/src/libstore/build.cc @@ -1240,6 +1240,12 @@ DerivationGoal::HookReply DerivationGoal::tryBuildHook() initChild(); + string s; + foreach (DerivationOutputs::const_iterator, i, drv.outputs) + s += i->second.path + " "; + if (setenv("NIX_HELD_LOCKS", s.c_str(), 1)) + throw SysError("setting an environment variable"); + execl(buildHook.c_str(), buildHook.c_str(), (worker.canBuildMore() ? (string) "1" : "0").c_str(), thisSystem.c_str(), @@ -1945,13 +1951,21 @@ void DerivationGoal::computeClosure() { map<Path, PathSet> allReferences; map<Path, Hash> contentHashes; - + + /* When using a build hook, the build hook can register the output + as valid (by doing `nix-store --import'). If so we don't have + to do anything here. */ + if (usingBuildHook) { + bool allValid = true; + foreach (DerivationOutputs::iterator, i, drv.outputs) + if (!worker.store.isValidPath(i->second.path)) allValid = false; + if (allValid) return; + } + /* Check whether the output paths were created, and grep each output path to determine what other paths it references. Also make all output paths read-only. */ - for (DerivationOutputs::iterator i = drv.outputs.begin(); - i != drv.outputs.end(); ++i) - { + foreach (DerivationOutputs::iterator, i, drv.outputs) { Path path = i->second.path; if (!pathExists(path)) { throw BuildError( @@ -2043,14 +2057,11 @@ void DerivationGoal::computeClosure() paths referenced by each of them. !!! this should be atomic so that either all paths are registered as valid, or none are. */ - for (DerivationOutputs::iterator i = drv.outputs.begin(); - i != drv.outputs.end(); ++i) - { + foreach (DerivationOutputs::iterator, i, drv.outputs) worker.store.registerValidPath(i->second.path, contentHashes[i->second.path], allReferences[i->second.path], drvPath); - } /* It is now safe to delete the lock files, since all future lockers will see that the output paths are valid; they will not diff --git a/src/libstore/local-store.cc b/src/libstore/local-store.cc index 159f28c91860..1d0c68cb88a5 100644 --- a/src/libstore/local-store.cc +++ b/src/libstore/local-store.cc @@ -924,7 +924,14 @@ Path LocalStore::importPath(bool requireSignature, Source & source) if (!isValidPath(dstPath)) { - PathLocks outputLock(singleton<PathSet, Path>(dstPath)); + PathLocks outputLock; + + /* Lock the output path. But don't lock if we're being called + from a build hook (whose parent process already acquired a + lock on this path). */ + Strings locksHeld = tokenizeString(getEnv("NIX_HELD_LOCKS")); + if (find(locksHeld.begin(), locksHeld.end(), dstPath) == locksHeld.end()) + outputLock.lockPaths(singleton<PathSet, Path>(dstPath)); if (!isValidPath(dstPath)) { |