diff --git a/src/libstore/build/derivation-resolution-goal.cc b/src/libstore/build/derivation-resolution-goal.cc index e205fc774bb..315edd2faf4 100644 --- a/src/libstore/build/derivation-resolution-goal.cc +++ b/src/libstore/build/derivation-resolution-goal.cc @@ -107,32 +107,7 @@ Goal::Co DerivationResolutionGoal::resolveDerivation() { auto & fullDrv = *drv; - auto drvType = fullDrv.type(); - bool resolveDrv = - std::visit( - overloaded{ - [&](const DerivationType::InputAddressed & ia) { - /* must resolve if deferred. */ - return ia.deferred; - }, - [&](const DerivationType::ContentAddressed & ca) { - return !fullDrv.inputDrvs.map.empty() - && (ca.fixed - /* Can optionally resolve if fixed, which is good - for avoiding unnecessary rebuilds. */ - ? experimentalFeatureSettings.isEnabled(Xp::CaDerivations) - /* Must resolve if floating and there are any inputs - drvs. */ - : true); - }, - [&](const DerivationType::Impure &) { return true; }}, - drvType.raw) - /* no inputs are outputs of dynamic derivations */ - || std::ranges::any_of(fullDrv.inputDrvs.map.begin(), fullDrv.inputDrvs.map.end(), [](auto & pair) { - return !pair.second.childMap.empty(); - }); - - if (resolveDrv && !fullDrv.inputDrvs.map.empty()) { + if (fullDrv.shouldResolve()) { experimentalFeatureSettings.require(Xp::CaDerivations); /* We are be able to resolve this derivation based on the diff --git a/src/libstore/derivations.cc b/src/libstore/derivations.cc index 76539e95131..10c6c724cc6 100644 --- a/src/libstore/derivations.cc +++ b/src/libstore/derivations.cc @@ -1119,6 +1119,39 @@ static void rewriteDerivation(Store & store, BasicDerivation & drv, const String } } +bool Derivation::shouldResolve() const +{ + /* No input drvs means nothing to resolve. */ + if (inputDrvs.map.empty()) + return false; + + auto drvType = type(); + + bool typeNeedsResolve = std::visit( + overloaded{ + [&](const DerivationType::InputAddressed & ia) { + /* Must resolve if deferred. */ + return ia.deferred; + }, + [&](const DerivationType::ContentAddressed & ca) { + return ca.fixed + /* Can optionally resolve if fixed, which is good + for avoiding unnecessary rebuilds. */ + ? experimentalFeatureSettings.isEnabled(Xp::CaDerivations) + /* Must resolve if floating. */ + : true; + }, + [&](const DerivationType::Impure &) { return true; }, + }, + drvType.raw); + + /* Also need to resolve if any inputs are outputs of dynamic derivations. */ + bool hasDynamicInputs = std::ranges::any_of( + inputDrvs.map.begin(), inputDrvs.map.end(), [](auto & pair) { return !pair.second.childMap.empty(); }); + + return typeNeedsResolve || hasDynamicInputs; +} + std::optional Derivation::tryResolve(Store & store, Store * evalStore) const { return tryResolve( diff --git a/src/libstore/include/nix/store/derivations.hh b/src/libstore/include/nix/store/derivations.hh index a8c702fc366..91a6b5b4085 100644 --- a/src/libstore/include/nix/store/derivations.hh +++ b/src/libstore/include/nix/store/derivations.hh @@ -340,6 +340,19 @@ struct Derivation : BasicDerivation bool maskOutputs, DerivedPathMap::ChildNode::Map * actualInputs = nullptr) const; + /** + * Determine whether this derivation should be resolved before building. + * + * Resolution is needed when: + * - Input-addressed derivations are deferred (depend on CA derivations) + * - Content-addressed derivations have input drvs and are either: + * - Floating (non-fixed), which must always be resolved + * - Fixed, which can optionally be resolved when ca-derivations is enabled + * - Impure derivations always need resolution + * - Any input derivations have outputs from dynamic derivations + */ + bool shouldResolve() const; + /** * Return the underlying basic derivation but with these changes: * diff --git a/src/nix/nix-build/nix-build.cc b/src/nix/nix-build/nix-build.cc index 53dc46eaa6f..360f3f43463 100644 --- a/src/nix/nix-build/nix-build.cc +++ b/src/nix/nix-build/nix-build.cc @@ -531,7 +531,7 @@ static void main_nix_build(int argc, char ** argv) shell = store->printStorePath(shellDrvOutputs.at("out").value()) + "/bin/bash"; } - if (experimentalFeatureSettings.isEnabled(Xp::CaDerivations)) { + if (drv.shouldResolve()) { auto resolvedDrv = drv.tryResolve(*store); assert(resolvedDrv && "Successfully resolved the derivation"); drv = *resolvedDrv;