diff options
Diffstat (limited to 'Source/cmTarget.cxx')
-rw-r--r-- | Source/cmTarget.cxx | 179 |
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, |