Skip to content
Snippets Groups Projects
Commit e7480d67 authored by Brad King's avatar Brad King
Browse files

Fix custom command target substitution with CROSSCOMPILING_EMULATOR


In commit v3.6.0-rc1~88^2 (CustomCommandGenerator: Add support for
CROSSCOMPILING_EMULATOR, 2016-05-04) logic was introduced to substitute
a target's `CROSSCOMPILING_EMULATOR` for argv0 in a custom command.
However, it broke the case when the argv0 was a target name and now
fails to expand the target name to its location at the same time as
inserting the emulator.  Fix the latter case.

Inspired-by: default avatarBrian Maher <brian@brimworks.com>
Closes: #16288
parent ee0f2d23
No related branches found
No related tags found
No related merge requests found
......@@ -38,32 +38,44 @@ unsigned int cmCustomCommandGenerator::GetNumberOfCommands() const
return static_cast<unsigned int>(this->CC.GetCommandLines().size());
}
bool cmCustomCommandGenerator::UseCrossCompilingEmulator(unsigned int c) const
const char* cmCustomCommandGenerator::GetCrossCompilingEmulator(
unsigned int c) const
{
if (!this->LG->GetMakefile()->IsOn("CMAKE_CROSSCOMPILING")) {
return CM_NULLPTR;
}
std::string const& argv0 = this->CC.GetCommandLines()[c][0];
cmGeneratorTarget* target = this->LG->FindGeneratorTargetToUse(argv0);
if (target && target->GetType() == cmStateEnums::EXECUTABLE) {
return target->GetProperty("CROSSCOMPILING_EMULATOR") != CM_NULLPTR;
if (target && target->GetType() == cmStateEnums::EXECUTABLE &&
!target->IsImported()) {
return target->GetProperty("CROSSCOMPILING_EMULATOR");
}
return false;
return CM_NULLPTR;
}
std::string cmCustomCommandGenerator::GetCommand(unsigned int c) const
const char* cmCustomCommandGenerator::GetArgv0Location(unsigned int c) const
{
std::string const& argv0 = this->CC.GetCommandLines()[c][0];
cmGeneratorTarget* target = this->LG->FindGeneratorTargetToUse(argv0);
if (target && target->GetType() == cmStateEnums::EXECUTABLE &&
(target->IsImported() ||
target->GetProperty("CROSSCOMPILING_EMULATOR") ||
!this->LG->GetMakefile()->IsOn("CMAKE_CROSSCOMPILING"))) {
return target->GetLocation(this->Config);
}
if (target && target->GetType() == cmStateEnums::EXECUTABLE) {
const char* emulator = target->GetProperty("CROSSCOMPILING_EMULATOR");
if (emulator) {
return std::string(emulator);
}
return CM_NULLPTR;
}
std::string cmCustomCommandGenerator::GetCommand(unsigned int c) const
{
if (const char* emulator = this->GetCrossCompilingEmulator(c)) {
return std::string(emulator);
}
if (const char* location = this->GetArgv0Location(c)) {
return std::string(location);
}
std::string const& argv0 = this->CC.GetCommandLines()[c][0];
CM_AUTO_PTR<cmCompiledGeneratorExpression> cge = this->GE->Parse(argv0);
std::string exe = cge->Evaluate(this->LG, this->Config);
......@@ -99,13 +111,20 @@ void cmCustomCommandGenerator::AppendArguments(unsigned int c,
std::string& cmd) const
{
unsigned int offset = 1;
if (this->UseCrossCompilingEmulator(c)) {
if (this->GetCrossCompilingEmulator(c) != CM_NULLPTR) {
offset = 0;
}
cmCustomCommandLine const& commandLine = this->CC.GetCommandLines()[c];
for (unsigned int j = offset; j < commandLine.size(); ++j) {
std::string arg =
this->GE->Parse(commandLine[j])->Evaluate(this->LG, this->Config);
std::string arg;
if (const char* location =
j == 0 ? this->GetArgv0Location(c) : CM_NULLPTR) {
// GetCommand returned the emulator instead of the argv0 location,
// so transform the latter now.
arg = location;
} else {
arg = this->GE->Parse(commandLine[j])->Evaluate(this->LG, this->Config);
}
cmd += " ";
if (this->OldStyle) {
cmd += escapeForShellOldStyle(arg);
......
......@@ -23,6 +23,9 @@ class cmCustomCommandGenerator
mutable bool DependsDone;
mutable std::vector<std::string> Depends;
const char* GetCrossCompilingEmulator(unsigned int c) const;
const char* GetArgv0Location(unsigned int c) const;
public:
cmCustomCommandGenerator(cmCustomCommand const& cc,
const std::string& config, cmLocalGenerator* lg);
......@@ -30,7 +33,6 @@ public:
cmCustomCommand const& GetCC() const { return this->CC; }
unsigned int GetNumberOfCommands() const;
std::string GetCommand(unsigned int c) const;
bool UseCrossCompilingEmulator(unsigned int c) const;
void AppendArguments(unsigned int c, std::string& cmd) const;
const char* GetComment() const;
std::string GetWorkingDirectory() const;
......
......@@ -14,7 +14,8 @@
int main(int argc, const char* argv[])
{
const char* substring_failure = "generated_exe_emulator_unexpected";
const char* substring_success = "generated_exe_emulator_expected";
// Require a slash to make sure it is a path and not a target name.
const char* substring_success = "/generated_exe_emulator_expected";
const char* str = argv[1];
if (argc < 2) {
return EXIT_FAILURE;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment