|
@@ -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);
|
|
|
}
|
|
|
|
|
|
//----------------------------------------------------------------------------
|
|
@@ -3527,6 +3555,29 @@ static void cmTargetCheckLINK_INTERFACE_LIBRARIES(
|
|
|
context->IssueMessage(cmake::FATAL_ERROR, e.str());
|
|
|
}
|
|
|
|
|
|
+//----------------------------------------------------------------------------
|
|
|
+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)
|
|
|
{
|
|
@@ -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,
|