summaryrefslogtreecommitdiffstats
path: root/Source/cmTarget.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'Source/cmTarget.cxx')
-rw-r--r--Source/cmTarget.cxx179
1 files changed, 172 insertions, 7 deletions
diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index f7424a7..3bad407 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -197,6 +197,7 @@ cmTarget::cmTarget()
this->PolicyStatusCMP0008 = cmPolicies::WARN;
this->PolicyStatusCMP0020 = cmPolicies::WARN;
this->PolicyStatusCMP0021 = cmPolicies::WARN;
+ this->PolicyStatusCMP0022 = cmPolicies::WARN;
this->LinkLibrariesAnalyzed = false;
this->HaveInstallRule = false;
this->DLLPlatform = false;
@@ -474,7 +475,7 @@ void cmTarget::DefineProperties(cmake *cm)
"imported library. "
"The list "
"should be disjoint from the list of interface libraries in the "
- "IMPORTED_LINK_INTERFACE_LIBRARIES property. On platforms requiring "
+ "INTERFACE_LINK_LIBRARIES property. On platforms requiring "
"dependent shared libraries to be found at link time CMake uses this "
"list to add appropriate files or paths to the link command line. "
"Ignored for non-imported targets.");
@@ -495,7 +496,10 @@ void cmTarget::DefineProperties(cmake *cm)
"The libraries will be included on the link line for the target. "
"Unlike the LINK_INTERFACE_LIBRARIES property, this property applies "
"to all imported target types, including STATIC libraries. "
- "This property is ignored for non-imported targets.");
+ "This property is ignored for non-imported targets.\n"
+ "This property is ignored if the target also has a non-empty "
+ "INTERFACE_LINK_LIBRARIES property.\n"
+ "This property is deprecated. Use INTERFACE_LINK_LIBRARIES instead.");
cm->DefineProperty
("IMPORTED_LINK_INTERFACE_LIBRARIES_<CONFIG>", cmProperty::TARGET,
@@ -503,7 +507,10 @@ void cmTarget::DefineProperties(cmake *cm)
"Configuration names correspond to those provided by the project "
"from which the target is imported. "
"If set, this property completely overrides the generic property "
- "for the named configuration.");
+ "for the named configuration.\n"
+ "This property is ignored if the target also has a non-empty "
+ "INTERFACE_LINK_LIBRARIES property.\n"
+ "This property is deprecated. Use INTERFACE_LINK_LIBRARIES instead.");
cm->DefineProperty
("IMPORTED_LINK_INTERFACE_LANGUAGES", cmProperty::TARGET,
@@ -820,7 +827,10 @@ void cmTarget::DefineProperties(cmake *cm)
"This property is initialized by the value of the variable "
"CMAKE_LINK_INTERFACE_LIBRARIES if it is set when a target is "
"created. "
- "This property is ignored for STATIC libraries.");
+ "This property is ignored for STATIC libraries.\n"
+ "This property is overriden by the INTERFACE_LINK_LIBRARIES property if "
+ "policy CMP0022 is NEW.\n"
+ "This property is deprecated. Use INTERFACE_LINK_LIBRARIES instead.");
cm->DefineProperty
("LINK_INTERFACE_LIBRARIES_<CONFIG>", cmProperty::TARGET,
@@ -828,7 +838,23 @@ void cmTarget::DefineProperties(cmake *cm)
"This is the configuration-specific version of "
"LINK_INTERFACE_LIBRARIES. "
"If set, this property completely overrides the generic property "
- "for the named configuration.");
+ "for the named configuration.\n"
+ "This property is overriden by the INTERFACE_LINK_LIBRARIES property if "
+ "policy CMP0022 is NEW.\n"
+ "This property is deprecated. Use INTERFACE_LINK_LIBRARIES instead.");
+
+ cm->DefineProperty
+ ("INTERFACE_LINK_LIBRARIES", cmProperty::TARGET,
+ "List public interface libraries for a shared library or executable.",
+ "This property contains the list of transitive link dependencies. "
+ "When the target is linked into another target the libraries "
+ "listed (and recursively their link interface libraries) will be "
+ "provided to the other target also. "
+ "This property is overriden by the LINK_INTERFACE_LIBRARIES or "
+ "LINK_INTERFACE_LIBRARIES_<CONFIG> property if "
+ "policy CMP0022 is OLD or unset.\n"
+ "\n"
+ CM_DOCUMENT_COMMAND_GENERATOR_EXPRESSIONS);
cm->DefineProperty
("INTERFACE_INCLUDE_DIRECTORIES", cmProperty::TARGET,
@@ -1678,6 +1704,8 @@ void cmTarget::SetMakefile(cmMakefile* mf)
this->Makefile->GetPolicyStatus(cmPolicies::CMP0020);
this->PolicyStatusCMP0021 =
this->Makefile->GetPolicyStatus(cmPolicies::CMP0021);
+ this->PolicyStatusCMP0022 =
+ this->Makefile->GetPolicyStatus(cmPolicies::CMP0022);
}
//----------------------------------------------------------------------------
@@ -3528,6 +3556,29 @@ static void cmTargetCheckLINK_INTERFACE_LIBRARIES(
}
//----------------------------------------------------------------------------
+static void cmTargetCheckINTERFACE_LINK_LIBRARIES(const char* value,
+ cmMakefile* context)
+{
+ // Look for link-type keywords in the value.
+ static cmsys::RegularExpression
+ keys("(^|;)(debug|optimized|general)(;|$)");
+ if(!keys.find(value))
+ {
+ return;
+ }
+
+ // Report an error.
+ cmOStringStream e;
+
+ e << "Property INTERFACE_LINK_LIBRARIES may not contain link-type "
+ "keyword \"" << keys.match(2) << "\". The INTERFACE_LINK_LIBRARIES "
+ "property may contain configuration-sensitive generator-expressions "
+ "which may be used to specify per-configuration rules.";
+
+ context->IssueMessage(cmake::FATAL_ERROR, e.str());
+}
+
+//----------------------------------------------------------------------------
void cmTarget::CheckProperty(const char* prop, cmMakefile* context)
{
// Certain properties need checking.
@@ -3545,6 +3596,13 @@ void cmTarget::CheckProperty(const char* prop, cmMakefile* context)
cmTargetCheckLINK_INTERFACE_LIBRARIES(prop, value, context, true);
}
}
+ if(strncmp(prop, "INTERFACE_LINK_LIBRARIES", 24) == 0)
+ {
+ if(const char* value = this->GetProperty(prop))
+ {
+ cmTargetCheckINTERFACE_LINK_LIBRARIES(value, context);
+ }
+ }
}
//----------------------------------------------------------------------------
@@ -6013,8 +6071,34 @@ void cmTarget::GetTransitivePropertyLinkLibraries(
{
return;
}
+ if(this->GetType() != STATIC_LIBRARY
+ || this->GetPolicyStatusCMP0022() == cmPolicies::WARN
+ || this->GetPolicyStatusCMP0022() == cmPolicies::OLD)
+ {
+ libs = iface->Libraries;
+ return;
+ }
+
+ const char* linkIfaceProp = "INTERFACE_LINK_LIBRARIES";
+ const char* interfaceLibs = this->GetProperty(linkIfaceProp);
- libs = iface->Libraries;
+ if (!interfaceLibs)
+ {
+ return;
+ }
+
+ // The interface libraries have been explicitly set.
+ cmListFileBacktrace lfbt;
+ cmGeneratorExpression ge(lfbt);
+ cmGeneratorExpressionDAGChecker dagChecker(lfbt, this->GetName(),
+ linkIfaceProp, 0, 0);
+ dagChecker.SetTransitivePropertiesOnly();
+ cmSystemTools::ExpandListArgument(ge.Parse(interfaceLibs)->Evaluate(
+ this->Makefile,
+ config,
+ false,
+ headTarget,
+ this, &dagChecker), libs);
}
//----------------------------------------------------------------------------
@@ -6035,6 +6119,8 @@ bool cmTarget::ComputeLinkInterface(const char* config, LinkInterface& iface,
// An explicit list of interface libraries may be set for shared
// libraries and executables that export symbols.
const char* explicitLibraries = 0;
+ const char* newExplicitLibraries =
+ this->GetProperty("INTERFACE_LINK_LIBRARIES");
std::string linkIfaceProp;
if(this->GetType() == cmTarget::SHARED_LIBRARY ||
this->IsExecutableWithExports())
@@ -6050,6 +6136,81 @@ bool cmTarget::ComputeLinkInterface(const char* config, LinkInterface& iface,
linkIfaceProp = "LINK_INTERFACE_LIBRARIES";
explicitLibraries = this->GetProperty(linkIfaceProp.c_str());
}
+ if (newExplicitLibraries
+ && (!explicitLibraries ||
+ (explicitLibraries
+ && strcmp(newExplicitLibraries, explicitLibraries) != 0)))
+ {
+ switch(this->GetPolicyStatusCMP0022())
+ {
+ case cmPolicies::WARN:
+ {
+ cmOStringStream w;
+ w << (this->Makefile->GetPolicies()
+ ->GetPolicyWarning(cmPolicies::CMP0022)) << "\n"
+ << "Target \"" << this->GetName() << "\" has a "
+ "INTERFACE_LINK_LIBRARIES property which differs from its "
+ << linkIfaceProp << " properties.";
+ this->Makefile->IssueMessage(cmake::AUTHOR_WARNING, w.str());
+ }
+ // Fall through
+ case cmPolicies::OLD:
+ break;
+ case cmPolicies::REQUIRED_IF_USED:
+ case cmPolicies::REQUIRED_ALWAYS:
+ case cmPolicies::NEW:
+ explicitLibraries = newExplicitLibraries;
+ linkIfaceProp = "INTERFACE_LINK_LIBRARIES";
+ break;
+ }
+ }
+ }
+ else if(this->GetType() == cmTarget::STATIC_LIBRARY)
+ {
+ if (newExplicitLibraries)
+ {
+ cmListFileBacktrace lfbt;
+ cmGeneratorExpression ge(lfbt);
+ cmGeneratorExpressionDAGChecker dagChecker(lfbt, this->GetName(),
+ "INTERFACE_LINK_LIBRARIES", 0, 0);
+ std::vector<std::string> ifaceLibs;
+ cmSystemTools::ExpandListArgument(
+ ge.Parse(newExplicitLibraries)->Evaluate(
+ this->Makefile,
+ config,
+ false,
+ headTarget,
+ this, &dagChecker), ifaceLibs);
+ LinkImplementation const* impl = this->GetLinkImplementation(config,
+ headTarget);
+ if (ifaceLibs != impl->Libraries)
+ {
+ switch(this->GetPolicyStatusCMP0022())
+ {
+ case cmPolicies::WARN:
+ {
+ cmOStringStream w;
+ w << (this->Makefile->GetPolicies()
+ ->GetPolicyWarning(cmPolicies::CMP0022)) << "\n"
+ << "Static library target \"" << this->GetName() << "\" has a "
+ "INTERFACE_LINK_LIBRARIES property. This should be preferred "
+ "as the source of the link interface for this library. "
+ "Ignoring the property and using the link implementation "
+ "as the link interface instead.";
+ this->Makefile->IssueMessage(cmake::AUTHOR_WARNING, w.str());
+ }
+ // Fall through
+ case cmPolicies::OLD:
+ break;
+ case cmPolicies::REQUIRED_IF_USED:
+ case cmPolicies::REQUIRED_ALWAYS:
+ case cmPolicies::NEW:
+ explicitLibraries = newExplicitLibraries;
+ linkIfaceProp = "INTERFACE_LINK_LIBRARIES";
+ break;
+ }
+ }
+ }
}
// There is no implicit link interface for executables or modules
@@ -6113,7 +6274,11 @@ bool cmTarget::ComputeLinkInterface(const char* config, LinkInterface& iface,
}
}
}
- else
+ else if (this->GetPolicyStatusCMP0022() == cmPolicies::WARN
+ || this->GetPolicyStatusCMP0022() == cmPolicies::OLD)
+ // The implementation shouldn't be the interface if CMP0022 is NEW. That
+ // way, the LINK_LIBRARIES property can be set directly without having to
+ // empty the INTERFACE_LINK_LIBRARIES
{
// The link implementation is the default link interface.
LinkImplementation const* impl = this->GetLinkImplementation(config,