summaryrefslogtreecommitdiffstats
path: root/Source
diff options
context:
space:
mode:
Diffstat (limited to 'Source')
-rw-r--r--Source/cmGeneratorExpressionDAGChecker.cxx3
-rw-r--r--Source/cmPolicies.cxx22
-rw-r--r--Source/cmPolicies.h1
-rw-r--r--Source/cmTarget.cxx179
-rw-r--r--Source/cmTarget.h5
5 files changed, 202 insertions, 8 deletions
diff --git a/Source/cmGeneratorExpressionDAGChecker.cxx b/Source/cmGeneratorExpressionDAGChecker.cxx
index a4d5453..8b17c37 100644
--- a/Source/cmGeneratorExpressionDAGChecker.cxx
+++ b/Source/cmGeneratorExpressionDAGChecker.cxx
@@ -174,7 +174,8 @@ bool cmGeneratorExpressionDAGChecker::EvaluatingLinkLibraries(const char *tgt)
|| strcmp(prop, "LINK_INTERFACE_LIBRARIES") == 0
|| strcmp(prop, "IMPORTED_LINK_INTERFACE_LIBRARIES") == 0
|| strncmp(prop, "LINK_INTERFACE_LIBRARIES_", 25) == 0
- || strncmp(prop, "IMPORTED_LINK_INTERFACE_LIBRARIES_", 34) == 0);
+ || strncmp(prop, "IMPORTED_LINK_INTERFACE_LIBRARIES_", 34) == 0)
+ || strcmp(prop, "INTERFACE_LINK_LIBRARIES") == 0;
}
//----------------------------------------------------------------------------
diff --git a/Source/cmPolicies.cxx b/Source/cmPolicies.cxx
index 32829a6..20c3058 100644
--- a/Source/cmPolicies.cxx
+++ b/Source/cmPolicies.cxx
@@ -544,6 +544,28 @@ cmPolicies::cmPolicies()
"The NEW behavior for this policy is to issue a FATAL_ERROR if "
"INCLUDE_DIRECTORIES contains a relative path.",
2,8,11,20130516, cmPolicies::WARN);
+
+ this->DefinePolicy(
+ CMP0022, "CMP0022",
+ "INTERFACE_LINK_LIBRARIES defines the link interface.",
+ "CMake 2.8.11 constructed the 'link interface' of a target from "
+ "properties matching (IMPORTED_)?LINK_INTERFACE_LIBRARIES(_<CONFIG>)?. "
+ "The modern way to specify config-sensitive content is to use generator "
+ "expressions and the IMPORTED_ prefix makes uniform processing of the "
+ "link interface with generator expressions impossible. The "
+ "INTERFACE_LINK_LIBRARIES target property was introduced as a "
+ "replacement in CMake 2.8.12. This new property is named consistently "
+ "with the INTERFACE_COMPILE_DEFINITIONS, INTERFACE_INCLUDE_DIRECTORIES "
+ "and INTERFACE_COMPILE_OPTIONS properties. For in-build targets, CMake "
+ "will use the INTERFACE_LINK_LIBRARIES property as the source of the "
+ "link interface only if policy CMP0022 is NEW. "
+ "\n"
+ "The OLD behavior for this policy is to ignore the "
+ "INTERFACE_LINK_LIBRARIES property for in-build targets. "
+ "The NEW behavior for this policy is to use the INTERFACE_LINK_LIBRARIES "
+ "property for in-build targets, and ignore the old properties matching "
+ "(IMPORTED_)?LINK_INTERFACE_LIBRARIES(_<CONFIG>)?.",
+ 2,8,11,20130516, cmPolicies::WARN);
}
cmPolicies::~cmPolicies()
diff --git a/Source/cmPolicies.h b/Source/cmPolicies.h
index a033e87..20c953f 100644
--- a/Source/cmPolicies.h
+++ b/Source/cmPolicies.h
@@ -72,6 +72,7 @@ public:
CMP0020, ///< Automatically link Qt executables to qtmain target
CMP0021, ///< Fatal error on relative paths in INCLUDE_DIRECTORIES
/// target property
+ CMP0022, ///< INTERFACE_LINK_LIBRARIES defines the link interface
/** \brief Always the last entry.
*
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,
diff --git a/Source/cmTarget.h b/Source/cmTarget.h
index dd28405..d7ee332 100644
--- a/Source/cmTarget.h
+++ b/Source/cmTarget.h
@@ -111,6 +111,10 @@ public:
cmPolicies::PolicyStatus GetPolicyStatusCMP0021() const
{ return this->PolicyStatusCMP0021; }
+ /** Get the status of policy CMP0022 when the target was created. */
+ cmPolicies::PolicyStatus GetPolicyStatusCMP0022() const
+ { return this->PolicyStatusCMP0022; }
+
/**
* Get the list of the custom commands for this target
*/
@@ -695,6 +699,7 @@ private:
cmPolicies::PolicyStatus PolicyStatusCMP0008;
cmPolicies::PolicyStatus PolicyStatusCMP0020;
cmPolicies::PolicyStatus PolicyStatusCMP0021;
+ cmPolicies::PolicyStatus PolicyStatusCMP0022;
// Internal representation details.
friend class cmTargetInternals;