diff options
author | Klaus Aehlig <klaus.aehlig@huawei.com> | 2025-03-26 12:08:54 +0100 |
---|---|---|
committer | Klaus Aehlig <klaus.aehlig@huawei.com> | 2025-04-07 16:09:43 +0200 |
commit | 4cd12f7ba531c255aa3945bd5bc1a6a1ab0bc7bc (patch) | |
tree | 995f8faf1cf10056303386dd14b14143cd4a015e /src/buildtool/build_engine/target_map/target_map.cpp | |
parent | eb101e14097d02c74a1e34927a08bba4b7d739c5 (diff) | |
download | justbuild-4cd12f7ba531c255aa3945bd5bc1a6a1ab0bc7bc.tar.gz |
Defined rules: add TREE_OVERLAY and DISJOINT_TREE_OVERLAY function
Diffstat (limited to 'src/buildtool/build_engine/target_map/target_map.cpp')
-rw-r--r-- | src/buildtool/build_engine/target_map/target_map.cpp | 114 |
1 files changed, 89 insertions, 25 deletions
diff --git a/src/buildtool/build_engine/target_map/target_map.cpp b/src/buildtool/build_engine/target_map/target_map.cpp index 634db0dc..1e1436d3 100644 --- a/src/buildtool/build_engine/target_map/target_map.cpp +++ b/src/buildtool/build_engine/target_map/target_map.cpp @@ -328,6 +328,38 @@ auto ListDependencies( return deps.str(); } +auto ExprToTree(std::string const& context, + ExpressionPtr const& val) -> Tree::Ptr { + if (not val->IsMap()) { + throw Evaluator::EvaluationError{ + fmt::format("{} has to be a map of artifacts, " + "but found {}", + context, + val->ToString())}; + } + std::unordered_map<std::string, ArtifactDescription> artifacts; + artifacts.reserve(val->Map().size()); + for (auto const& [input_path, artifact] : val->Map()) { + if (not artifact->IsArtifact()) { + throw Evaluator::EvaluationError{ + fmt::format("{} has to be a map of artifacts, " + "but found {} for {}", + artifact->ToString(), + input_path, + context)}; + } + auto norm_path = ToNormalPath(std::filesystem::path{input_path}); + artifacts.emplace(std::move(norm_path), artifact->Artifact()); + } + auto conflict = BuildMaps::Target::Utils::tree_conflict(val); + if (conflict) { + throw Evaluator::EvaluationError{fmt::format( + "Tree conflicts on subtree {} of {}", *conflict, context)}; + } + auto tree = std::make_shared<Tree>(std::move(artifacts)); + return tree; +} + void withDependencies( const gsl::not_null<AnalyseContext*>& context, const std::vector<BuildMaps::Target::ConfiguredTarget>& transition_keys, @@ -491,6 +523,7 @@ void withDependencies( std::vector<ActionDescription::Ptr> actions{}; std::vector<std::string> blobs{}; std::vector<Tree::Ptr> trees{}; + std::vector<TreeOverlay::Ptr> tree_overlays{}; auto main_exp_fcts = FunctionMap::MakePtr( {{"FIELD", [¶ms](auto&& eval, auto const& expr, auto const& env) { @@ -813,36 +846,67 @@ void withDependencies( {"TREE", [&trees](auto&& eval, auto const& expr, auto const& env) { auto val = eval(expr->Get("$1", Expression::kEmptyMapExpr), env); - if (not val->IsMap()) { + auto tree = ExprToTree("TREE argument", val); + auto tree_id = tree->Id(); + trees.emplace_back(std::move(tree)); + return ExpressionPtr{ArtifactDescription::CreateTree(tree_id)}; + }}, + + {"TREE_OVERLAY", + [&tree_overlays, &trees]( + auto&& eval, auto const& expr, auto const& env) { + auto val = eval(expr->Get("$1", Expression::kEmptyList), env); + if (not val->IsList()) { throw Evaluator::EvaluationError{ - fmt::format("TREE argument has to be a map of artifacts, " - "but found {}", + fmt::format("TREE_OVERLAY argument has to be a list of " + "stages, but found {}", val->ToString())}; } - std::unordered_map<std::string, ArtifactDescription> artifacts; - artifacts.reserve(val->Map().size()); - for (auto const& [input_path, artifact] : val->Map()) { - if (not artifact->IsArtifact()) { - throw Evaluator::EvaluationError{fmt::format( - "TREE argument has to be a map of artifacts, " - "but found {} for {}", - artifact->ToString(), - input_path)}; - } - auto norm_path = - ToNormalPath(std::filesystem::path{input_path}); - artifacts.emplace(std::move(norm_path), artifact->Artifact()); + TreeOverlay::to_overlay_t parts{}; + for (std::size_t i = 0; i < val->List().size(); i++) { + auto& entry = val->List()[i]; + auto context = + fmt::format("Entry {} of TREE_OVERLAY argument", i); + auto tree = ExprToTree(context, entry); + auto tree_id = tree->Id(); + trees.emplace_back(std::move(tree)); + parts.emplace_back(ArtifactDescription::CreateTree(tree_id)); } - auto conflict = BuildMaps::Target::Utils::tree_conflict(val); - if (conflict) { - throw Evaluator::EvaluationError{ - fmt::format("TREE conflicts on subtree {}", *conflict)}; + auto overlay = std::make_shared<TreeOverlay>(std::move(parts), + /*disjoint=*/false); + auto overlay_id = overlay->Id(); + tree_overlays.emplace_back(std::move(overlay)); + return ExpressionPtr{ + ArtifactDescription::CreateTreeOverlay(overlay_id)}; + }}, + {"DISJOINT_TREE_OVERLAY", + [&tree_overlays, &trees]( + auto&& eval, auto const& expr, auto const& env) { + auto val = eval(expr->Get("$1", Expression::kEmptyList), env); + if (not val->IsList()) { + throw Evaluator::EvaluationError{fmt::format( + "DISJOINT_TREE_OVERLAY argument has to be a list of " + "stages, but found {}", + val->ToString())}; } - auto tree = std::make_shared<Tree>(std::move(artifacts)); - auto tree_id = tree->Id(); - trees.emplace_back(std::move(tree)); - return ExpressionPtr{ArtifactDescription::CreateTree(tree_id)}; + TreeOverlay::to_overlay_t parts{}; + for (std::size_t i = 0; i < val->List().size(); i++) { + auto& entry = val->List()[i]; + auto context = fmt::format( + "Entry {} of DISJOINT_TREE_OVERLAY argument", i); + auto tree = ExprToTree(context, entry); + auto tree_id = tree->Id(); + trees.emplace_back(std::move(tree)); + parts.emplace_back(ArtifactDescription::CreateTree(tree_id)); + } + auto overlay = std::make_shared<TreeOverlay>(std::move(parts), + /*disjoint=*/true); + auto overlay_id = overlay->Id(); + tree_overlays.emplace_back(std::move(overlay)); + return ExpressionPtr{ + ArtifactDescription::CreateTreeOverlay(overlay_id)}; }}, + {"VALUE_NODE", [](auto&& eval, auto const& expr, auto const& env) { auto val = eval(expr->Get("$1", Expression::kNone), env); @@ -1044,7 +1108,7 @@ void withDependencies( std::move(actions), std::move(blobs), std::move(trees), - std::vector<TreeOverlay::Ptr>{}, + std::move(tree_overlays), std::move(effective_vars), std::move(tainted), std::move(implied_export), |