tests: Preserve empty arguments in test command lines

This will now preserve empty values in the TEST_LAUNCHER and
CROSSCOMPILING_EMULATOR target properties for tests added by:

- The add_test() command.
- The ExternalData_Add_Test() command from the ExternalData module.
- The gtest_add_tests() or gtest_discover_tests() commands from the
  GoogleTest module.

For the gtest_add_tests() and gtest_discover_tests() commands,
empty elements in the values passed after the EXTRA_ARGS keyword
are also now preserved.

Policy CMP0178 is added to provide backward compatibility with the
old behavior where empty values were silently discarded from the
above cases.

Fixes: #26337
This commit is contained in:
Craig Scott
2024-09-30 21:13:13 +10:00
parent 9f1703530b
commit fc7aa3cd69
27 changed files with 512 additions and 80 deletions
+24 -3
View File
@@ -174,15 +174,36 @@ void cmTestGenerator::GenerateScriptForConfig(std::ostream& os,
if (!cmNonempty(launcher)) {
return;
}
cmList launcherWithArgs{ ge.Parse(*launcher)->Evaluate(this->LG,
config) };
const auto propVal = ge.Parse(*launcher)->Evaluate(this->LG, config);
cmList launcherWithArgs(propVal, cmList::ExpandElements::Yes,
this->Test->GetCMP0178() == cmPolicies::NEW
? cmList::EmptyElements::Yes
: cmList::EmptyElements::No);
if (!launcherWithArgs.empty() && !launcherWithArgs[0].empty()) {
if (this->Test->GetCMP0178() == cmPolicies::WARN) {
cmList argsWithEmptyValuesPreserved(
propVal, cmList::ExpandElements::Yes, cmList::EmptyElements::Yes);
if (launcherWithArgs != argsWithEmptyValuesPreserved) {
this->Test->GetMakefile()->IssueMessage(
MessageType::AUTHOR_WARNING,
cmStrCat("The ", propertyName, " property of target '",
target->GetName(),
"' contains empty list items. Those empty items are "
"being silently discarded to preserve backward "
"compatibility.\n",
cmPolicies::GetPolicyWarning(cmPolicies::CMP0178)));
}
}
std::string launcherExe(launcherWithArgs[0]);
cmSystemTools::ConvertToUnixSlashes(launcherExe);
os << cmOutputConverter::EscapeForCMake(launcherExe) << " ";
for (std::string const& arg :
cmMakeRange(launcherWithArgs).advance(1)) {
os << cmOutputConverter::EscapeForCMake(arg) << " ";
if (arg.empty()) {
os << "\"\" ";
} else {
os << cmOutputConverter::EscapeForCMake(arg) << " ";
}
}
}
};