diff options
-rw-r--r-- | doc/concepts/rules.md | 9 | ||||
-rw-r--r-- | src/buildtool/build_engine/target_map/target_map.cpp | 14 |
2 files changed, 21 insertions, 2 deletions
diff --git a/doc/concepts/rules.md b/doc/concepts/rules.md index ba901dca..a9db5705 100644 --- a/doc/concepts/rules.md +++ b/doc/concepts/rules.md @@ -178,12 +178,19 @@ following arguments. non-empty list of strings. The 0'th element of that list will also be the program to be executed. + - `"cwd"` The directory inside the action root to change to before + executing the command. The directory has to be given as a string + decribing a non-upwards relative path. This field is optional + and defaults to `""`. + - `"env"` The environment in which the command should be executed, given as a map of strings to strings. - `"outs"` and `"out_dirs"` Two list of strings naming the files and directories, respectively, the command is expected to - create. It is an error if the command fails to create the + create. Those paths are interpreted relative to the action root + (not relative to `"cwd"`). + It is an error if the command fails to create the promised output files. These two lists have to be disjoint, but an entry of `"outs"` may well name a location inside one of the `"out_dirs"`. diff --git a/src/buildtool/build_engine/target_map/target_map.cpp b/src/buildtool/build_engine/target_map/target_map.cpp index 75bf6607..14d897b9 100644 --- a/src/buildtool/build_engine/target_map/target_map.cpp +++ b/src/buildtool/build_engine/target_map/target_map.cpp @@ -593,6 +593,18 @@ void withDependencies( } cmd.emplace_back(arg->String()); } + auto cwd_exp = + eval(expr->Get("cwd", Expression::kEmptyString), env); + if (not cwd_exp->IsString()) { + throw Evaluator::EvaluationError{ + fmt::format("cwd has to be a string, but found {}", + cwd_exp->ToString())}; + } + if (not PathIsNonUpwards(cwd_exp->String())) { + throw Evaluator::EvaluationError{fmt::format( + "cwd has to be a non-upwards relative path, but found {}", + cwd_exp->ToString())}; + } auto env_exp = eval(expr->Get("env", empty_map_exp), env); if (not env_exp->IsMap()) { throw Evaluator::EvaluationError{ @@ -697,7 +709,7 @@ void withDependencies( outputs, output_dirs, std::move(cmd), - "", + cwd_exp->String(), env_exp, may_fail, no_cache, |