summaryrefslogtreecommitdiffstats
path: root/Source
diff options
context:
space:
mode:
authorBrad King <brad.king@kitware.com>2024-01-26 20:16:46 (GMT)
committerBrad King <brad.king@kitware.com>2024-01-29 15:30:24 (GMT)
commit13ece67a58a4755807a2e9001e245fdafe9e52e2 (patch)
treef5d29e88f5d54106e84bd68ad84a85a1984f83fc /Source
parentb9ad73fcb2ddbdd53eff6c3ba635b96f5ed0c87b (diff)
downloadCMake-13ece67a58a4755807a2e9001e245fdafe9e52e2.zip
CMake-13ece67a58a4755807a2e9001e245fdafe9e52e2.tar.gz
CMake-13ece67a58a4755807a2e9001e245fdafe9e52e2.tar.bz2
Add genex support to TEST_LAUNCHER and CROSSCOMPILING_EMULATOR
Evaluate generator expressions in these properties, as they apply to `add_test`, `add_custom_command`, and `add_custom_target`. The `CMAKE_CROSSCOMPILING_EMULATOR` variable's `try_run` behavior occurs at configure time and so cannot support generator expressions.
Diffstat (limited to 'Source')
-rw-r--r--Source/cmCustomCommandGenerator.cxx13
-rw-r--r--Source/cmFileAPICodemodel.cxx28
-rw-r--r--Source/cmTestGenerator.cxx6
3 files changed, 32 insertions, 15 deletions
diff --git a/Source/cmCustomCommandGenerator.cxx b/Source/cmCustomCommandGenerator.cxx
index 634b63b..2dea338 100644
--- a/Source/cmCustomCommandGenerator.cxx
+++ b/Source/cmCustomCommandGenerator.cxx
@@ -284,8 +284,12 @@ void cmCustomCommandGenerator::FillEmulatorsWithArguments()
if (!this->LG->GetMakefile()->IsOn("CMAKE_CROSSCOMPILING")) {
return;
}
+ cmGeneratorExpression ge(*this->LG->GetCMakeInstance(),
+ this->CC->GetBacktrace());
for (unsigned int c = 0; c < this->GetNumberOfCommands(); ++c) {
+ // If the command is the plain name of an executable target,
+ // launch it with its emulator.
std::string const& argv0 = this->CommandLines[c][0];
cmGeneratorTarget* target = this->LG->FindGeneratorTargetToUse(argv0);
if (target && target->GetType() == cmStateEnums::EXECUTABLE &&
@@ -297,7 +301,12 @@ void cmCustomCommandGenerator::FillEmulatorsWithArguments()
continue;
}
- cmExpandList(*emulator_property, this->EmulatorsWithArguments[c]);
+ // Plain target names are replaced by GetArgv0Location with the
+ // path to the executable artifact in the command config, so
+ // evaluate the launcher's location in the command config too.
+ std::string const emulator =
+ ge.Parse(*emulator_property)->Evaluate(this->LG, this->CommandConfig);
+ cmExpandList(emulator, this->EmulatorsWithArguments[c]);
}
}
}
@@ -313,6 +322,8 @@ std::vector<std::string> cmCustomCommandGenerator::GetCrossCompilingEmulator(
const char* cmCustomCommandGenerator::GetArgv0Location(unsigned int c) const
{
+ // If the command is the plain name of an executable target, we replace it
+ // with the path to the executable artifact in the command config.
std::string const& argv0 = this->CommandLines[c][0];
cmGeneratorTarget* target = this->LG->FindGeneratorTargetToUse(argv0);
if (target && target->GetType() == cmStateEnums::EXECUTABLE &&
diff --git a/Source/cmFileAPICodemodel.cxx b/Source/cmFileAPICodemodel.cxx
index 30a7e67..e9302da 100644
--- a/Source/cmFileAPICodemodel.cxx
+++ b/Source/cmFileAPICodemodel.cxx
@@ -2092,18 +2092,22 @@ Json::Value Target::DumpLauncher(const char* name, const char* type)
cmValue property = this->GT->GetProperty(name);
Json::Value launcher;
if (property) {
- cmList commandWithArgs{ *property };
- std::string command(commandWithArgs[0]);
- cmSystemTools::ConvertToUnixSlashes(command);
- launcher = Json::objectValue;
- launcher["command"] = RelativeIfUnder(this->TopSource, command);
- launcher["type"] = type;
- Json::Value args;
- for (std::string const& arg : cmMakeRange(commandWithArgs).advance(1)) {
- args.append(arg);
- }
- if (!args.empty()) {
- launcher["arguments"] = std::move(args);
+ cmLocalGenerator* lg = this->GT->GetLocalGenerator();
+ cmGeneratorExpression ge(*lg->GetCMakeInstance());
+ cmList commandWithArgs{ ge.Parse(*property)->Evaluate(lg, this->Config) };
+ if (!commandWithArgs.empty() && !commandWithArgs[0].empty()) {
+ std::string command(commandWithArgs[0]);
+ cmSystemTools::ConvertToUnixSlashes(command);
+ launcher = Json::objectValue;
+ launcher["command"] = RelativeIfUnder(this->TopSource, command);
+ launcher["type"] = type;
+ Json::Value args;
+ for (std::string const& arg : cmMakeRange(commandWithArgs).advance(1)) {
+ args.append(arg);
+ }
+ if (!args.empty()) {
+ launcher["arguments"] = std::move(args);
+ }
}
}
return launcher;
diff --git a/Source/cmTestGenerator.cxx b/Source/cmTestGenerator.cxx
index f7403cf..840d8cf 100644
--- a/Source/cmTestGenerator.cxx
+++ b/Source/cmTestGenerator.cxx
@@ -168,12 +168,14 @@ void cmTestGenerator::GenerateScriptForConfig(std::ostream& os,
// Use the target file on disk.
exe = target->GetFullPath(config);
- auto addLauncher = [&os, target](std::string const& propertyName) {
+ auto addLauncher = [this, &config, &ge, &os,
+ target](std::string const& propertyName) {
cmValue launcher = target->GetProperty(propertyName);
if (!cmNonempty(launcher)) {
return;
}
- cmList launcherWithArgs{ *launcher };
+ cmList launcherWithArgs{ ge.Parse(*launcher)->Evaluate(this->LG,
+ config) };
if (!launcherWithArgs.empty() && !launcherWithArgs[0].empty()) {
std::string launcherExe(launcherWithArgs[0]);
cmSystemTools::ConvertToUnixSlashes(launcherExe);