Teach target_* commands to set INTERFACE properties of IMPORTED targets

Now, several `INTERFACE_*` properties can be set on `IMPORTED` targets,
not only via `set_property` and `set_target_properties` but also via
`target_compile_definitions`, `target_compile_features`,
`target_compile_options`, `target_include_directories`, `target_sources`
and `target_link_libraries`.

Fixes: #15689
Issue: #17197
This commit is contained in:
Deniz Bahadir
2017-09-18 17:50:11 +02:00
committed by Brad King
parent e40fd9fd19
commit fe4b25ec2f
28 changed files with 91 additions and 95 deletions

View File

@@ -17,15 +17,6 @@ bool cmTargetCompileDefinitionsCommand::InitialPass(
return this->HandleArguments(args, "COMPILE_DEFINITIONS");
}
void cmTargetCompileDefinitionsCommand::HandleImportedTarget(
const std::string& tgt)
{
std::ostringstream e;
e << "Cannot specify compile definitions for imported target \"" << tgt
<< "\".";
this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
}
void cmTargetCompileDefinitionsCommand::HandleMissingTarget(
const std::string& name)
{
@@ -56,5 +47,5 @@ bool cmTargetCompileDefinitionsCommand::HandleDirectContent(
cmTarget* tgt, const std::vector<std::string>& content, bool, bool)
{
tgt->AppendProperty("COMPILE_DEFINITIONS", this->Join(content).c_str());
return true;
return true; // Successfully handled.
}

View File

@@ -30,7 +30,6 @@ public:
cmExecutionStatus& status) override;
private:
void HandleImportedTarget(const std::string& tgt) override;
void HandleMissingTarget(const std::string& name) override;
bool HandleDirectContent(cmTarget* tgt,

View File

@@ -17,15 +17,6 @@ bool cmTargetCompileFeaturesCommand::InitialPass(
return this->HandleArguments(args, "COMPILE_FEATURES", NO_FLAGS);
}
void cmTargetCompileFeaturesCommand::HandleImportedTarget(
const std::string& tgt)
{
std::ostringstream e;
e << "Cannot specify compile features for imported target \"" << tgt
<< "\".";
this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
}
void cmTargetCompileFeaturesCommand::HandleMissingTarget(
const std::string& name)
{
@@ -49,8 +40,8 @@ bool cmTargetCompileFeaturesCommand::HandleDirectContent(
std::string error;
if (!this->Makefile->AddRequiredTargetFeature(tgt, it, &error)) {
this->SetError(error);
return false;
return false; // Not (successfully) handled.
}
}
return true;
return true; // Successfully handled.
}

View File

@@ -22,7 +22,6 @@ class cmTargetCompileFeaturesCommand : public cmTargetPropCommandBase
cmExecutionStatus& status) override;
private:
void HandleImportedTarget(const std::string& tgt) override;
void HandleMissingTarget(const std::string& name) override;
bool HandleDirectContent(cmTarget* tgt,

View File

@@ -18,21 +18,12 @@ bool cmTargetCompileOptionsCommand::InitialPass(
return this->HandleArguments(args, "COMPILE_OPTIONS", PROCESS_BEFORE);
}
void cmTargetCompileOptionsCommand::HandleImportedTarget(
const std::string& tgt)
{
std::ostringstream e;
e << "Cannot specify compile options for imported target \"" << tgt << "\".";
this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
}
void cmTargetCompileOptionsCommand::HandleMissingTarget(
const std::string& name)
{
std::ostringstream e;
e << "Cannot specify compile options for target \"" << name
<< "\" "
"which is not built by this project.";
<< "\" which is not built by this project.";
this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
}
@@ -47,5 +38,5 @@ bool cmTargetCompileOptionsCommand::HandleDirectContent(
{
cmListFileBacktrace lfbt = this->Makefile->GetBacktrace();
tgt->InsertCompileOption(this->Join(content), lfbt);
return true;
return true; // Successfully handled.
}

View File

@@ -30,7 +30,6 @@ public:
cmExecutionStatus& status) override;
private:
void HandleImportedTarget(const std::string& tgt) override;
void HandleMissingTarget(const std::string& name) override;
bool HandleDirectContent(cmTarget* tgt,

View File

@@ -21,22 +21,12 @@ bool cmTargetIncludeDirectoriesCommand::InitialPass(
ArgumentFlags(PROCESS_BEFORE | PROCESS_SYSTEM));
}
void cmTargetIncludeDirectoriesCommand::HandleImportedTarget(
const std::string& tgt)
{
std::ostringstream e;
e << "Cannot specify include directories for imported target \"" << tgt
<< "\".";
this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
}
void cmTargetIncludeDirectoriesCommand::HandleMissingTarget(
const std::string& name)
{
std::ostringstream e;
e << "Cannot specify include directories for target \"" << name
<< "\" "
"which is not built by this project.";
<< "\" which is not built by this project.";
this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
}
@@ -79,7 +69,7 @@ bool cmTargetIncludeDirectoriesCommand::HandleDirectContent(
}
tgt->AddSystemIncludeDirectories(sdirs);
}
return true;
return true; // Successfully handled.
}
void cmTargetIncludeDirectoriesCommand::HandleInterfaceContent(

View File

@@ -30,7 +30,6 @@ public:
cmExecutionStatus& status) override;
private:
void HandleImportedTarget(const std::string& tgt) override;
void HandleMissingTarget(const std::string& name) override;
bool HandleDirectContent(cmTarget* tgt,

View File

@@ -39,6 +39,16 @@ bool cmTargetLinkLibrariesCommand::InitialPass(
this->Target =
this->Makefile->GetCMakeInstance()->GetGlobalGenerator()->FindTarget(
args[0]);
if (!this->Target) {
const std::vector<cmTarget*>& importedTargets =
this->Makefile->GetOwnedImportedTargets();
for (cmTarget* importedTarget : importedTargets) {
if (importedTarget->GetName() == args[0]) {
this->Target = importedTarget;
break;
}
}
}
if (!this->Target) {
cmake::MessageType t = cmake::FATAL_ERROR; // fail by default
std::ostringstream e;
@@ -228,7 +238,7 @@ bool cmTargetLinkLibrariesCommand::InitialPass(
} else {
// Lookup old-style cache entry if type is unspecified. So if you
// do a target_link_libraries(foo optimized bar) it will stay optimized
// and not use the lookup. As there maybe the case where someone has
// and not use the lookup. As there may be the case where someone has
// specifed that a library is both debug and optimized. (this check is
// only there for backwards compatibility when mixing projects built
// with old versions of CMake and new)
@@ -299,6 +309,14 @@ bool cmTargetLinkLibrariesCommand::HandleLibrary(const std::string& lib,
"target_link_libraries");
return false;
}
if (this->Target->IsImported() &&
this->CurrentProcessingState != ProcessingKeywordLinkInterface) {
this->Makefile->IssueMessage(
cmake::FATAL_ERROR,
"IMPORTED library can only be used with the INTERFACE keyword of "
"target_link_libraries");
return false;
}
cmTarget::TLLSignature sig =
(this->CurrentProcessingState == ProcessingPlainPrivateInterface ||
@@ -354,6 +372,16 @@ bool cmTargetLinkLibrariesCommand::HandleLibrary(const std::string& lib,
cmTarget* t =
this->Makefile->FindLocalNonAliasTarget(this->Target->GetName());
if (!t) {
const std::vector<cmTarget*>& importedTargets =
this->Makefile->GetOwnedImportedTargets();
for (cmTarget* importedTarget : importedTargets) {
if (importedTarget->GetName() == this->Target->GetName()) {
t = importedTarget;
break;
}
}
}
if (!t) {
std::ostringstream e;
e << "Attempt to add link library \"" << lib << "\" to target \""

View File

@@ -84,17 +84,15 @@ bool cmTargetPropCommandBase::ProcessContentArgs(
this->SetError("called with invalid arguments");
return false;
}
if (this->Target->IsImported()) {
this->HandleImportedTarget(args[0]);
return false;
}
if (this->Target->GetType() == cmStateEnums::INTERFACE_LIBRARY &&
scope != "INTERFACE") {
this->SetError("may only set INTERFACE properties on INTERFACE targets");
return false;
}
if (this->Target->IsImported() && scope != "INTERFACE") {
this->SetError("may only set INTERFACE properties on IMPORTED targets");
return false;
}
++argIndex;

View File

@@ -35,7 +35,6 @@ protected:
bool prepend, bool system);
private:
virtual void HandleImportedTarget(const std::string& tgt) = 0;
virtual void HandleMissingTarget(const std::string& name) = 0;
virtual bool HandleDirectContent(cmTarget* tgt,

View File

@@ -17,13 +17,6 @@ bool cmTargetSourcesCommand::InitialPass(std::vector<std::string> const& args,
return this->HandleArguments(args, "SOURCES");
}
void cmTargetSourcesCommand::HandleImportedTarget(const std::string& tgt)
{
std::ostringstream e;
e << "Cannot specify sources for imported target \"" << tgt << "\".";
this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
}
void cmTargetSourcesCommand::HandleMissingTarget(const std::string& name)
{
std::ostringstream e;
@@ -43,5 +36,5 @@ bool cmTargetSourcesCommand::HandleDirectContent(
cmTarget* tgt, const std::vector<std::string>& content, bool, bool)
{
tgt->AppendProperty("SOURCES", this->Join(content).c_str());
return true;
return true; // Successfully handled.
}

View File

@@ -30,7 +30,6 @@ public:
cmExecutionStatus& status) override;
private:
void HandleImportedTarget(const std::string& tgt) override;
void HandleMissingTarget(const std::string& name) override;
bool HandleDirectContent(cmTarget* tgt,