diff --git a/src/libexpr/eval.hh b/src/libexpr/eval.hh index 11185159c1..602f63fded 100644 --- a/src/libexpr/eval.hh +++ b/src/libexpr/eval.hh @@ -11,6 +11,10 @@ typedef map DrvRoots; typedef map DrvHashes; +/* Cache for calls to addToStore(); maps source paths to the store + paths. */ +typedef map SrcToStore; + struct EvalState; /* Note: using a ATermVector is safe here, since when we call a primop @@ -24,6 +28,7 @@ struct EvalState ATermMap primOps; DrvRoots drvRoots; DrvHashes drvHashes; /* normalised derivation hashes */ + SrcToStore srcToStore; Expr blackHole; unsigned int nrEvaluated; diff --git a/src/libexpr/primops.cc b/src/libexpr/primops.cc index 31fff0b493..77721a5a8d 100644 --- a/src/libexpr/primops.cc +++ b/src/libexpr/primops.cc @@ -165,9 +165,15 @@ static void processBinding(EvalState & state, Expr e, Derivation & drv, if (isDerivation(srcPath)) throw Error(format("file names are not allowed to end in `%1%'") % drvExtension); - Path dstPath(addToStore(srcPath)); - printMsg(lvlChatty, format("copied source `%1%' -> `%2%'") - % srcPath % dstPath); + Path dstPath; + if (state.srcToStore[srcPath] != "") + dstPath = state.srcToStore[srcPath]; + else { + dstPath = addToStore(srcPath); + state.srcToStore[srcPath] = dstPath; + printMsg(lvlChatty, format("copied source `%1%' -> `%2%'") + % srcPath % dstPath); + } drv.inputSrcs.insert(dstPath); ss.push_back(dstPath); }