summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKlaus Aehlig <klaus.aehlig@huawei.com>2024-08-02 11:22:04 +0200
committerKlaus Aehlig <klaus.aehlig@huawei.com>2024-08-02 11:28:37 +0200
commit967fef30981a28a0a91c8f86db3d5b7b2bc2fb66 (patch)
tree869bc58d0cb9c6c3e3a02755999f096704954d20
parentcc3d0aa8227acace9a89ae4c5dfa3148c0227655 (diff)
downloadjustbuild-967fef30981a28a0a91c8f86db3d5b7b2bc2fb66.tar.gz
generic rule: add support for cwd
-rw-r--r--doc/concepts/built-in-rules.md13
-rw-r--r--src/buildtool/build_engine/target_map/built_in_rules.cpp28
2 files changed, 35 insertions, 6 deletions
diff --git a/doc/concepts/built-in-rules.md b/doc/concepts/built-in-rules.md
index 69df06dc..6c80ffb4 100644
--- a/doc/concepts/built-in-rules.md
+++ b/doc/concepts/built-in-rules.md
@@ -91,23 +91,26 @@ precedence to the artifacts over the runfiles; conflicts within
artifacts or runfiles are resolved in a latest-wins fashion using the
order of the targets in the evaluated `"deps"` argument.
-The fields `"cmds"`, `"sh -c"`, `"out_dirs"`, `"outs"`, and `"env"`
+The fields `"cmds"`, `"cwd"`, `"sh -c"`, `"out_dirs"`, `"outs"`, and `"env"`
are evaluated fields where `"cmds"`, `"out_dirs"`, and `"outs"`
have to evaluate to a list of strings, `"sh -c"` has to evalute to
-a list of strings or `null`, and `"env"` has to evaluate to a map
-of strings. During their evaluation, the functions `"outs"` and
+a list of strings or `null`, `"env"` has to evaluate to a map
+of strings, and `"cwd"` has to evaluate to a single string naming a non-upwards
+relative path. During their evaluation, the functions `"outs"` and
`"runfiles"` can be used to access the logical paths of the artifacts
and runfiles, respectively, of a target specified in `"deps"`. Here,
`"env"` specifies the environment in which the action is carried
out. `"out_dirs"` and `"outs"` define the output directories and
-files, respectively, the action has to produce. Since some artifacts
+files, respectively, the action has to produce; these path are read
+relative to the action root. Since some artifacts
are to be produced, at least one of `"out_dirs"` or `"outs"` must
be a non-empty list of strings. It is an error if one or more paths
are present in both the `"out_dirs"` and `"outs"`. Finally, the
strings in `"cmds"` are extended by a newline character and joined,
and command of the action is the result of evaluating the field
`"sh -c"` (or `["sh", "-c"]` if `"sh -c"` evaluates to `null` or
-`[]`) extended by this string.
+`[]`) extended by this string; the command is executed in the
+subdirectory of the execution root specified by `"cwd"`.
The artifacts of this target are the outputs (as declared by
`"out_dirs"` and `"outs"`) of this action. Runfiles and provider map are
diff --git a/src/buildtool/build_engine/target_map/built_in_rules.cpp b/src/buildtool/build_engine/target_map/built_in_rules.cpp
index e1cf9c7f..e3cfc028 100644
--- a/src/buildtool/build_engine/target_map/built_in_rules.cpp
+++ b/src/buildtool/build_engine/target_map/built_in_rules.cpp
@@ -42,6 +42,7 @@ namespace {
auto const kGenericRuleFields =
std::unordered_set<std::string>{"arguments_config",
"cmds",
+ "cwd",
"deps",
"env",
"execution properties",
@@ -1196,6 +1197,31 @@ void GenericRuleWithDeps(
cmd_ss << x->String();
cmd_ss << "\n";
}
+ auto cwd_exp =
+ desc->ReadOptionalExpression("cwd", Expression::kEmptyString);
+ if (not cwd_exp) {
+ return;
+ }
+ auto cwd_value = cwd_exp.Evaluate(
+ param_config, string_fields_fcts, [&logger](auto const& msg) {
+ (*logger)(fmt::format("While evaluating cwd:\n{}", msg), true);
+ });
+ if (not cwd_value) {
+ return;
+ }
+ if (not cwd_value->IsString()) {
+ (*logger)(fmt::format("cwd has to evaluate to a string, but found {}",
+ cwd_value->ToString()),
+ true);
+ return;
+ }
+ if (not PathIsNonUpwards(cwd_value->String())) {
+ (*logger)(fmt::format("cwd has to evalute to a non-upwards relative "
+ "path, but found {}",
+ cwd_value->ToString()),
+ true);
+ return;
+ }
auto const& empty_map_exp = Expression::kEmptyMapExpr;
auto env_exp = desc->ReadOptionalExpression("env", empty_map_exp);
if (not env_exp) {
@@ -1341,7 +1367,7 @@ void GenericRuleWithDeps(
outs,
out_dirs,
argv,
- "",
+ cwd_value->String(),
env_val,
std::nullopt,
false,