aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/libexpr/primops.cc30
-rw-r--r--src/libstore/build.cc66
2 files changed, 36 insertions, 60 deletions
diff --git a/src/libexpr/primops.cc b/src/libexpr/primops.cc
index 717f649c4..34e7e8052 100644
--- a/src/libexpr/primops.cc
+++ b/src/libexpr/primops.cc
@@ -399,16 +399,29 @@ static Expr prim_derivationStrict(EvalState & state, const ATermVector & args)
/* Everything in the context of the strings in the derivation
attributes should be added as dependencies of the resulting
derivation. */
- for (PathSet::iterator i = context.begin(); i != context.end(); ++i) {
+ foreach (PathSet::iterator, i, context) {
Path path = *i;
- bool buildDrv = true;
+
+ /* Paths marked with `=' denote that the path of a derivation
+ is explicitly passed to the builder. Since that allows the
+ builder to gain access to every path in the dependency
+ graph of the derivation (including all outputs), all paths
+ in the graph must be added to this derivation's list of
+ inputs to ensure that they are available when the builder
+ runs. */
if (path.at(0) == '=') {
- buildDrv = false;
path = string(path, 1);
+ PathSet refs; computeFSClosure(path, refs);
+ foreach (PathSet::iterator, j, refs) {
+ drv.inputSrcs.insert(*j);
+ if (isDerivation(*j))
+ drv.inputDrvs[*j] = singleton<StringSet>("out");
+ }
}
+
debug(format("derivation uses `%1%'") % path);
assert(isStorePath(path));
- if (buildDrv && isDerivation(path))
+ if (isDerivation(path))
drv.inputDrvs[path] = singleton<StringSet>("out");
else
drv.inputSrcs.insert(path);
@@ -484,7 +497,7 @@ static Expr prim_derivationStrict(EvalState & state, const ATermVector & args)
outAttrs.set(toATerm("outPath"),
makeAttrRHS(makeStr(outPath, singleton<PathSet>(drvPath)), makeNoPos()));
outAttrs.set(toATerm("drvPath"),
- makeAttrRHS(makeStr(drvPath, singleton<PathSet>(drvPath)), makeNoPos()));
+ makeAttrRHS(makeStr(drvPath, singleton<PathSet>("=" + drvPath)), makeNoPos()));
return makeAttrs(outAttrs);
}
@@ -541,13 +554,6 @@ static Expr prim_storePath(EvalState & state, const ATermVector & args)
Path path2 = toStorePath(path);
if (!store->isValidPath(path2))
throw EvalError(format("store path `%1%' is not valid") % path2);
- /* If this is a derivation, mark it so it doesn't get built;
- i.e. we want the dependency as a "source" dependency. This is
- to make nix-push work properly (we want it to create a NAR
- archive of the derivation, not build the derivation as a
- side-effect). The `=' is a special marker that gets stripped
- off by prim_derivationStrict. */
- if (isDerivation(path2)) path2 = "=" + path2;
context.insert(path2);
return makeStr(path, context);
}
diff --git a/src/libstore/build.cc b/src/libstore/build.cc
index 6a62345f7..b275c9008 100644
--- a/src/libstore/build.cc
+++ b/src/libstore/build.cc
@@ -935,8 +935,6 @@ void DerivationGoal::inputsRealised()
/* Second, the input sources. */
foreach (PathSet::iterator, i, drv.inputSrcs)
computeFSClosure(*i, inputPaths);
- /* !!! if `*i' is a derivation, then add the closure of every
- output in the dependency graph to `inputPaths'. */
debug(format("added input paths %1%") % showPaths(inputPaths));
@@ -1534,55 +1532,27 @@ void DerivationGoal::startBuilder()
throw BuildError(format("`exportReferencesGraph' contains an invalid path `%1%'")
% storePath);
- /* Write closure info to `fileName'. */
- PathSet refs;
- computeFSClosure(storePath, refs);
- /* !!! in secure Nix, the writing should be done on the
- build uid for security (maybe). */
- writeStringToFile(tmpDir + "/" + fileName,
- makeValidityRegistration(refs, false, false));
- }
-
- // The same for derivations
- // !!! urgh, cut&paste duplication
- s = drv.env["exportBuildReferencesGraph"];
- ss = tokenizeString(s);
- if (ss.size() % 2 != 0)
- throw BuildError(format("odd number of tokens in `exportBuildReferencesGraph': `%1%'") % s);
- for (Strings::iterator i = ss.begin(); i != ss.end(); ) {
- string fileName = *i++;
- checkStoreName(fileName); /* !!! abuse of this function */
-
- /* Check that the store path is valid. */
- Path storePath = *i++;
- if (!isInStore(storePath))
- throw BuildError(format("`exportBuildReferencesGraph' contains a non-store path `%1%'")
- % storePath);
- storePath = toStorePath(storePath);
- if (!worker.store.isValidPath(storePath))
- throw BuildError(format("`exportBuildReferencesGraph' contains an invalid path `%1%'")
- % storePath);
+ /* If there are derivations in the graph, then include their
+ outputs as well. This is useful if you want to do things
+ like passing all build-time dependencies of some path to a
+ derivation that builds a NixOS DVD image. */
+ PathSet paths, paths2;
+ computeFSClosure(storePath, paths);
+ paths2 = paths;
+
+ foreach (PathSet::iterator, j, paths2) {
+ if (isDerivation(*j)) {
+ Derivation drv = derivationFromPath(*j);
+ foreach (DerivationOutputs::iterator, k, drv.outputs)
+ computeFSClosure(k->second.path, paths);
+ }
+ }
/* Write closure info to `fileName'. */
- PathSet refs1,refs;
- computeFSClosure(storePath, refs1);
- for (PathSet::iterator j = refs1.begin(); j != refs1.end() ; j++) {
- refs.insert (*j);
- if (isDerivation (*j)) {
- Derivation deriv = derivationFromPath (*j);
- for (DerivationOutputs::iterator k=deriv.outputs.begin();
- k != deriv.outputs.end(); k++) {
- refs.insert(k->second.path);
-
- }
- }
- }
- /* !!! in secure Nix, the writing should be done on the
- build uid for security (maybe). */
writeStringToFile(tmpDir + "/" + fileName,
- makeValidityRegistration(refs, false, false));
+ makeValidityRegistration(paths, false, false));
}
-
+
/* If `build-users-group' is not empty, then we have to build as
one of the members of that group. */
@@ -2167,7 +2137,7 @@ SubstitutionGoal::SubstitutionGoal(const Path & storePath, Worker & worker)
SubstitutionGoal::~SubstitutionGoal()
{
/* !!! Once we let substitution goals run under a build user, we
- need to do use the setuid helper just as in ~DerivationGoal().
+ need to use the setuid helper just as in ~DerivationGoal().
Idem for cancel. */
if (pid != -1) worker.childTerminated(pid);
}