diff options
author | Brad King <brad.king@kitware.com> | 2013-11-04 12:54:20 (GMT) |
---|---|---|
committer | CMake Topic Stage <kwrobot@kitware.com> | 2013-11-04 12:54:20 (GMT) |
commit | b4a1f442bbaaaa5c1260e87ae7e8e488c8ccef16 (patch) | |
tree | 85727bbc74ab92f59ab7854d9544e5d2cbbe660c /Source | |
parent | eb3761ae68ea643ee7a2a290f03017e67c888a6b (diff) | |
parent | b51696f003a945e7f9de0b551afd707416cc09fa (diff) | |
download | CMake-b4a1f442bbaaaa5c1260e87ae7e8e488c8ccef16.zip CMake-b4a1f442bbaaaa5c1260e87ae7e8e488c8ccef16.tar.gz CMake-b4a1f442bbaaaa5c1260e87ae7e8e488c8ccef16.tar.bz2 |
Merge topic 'policy-CMP0022-fixes-for-master'
b51696f CMP0022: Update target_link_libraries plain signature documentation
25b7f87 Merge branch 'policy-CMP0022-fixes' into policy-CMP0022-fixes-for-master
0a561a0 CMP0022: Warn about a given target at most once
23d21b7 Do not export INTERFACE_LINK_LIBRARIES from non-linkable targets
ef10b87 CMP0022: Plain target_link_libraries must populate link interface
0e06788 CMP0022: Add test for target_link_libraries plain signature
c0f4a61 CMP0022: Add unit test for null pointer check and message.
4b0cfa7 Merge branch 'output-CMP0022-entries' into policy-CMP0022-fixes
Diffstat (limited to 'Source')
-rw-r--r-- | Source/cmExportFileGenerator.cxx | 5 | ||||
-rw-r--r-- | Source/cmTarget.cxx | 252 | ||||
-rw-r--r-- | Source/cmTargetLinkLibrariesCommand.cxx | 10 |
3 files changed, 125 insertions, 142 deletions
diff --git a/Source/cmExportFileGenerator.cxx b/Source/cmExportFileGenerator.cxx index 03e8dff..fdc075e 100644 --- a/Source/cmExportFileGenerator.cxx +++ b/Source/cmExportFileGenerator.cxx @@ -191,6 +191,10 @@ bool cmExportFileGenerator::PopulateInterfaceLinkLibrariesProperty( ImportPropertyMap &properties, std::vector<std::string> &missingTargets) { + if(!target->IsLinkable()) + { + return false; + } const char *input = target->GetProperty("INTERFACE_LINK_LIBRARIES"); if (input) { @@ -654,6 +658,7 @@ cmExportFileGenerator if (iface->ImplementationIsInterface) { + // Policy CMP0022 must not be NEW. this->SetImportLinkProperty(suffix, target, "IMPORTED_LINK_INTERFACE_LIBRARIES", iface->Libraries, properties, missingTargets); diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx index f8b6c92..d0390f7 100644 --- a/Source/cmTarget.cxx +++ b/Source/cmTarget.cxx @@ -81,10 +81,12 @@ class cmTargetInternals public: cmTargetInternals() { + this->PolicyWarnedCMP0022 = false; this->SourceFileFlagsConstructed = false; } cmTargetInternals(cmTargetInternals const&) { + this->PolicyWarnedCMP0022 = false; this->SourceFileFlagsConstructed = false; } ~cmTargetInternals(); @@ -104,6 +106,7 @@ public: typedef std::map<TargetConfigPair, OptionalLinkInterface> LinkInterfaceMapType; LinkInterfaceMapType LinkInterfaceMap; + bool PolicyWarnedCMP0022; typedef std::map<cmStdString, cmTarget::OutputInfo> OutputInfoMapType; OutputInfoMapType OutputInfoMap; @@ -685,21 +688,10 @@ void cmTarget::MergeLinkLibraries( cmMakefile& mf, i += this->PrevLinkedLibraries.size(); for( ; i != libs.end(); ++i ) { - const char *lib = i->first.c_str(); - // We call this so that the dependencies get written to the cache - this->AddLinkLibrary( mf, selfname, lib, i->second ); - - if (this->GetType() == cmTarget::STATIC_LIBRARY) - { - std::string configLib = this->GetDebugGeneratorExpressions(lib, - i->second); - if (cmGeneratorExpression::IsValidTargetName(lib) - || cmGeneratorExpression::Find(lib) != std::string::npos) - { - configLib = "$<LINK_ONLY:" + configLib + ">"; - } - this->AppendProperty("INTERFACE_LINK_LIBRARIES", configLib.c_str()); - } + // This is equivalent to the target_link_libraries plain signature. + this->AddLinkLibrary( mf, selfname, i->first.c_str(), i->second ); + this->AppendProperty("INTERFACE_LINK_LIBRARIES", + this->GetDebugGeneratorExpressions(i->first.c_str(), i->second).c_str()); } this->PrevLinkedLibraries = libs; } @@ -5030,12 +5022,20 @@ 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()) + if(this->PolicyStatusCMP0022 != cmPolicies::OLD && + this->PolicyStatusCMP0022 != cmPolicies::WARN) { + // CMP0022 NEW behavior is to use INTERFACE_LINK_LIBRARIES. + linkIfaceProp = "INTERFACE_LINK_LIBRARIES"; + explicitLibraries = this->GetProperty(linkIfaceProp.c_str()); + } + else if(this->GetType() == cmTarget::SHARED_LIBRARY || + this->IsExecutableWithExports()) + { + // CMP0022 OLD behavior is to use LINK_INTERFACE_LIBRARIES if set on a + // shared lib or executable. + // Lookup the per-configuration property. linkIfaceProp = "LINK_INTERFACE_LIBRARIES"; linkIfaceProp += suffix; @@ -5047,127 +5047,34 @@ 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." - "\n" - "INTERFACE_LINK_LIBRARIES:\n " - << newExplicitLibraries - << "\n" - << linkIfaceProp << ":\n " - << (explicitLibraries ? explicitLibraries : "(empty)") << "\n"; - 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(explicitLibraries && this->PolicyStatusCMP0022 == cmPolicies::WARN && + !this->Internal->PolicyWarnedCMP0022) { - if (newExplicitLibraries) + // Compare the explicitly set old link interface properties to the + // preferred new link interface property one and warn if different. + const char* newExplicitLibraries = + this->GetProperty("INTERFACE_LINK_LIBRARIES"); + if (newExplicitLibraries + && strcmp(newExplicitLibraries, explicitLibraries) != 0) { - 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: - { - std::string oldLibraries; - std::string newLibraries; - const char *sep = ""; - for(std::vector<std::string>::const_iterator it - = impl->Libraries.begin(); it != impl->Libraries.end(); ++it) - { - oldLibraries += sep; - oldLibraries += *it; - sep = ";"; - } - sep = ""; - for(std::vector<std::string>::const_iterator it - = ifaceLibs.begin(); it != ifaceLibs.end(); ++it) - { - newLibraries += sep; - newLibraries += *it; - sep = ";"; - } - - 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." - "\n" - "INTERFACE_LINK_LIBRARIES:\n " - << newLibraries - << "\n" - << "Link implementation:\n " - << oldLibraries << "\n"; - 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 - { - iface.Libraries = impl->Libraries; - if(this->LinkLanguagePropagatesToDependents()) - { - // Targets using this archive need its language runtime libraries. - iface.Languages = impl->Languages; - } - } + cmOStringStream w; + w << + (this->Makefile->GetPolicies() + ->GetPolicyWarning(cmPolicies::CMP0022)) << "\n" + "Target \"" << this->GetName() << "\" has an " + "INTERFACE_LINK_LIBRARIES property which differs from its " << + linkIfaceProp << " properties." + "\n" + "INTERFACE_LINK_LIBRARIES:\n" + " " << newExplicitLibraries << "\n" << + linkIfaceProp << ":\n" + " " << (explicitLibraries ? explicitLibraries : "(empty)") << "\n"; + this->Makefile->IssueMessage(cmake::AUTHOR_WARNING, w.str()); + this->Internal->PolicyWarnedCMP0022 = true; } } - else if (this->GetType() == cmTarget::INTERFACE_LIBRARY) - { - explicitLibraries = newExplicitLibraries; - linkIfaceProp = "INTERFACE_LINK_LIBRARIES"; - } // There is no implicit link interface for executables or modules // so if none was explicitly set then there is no link interface. @@ -5235,11 +5142,12 @@ bool cmTarget::ComputeLinkInterface(const char* config, LinkInterface& iface, } } } - 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 + else if (this->PolicyStatusCMP0022 == cmPolicies::WARN + || this->PolicyStatusCMP0022 == cmPolicies::OLD) + // If CMP0022 is NEW then the plain tll signature sets the + // INTERFACE_LINK_LIBRARIES, so if we get here then the project + // cleared the property explicitly and we should not fall back + // to the link implementation. { // The link implementation is the default link interface. LinkImplementation const* impl = this->GetLinkImplementation(config, @@ -5252,6 +5160,70 @@ bool cmTarget::ComputeLinkInterface(const char* config, LinkInterface& iface, // Targets using this archive need its language runtime libraries. iface.Languages = impl->Languages; } + + if(this->PolicyStatusCMP0022 == cmPolicies::WARN && + !this->Internal->PolicyWarnedCMP0022) + { + // Compare the link implementation fallback link interface to the + // preferred new link interface property and warn if different. + cmListFileBacktrace lfbt; + cmGeneratorExpression ge(lfbt); + cmGeneratorExpressionDAGChecker dagChecker(lfbt, this->GetName(), + "INTERFACE_LINK_LIBRARIES", 0, 0); + std::vector<std::string> ifaceLibs; + const char* newExplicitLibraries = + this->GetProperty("INTERFACE_LINK_LIBRARIES"); + cmSystemTools::ExpandListArgument( + ge.Parse(newExplicitLibraries)->Evaluate(this->Makefile, + config, + false, + headTarget, + this, &dagChecker), + ifaceLibs); + if (ifaceLibs != impl->Libraries) + { + std::string oldLibraries; + std::string newLibraries; + const char *sep = ""; + for(std::vector<std::string>::const_iterator it + = impl->Libraries.begin(); it != impl->Libraries.end(); ++it) + { + oldLibraries += sep; + oldLibraries += *it; + sep = ";"; + } + sep = ""; + for(std::vector<std::string>::const_iterator it + = ifaceLibs.begin(); it != ifaceLibs.end(); ++it) + { + newLibraries += sep; + newLibraries += *it; + sep = ";"; + } + if(oldLibraries.empty()) + { oldLibraries = "(empty)"; } + if(newLibraries.empty()) + { newLibraries = "(empty)"; } + + cmOStringStream w; + w << + (this->Makefile->GetPolicies() + ->GetPolicyWarning(cmPolicies::CMP0022)) << "\n" + "Target \"" << this->GetName() << "\" has an " + "INTERFACE_LINK_LIBRARIES property. " + "This should be preferred as the source of the link interface " + "for this library but because CMP0022 is not set CMake is " + "ignoring the property and using the link implementation " + "as the link interface instead." + "\n" + "INTERFACE_LINK_LIBRARIES:\n" + " " << newLibraries << "\n" + "Link implementation:\n" + " " << oldLibraries << "\n"; + this->Makefile->IssueMessage(cmake::AUTHOR_WARNING, w.str()); + this->Internal->PolicyWarnedCMP0022 = true; + } + } } if(this->GetType() == cmTarget::STATIC_LIBRARY) diff --git a/Source/cmTargetLinkLibrariesCommand.cxx b/Source/cmTargetLinkLibrariesCommand.cxx index 9add198..c289459 100644 --- a/Source/cmTargetLinkLibrariesCommand.cxx +++ b/Source/cmTargetLinkLibrariesCommand.cxx @@ -390,8 +390,14 @@ cmTargetLinkLibrariesCommand::HandleLibrary(const char* lib, { this->Makefile ->AddLinkLibraryForTarget(this->Target->GetName(), lib, llt); - if (this->CurrentProcessingState != ProcessingKeywordPublicInterface - && this->CurrentProcessingState != ProcessingPlainPublicInterface) + if(this->CurrentProcessingState == ProcessingLinkLibraries) + { + this->Target->AppendProperty("INTERFACE_LINK_LIBRARIES", + this->Target->GetDebugGeneratorExpressions(lib, llt).c_str()); + return true; + } + else if(this->CurrentProcessingState != ProcessingKeywordPublicInterface + && this->CurrentProcessingState != ProcessingPlainPublicInterface) { if (this->Target->GetType() == cmTarget::STATIC_LIBRARY) { |