|
|
@@ -25,16 +25,17 @@ const char* cmTargetLinkLibrariesCommand::LinkLibraryTypeNames[3] = {
|
|
|
bool cmTargetLinkLibrariesCommand::InitialPass(
|
|
|
std::vector<std::string> const& args, cmExecutionStatus&)
|
|
|
{
|
|
|
- // must have one argument
|
|
|
+ // Must have at least one argument.
|
|
|
if (args.empty()) {
|
|
|
this->SetError("called with incorrect number of arguments");
|
|
|
return false;
|
|
|
}
|
|
|
-
|
|
|
+ // Alias targets cannot be on the LHS of this command.
|
|
|
if (this->Makefile->IsAlias(args[0])) {
|
|
|
this->SetError("can not be used on an ALIAS target.");
|
|
|
return false;
|
|
|
}
|
|
|
+
|
|
|
// Lookup the target for which libraries are specified.
|
|
|
this->Target =
|
|
|
this->Makefile->GetCMakeInstance()->GetGlobalGenerator()->FindTarget(
|
|
|
@@ -78,8 +79,7 @@ bool cmTargetLinkLibrariesCommand::InitialPass(
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
- // now actually print the message
|
|
|
+ // Now actually print the message.
|
|
|
switch (t) {
|
|
|
case cmake::AUTHOR_WARNING:
|
|
|
this->Makefile->IssueMessage(cmake::AUTHOR_WARNING, e.str());
|
|
|
@@ -94,6 +94,7 @@ bool cmTargetLinkLibrariesCommand::InitialPass(
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
+ // OBJECT libraries are not allowed on the LHS of the command.
|
|
|
if (this->Target->GetType() == cmStateEnums::OBJECT_LIBRARY) {
|
|
|
std::ostringstream e;
|
|
|
e << "Object library target \"" << args[0] << "\" "
|
|
|
@@ -103,6 +104,7 @@ bool cmTargetLinkLibrariesCommand::InitialPass(
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
+ // Having a UTILITY library on the LHS is a bug.
|
|
|
if (this->Target->GetType() == cmStateEnums::UTILITY) {
|
|
|
std::ostringstream e;
|
|
|
const char* modal = nullptr;
|
|
|
@@ -129,7 +131,7 @@ bool cmTargetLinkLibrariesCommand::InitialPass(
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- // but we might not have any libs after variable expansion
|
|
|
+ // But we might not have any libs after variable expansion.
|
|
|
if (args.size() < 2) {
|
|
|
return true;
|
|
|
}
|
|
|
@@ -142,8 +144,8 @@ bool cmTargetLinkLibrariesCommand::InitialPass(
|
|
|
// specification if the keyword is encountered as the first argument.
|
|
|
this->CurrentProcessingState = ProcessingLinkLibraries;
|
|
|
|
|
|
- // add libraries, note that there is an optional prefix
|
|
|
- // of debug and optimized that can be used
|
|
|
+ // Add libraries, note that there is an optional prefix
|
|
|
+ // of debug and optimized that can be used.
|
|
|
for (unsigned int i = 1; i < args.size(); ++i) {
|
|
|
if (args[i] == "LINK_INTERFACE_LIBRARIES") {
|
|
|
this->CurrentProcessingState = ProcessingPlainLinkInterface;
|
|
|
@@ -366,10 +368,13 @@ bool cmTargetLinkLibrariesCommand::HandleLibrary(const std::string& lib,
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- // Handle normal case first.
|
|
|
+ // Handle normal case where the command was called with another keyword than
|
|
|
+ // INTERFACE / LINK_INTERFACE_LIBRARIES or none at all. (The "LINK_LIBRARIES"
|
|
|
+ // property of the target on the LHS shall be populated.)
|
|
|
if (this->CurrentProcessingState != ProcessingKeywordLinkInterface &&
|
|
|
this->CurrentProcessingState != ProcessingPlainLinkInterface) {
|
|
|
|
|
|
+ // Assure that the target on the LHS was created in the current directory.
|
|
|
cmTarget* t =
|
|
|
this->Makefile->FindLocalNonAliasTarget(this->Target->GetName());
|
|
|
if (!t) {
|
|
|
@@ -408,72 +413,80 @@ bool cmTargetLinkLibrariesCommand::HandleLibrary(const std::string& lib,
|
|
|
}
|
|
|
|
|
|
this->Target->AddLinkLibrary(*this->Makefile, lib, llt);
|
|
|
+ }
|
|
|
|
|
|
- if (this->CurrentProcessingState == ProcessingLinkLibraries) {
|
|
|
- this->Target->AppendProperty(
|
|
|
- "INTERFACE_LINK_LIBRARIES",
|
|
|
- this->Target->GetDebugGeneratorExpressions(lib, llt).c_str());
|
|
|
- return true;
|
|
|
- }
|
|
|
- if (this->CurrentProcessingState != ProcessingKeywordPublicInterface &&
|
|
|
- this->CurrentProcessingState != ProcessingPlainPublicInterface) {
|
|
|
- if (this->Target->GetType() == cmStateEnums::STATIC_LIBRARY) {
|
|
|
- std::string configLib =
|
|
|
- this->Target->GetDebugGeneratorExpressions(lib, llt);
|
|
|
- if (cmGeneratorExpression::IsValidTargetName(lib) ||
|
|
|
- cmGeneratorExpression::Find(lib) != std::string::npos) {
|
|
|
- configLib = "$<LINK_ONLY:" + configLib + ">";
|
|
|
- }
|
|
|
- this->Target->AppendProperty("INTERFACE_LINK_LIBRARIES",
|
|
|
- configLib.c_str());
|
|
|
+ // Handle (additional) case where the command was called with PRIVATE /
|
|
|
+ // LINK_PRIVATE and stop its processing. (The "INTERFACE_LINK_LIBRARIES"
|
|
|
+ // property of the target on the LHS shall only be populated if it is a
|
|
|
+ // STATIC library.)
|
|
|
+ if (this->CurrentProcessingState == ProcessingKeywordPrivateInterface ||
|
|
|
+ this->CurrentProcessingState == ProcessingPlainPrivateInterface) {
|
|
|
+ if (this->Target->GetType() == cmStateEnums::STATIC_LIBRARY) {
|
|
|
+ std::string configLib =
|
|
|
+ this->Target->GetDebugGeneratorExpressions(lib, llt);
|
|
|
+ if (cmGeneratorExpression::IsValidTargetName(lib) ||
|
|
|
+ cmGeneratorExpression::Find(lib) != std::string::npos) {
|
|
|
+ configLib = "$<LINK_ONLY:" + configLib + ">";
|
|
|
}
|
|
|
- // Not a 'public' or 'interface' library. Do not add to interface
|
|
|
- // property.
|
|
|
- return true;
|
|
|
+ this->Target->AppendProperty("INTERFACE_LINK_LIBRARIES",
|
|
|
+ configLib.c_str());
|
|
|
}
|
|
|
+ return true;
|
|
|
}
|
|
|
|
|
|
+ // Handle general case where the command was called with another keyword than
|
|
|
+ // PRIVATE / LINK_PRIVATE or none at all. (The "INTERFACE_LINK_LIBRARIES"
|
|
|
+ // property of the target on the LHS shall be populated.)
|
|
|
this->Target->AppendProperty(
|
|
|
"INTERFACE_LINK_LIBRARIES",
|
|
|
this->Target->GetDebugGeneratorExpressions(lib, llt).c_str());
|
|
|
|
|
|
+ // Stop processing if called without any keyword.
|
|
|
+ if (this->CurrentProcessingState == ProcessingLinkLibraries) {
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ // Stop processing if policy CMP0022 is set to NEW.
|
|
|
const cmPolicies::PolicyStatus policy22Status =
|
|
|
this->Target->GetPolicyStatusCMP0022();
|
|
|
-
|
|
|
if (policy22Status != cmPolicies::OLD &&
|
|
|
policy22Status != cmPolicies::WARN) {
|
|
|
return true;
|
|
|
}
|
|
|
-
|
|
|
+ // Stop processing if called with an INTERFACE library on the LHS.
|
|
|
if (this->Target->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
- // Get the list of configurations considered to be DEBUG.
|
|
|
- std::vector<std::string> debugConfigs =
|
|
|
- this->Makefile->GetCMakeInstance()->GetDebugConfigs();
|
|
|
- std::string prop;
|
|
|
-
|
|
|
- // Include this library in the link interface for the target.
|
|
|
- if (llt == DEBUG_LibraryType || llt == GENERAL_LibraryType) {
|
|
|
- // Put in the DEBUG configuration interfaces.
|
|
|
- for (std::string const& dc : debugConfigs) {
|
|
|
- prop = "LINK_INTERFACE_LIBRARIES_";
|
|
|
- prop += dc;
|
|
|
- this->Target->AppendProperty(prop, lib.c_str());
|
|
|
+ // Handle (additional) backward-compatibility case where the command was
|
|
|
+ // called with PUBLIC / INTERFACE / LINK_PUBLIC / LINK_INTERFACE_LIBRARIES.
|
|
|
+ // (The policy CMP0022 is not set to NEW.)
|
|
|
+ {
|
|
|
+ // Get the list of configurations considered to be DEBUG.
|
|
|
+ std::vector<std::string> debugConfigs =
|
|
|
+ this->Makefile->GetCMakeInstance()->GetDebugConfigs();
|
|
|
+ std::string prop;
|
|
|
+
|
|
|
+ // Include this library in the link interface for the target.
|
|
|
+ if (llt == DEBUG_LibraryType || llt == GENERAL_LibraryType) {
|
|
|
+ // Put in the DEBUG configuration interfaces.
|
|
|
+ for (std::string const& dc : debugConfigs) {
|
|
|
+ prop = "LINK_INTERFACE_LIBRARIES_";
|
|
|
+ prop += dc;
|
|
|
+ this->Target->AppendProperty(prop, lib.c_str());
|
|
|
+ }
|
|
|
}
|
|
|
- }
|
|
|
- if (llt == OPTIMIZED_LibraryType || llt == GENERAL_LibraryType) {
|
|
|
- // Put in the non-DEBUG configuration interfaces.
|
|
|
- this->Target->AppendProperty("LINK_INTERFACE_LIBRARIES", lib.c_str());
|
|
|
-
|
|
|
- // Make sure the DEBUG configuration interfaces exist so that the
|
|
|
- // general one will not be used as a fall-back.
|
|
|
- for (std::string const& dc : debugConfigs) {
|
|
|
- prop = "LINK_INTERFACE_LIBRARIES_";
|
|
|
- prop += dc;
|
|
|
- if (!this->Target->GetProperty(prop)) {
|
|
|
- this->Target->SetProperty(prop, "");
|
|
|
+ if (llt == OPTIMIZED_LibraryType || llt == GENERAL_LibraryType) {
|
|
|
+ // Put in the non-DEBUG configuration interfaces.
|
|
|
+ this->Target->AppendProperty("LINK_INTERFACE_LIBRARIES", lib.c_str());
|
|
|
+
|
|
|
+ // Make sure the DEBUG configuration interfaces exist so that the
|
|
|
+ // general one will not be used as a fall-back.
|
|
|
+ for (std::string const& dc : debugConfigs) {
|
|
|
+ prop = "LINK_INTERFACE_LIBRARIES_";
|
|
|
+ prop += dc;
|
|
|
+ if (!this->Target->GetProperty(prop)) {
|
|
|
+ this->Target->SetProperty(prop, "");
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
}
|