From 5aa9731c9fa06ca51df1e8bdd5f8625d0ce3776d Mon Sep 17 00:00:00 2001 From: Stephen Kelly Date: Tue, 4 Jun 2013 16:17:18 +0200 Subject: GenexEval: Add abstracted access to link interface for a target. This can be extended with special handling for static libraries so that we can process the link dependencies separately from the usage dependencies. --- Source/cmGeneratorExpressionEvaluator.cxx | 11 ++++++----- Source/cmTarget.cxx | 16 ++++++++++++++++ Source/cmTarget.h | 3 +++ 3 files changed, 25 insertions(+), 5 deletions(-) diff --git a/Source/cmGeneratorExpressionEvaluator.cxx b/Source/cmGeneratorExpressionEvaluator.cxx index 05bbc1c..e2af131 100644 --- a/Source/cmGeneratorExpressionEvaluator.cxx +++ b/Source/cmGeneratorExpressionEvaluator.cxx @@ -900,13 +900,14 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode if (std::find_if(transBegin, transEnd, TransitiveWhitelistCompare(propertyName)) != transEnd) { - const cmTarget::LinkInterface *iface = target->GetLinkInterface( - context->Config, - headTarget); - if(iface) + + std::vector libs; + target->GetTransitivePropertyLinkLibraries(context->Config, + headTarget, libs); + if (!libs.empty()) { linkedTargetsContent = - getLinkedTargetsContent(iface->Libraries, target, + getLinkedTargetsContent(libs, target, headTarget, context, &dagChecker, interfacePropertyName); diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx index a90fa74..f7424a7 100644 --- a/Source/cmTarget.cxx +++ b/Source/cmTarget.cxx @@ -6002,6 +6002,22 @@ cmTarget::LinkInterface const* cmTarget::GetLinkInterface(const char* config, } //---------------------------------------------------------------------------- +void cmTarget::GetTransitivePropertyLinkLibraries( + const char* config, + cmTarget *headTarget, + std::vector &libs) +{ + cmTarget::LinkInterface const* iface = this->GetLinkInterface(config, + headTarget); + if (!iface) + { + return; + } + + libs = iface->Libraries; +} + +//---------------------------------------------------------------------------- bool cmTarget::ComputeLinkInterface(const char* config, LinkInterface& iface, cmTarget *headTarget) { diff --git a/Source/cmTarget.h b/Source/cmTarget.h index 3bc0ab2..dd28405 100644 --- a/Source/cmTarget.h +++ b/Source/cmTarget.h @@ -276,6 +276,9 @@ public: if the target cannot be linked. */ LinkInterface const* GetLinkInterface(const char* config, cmTarget *headTarget); + void GetTransitivePropertyLinkLibraries(const char* config, + cmTarget *headTarget, + std::vector &libs); /** The link implementation specifies the direct library dependencies needed by the object files of the target. */ -- cgit v0.12 From ddde61c0b2b46a452366acae690aca0095c0a49c Mon Sep 17 00:00:00 2001 From: Stephen Kelly Date: Wed, 5 Jun 2013 13:43:54 +0200 Subject: Introduce the LINK_ONLY generator expression. This is an internal expression for use by target_link_libraries for static libraries. --- Source/cmGeneratorExpressionDAGChecker.cxx | 16 +++++++++++++++- Source/cmGeneratorExpressionDAGChecker.h | 5 +++++ Source/cmGeneratorExpressionEvaluator.cxx | 20 ++++++++++++++++++++ 3 files changed, 40 insertions(+), 1 deletion(-) diff --git a/Source/cmGeneratorExpressionDAGChecker.cxx b/Source/cmGeneratorExpressionDAGChecker.cxx index 5b79e35..a4d5453 100644 --- a/Source/cmGeneratorExpressionDAGChecker.cxx +++ b/Source/cmGeneratorExpressionDAGChecker.cxx @@ -22,7 +22,7 @@ cmGeneratorExpressionDAGChecker::cmGeneratorExpressionDAGChecker( const GeneratorExpressionContent *content, cmGeneratorExpressionDAGChecker *parent) : Parent(parent), Target(target), Property(property), - Content(content), Backtrace(backtrace) + Content(content), Backtrace(backtrace), TransitivePropertiesOnly(false) { const cmGeneratorExpressionDAGChecker *top = this; const cmGeneratorExpressionDAGChecker *p = this->Parent; @@ -139,6 +139,20 @@ cmGeneratorExpressionDAGChecker::checkGraph() const } //---------------------------------------------------------------------------- +bool cmGeneratorExpressionDAGChecker::GetTransitivePropertiesOnly() +{ + const cmGeneratorExpressionDAGChecker *top = this; + const cmGeneratorExpressionDAGChecker *parent = this->Parent; + while (parent) + { + top = parent; + parent = parent->Parent; + } + + return top->TransitivePropertiesOnly; +} + +//---------------------------------------------------------------------------- bool cmGeneratorExpressionDAGChecker::EvaluatingLinkLibraries(const char *tgt) { const cmGeneratorExpressionDAGChecker *top = this; diff --git a/Source/cmGeneratorExpressionDAGChecker.h b/Source/cmGeneratorExpressionDAGChecker.h index 95d466a..06b23f9 100644 --- a/Source/cmGeneratorExpressionDAGChecker.h +++ b/Source/cmGeneratorExpressionDAGChecker.h @@ -54,6 +54,10 @@ struct cmGeneratorExpressionDAGChecker CM_FOR_EACH_TRANSITIVE_PROPERTY_METHOD(DECLARE_TRANSITIVE_PROPERTY_METHOD) + bool GetTransitivePropertiesOnly(); + void SetTransitivePropertiesOnly() + { this->TransitivePropertiesOnly = true; } + private: Result checkGraph() const; @@ -65,6 +69,7 @@ private: const GeneratorExpressionContent * const Content; const cmListFileBacktrace Backtrace; Result CheckResult; + bool TransitivePropertiesOnly; }; #endif diff --git a/Source/cmGeneratorExpressionEvaluator.cxx b/Source/cmGeneratorExpressionEvaluator.cxx index e2af131..08d9d03 100644 --- a/Source/cmGeneratorExpressionEvaluator.cxx +++ b/Source/cmGeneratorExpressionEvaluator.cxx @@ -492,6 +492,24 @@ static const struct VersionEqualNode : public cmGeneratorExpressionNode } versionEqualNode; //---------------------------------------------------------------------------- +static const struct LinkOnlyNode : public cmGeneratorExpressionNode +{ + LinkOnlyNode() {} + + std::string Evaluate(const std::vector ¶meters, + cmGeneratorExpressionContext *, + const GeneratorExpressionContent *, + cmGeneratorExpressionDAGChecker *dagChecker) const + { + if(!dagChecker->GetTransitivePropertiesOnly()) + { + return parameters.front(); + } + return ""; + } +} linkOnlyNode; + +//---------------------------------------------------------------------------- static const struct ConfigurationNode : public cmGeneratorExpressionNode { ConfigurationNode() {} @@ -1396,6 +1414,8 @@ cmGeneratorExpressionNode* GetNode(const std::string &identifier) return &installPrefixNode; else if (identifier == "JOIN") return &joinNode; + else if (identifier == "LINK_ONLY") + return &linkOnlyNode; return 0; } -- cgit v0.12 From d0a76ea07cfc2a73900a9539e940e1e60dbba120 Mon Sep 17 00:00:00 2001 From: Stephen Kelly Date: Tue, 4 Jun 2013 16:25:47 +0200 Subject: Introduce the INTERFACE_LINK_LIBRARIES property. This property replaces the properties which match (IMPORTED_)?LINK_INTERFACE_LIBRARIES(_)?, and is enabled for IMPORTED targets, and for non-IMPORTED targets only with a policy. For static libraries, the INTERFACE_LINK_LIBRARIES property is also used as the source of transitive usage requirements content. Static libraries still require users to link to all entries in their LINK_LIBRARIES, but usage requirements such as INCLUDE_DIRECTORIES COMPILE_DEFINITIONS and COMPILE_OPTIONS can be restricted to only certain interface libraries. Because the INTERFACE_LINK_LIBRARIES property is populated unconditionally, we need to compare the evaluated result of it with the link implementation to determine whether to issue the policy warning for static libraries. For shared libraries, the policy warning is issued if the contents of the INTERFACE_LINK_LIBRARIES property differs from the contents of the relevant config-specific old LINK_INTERFACE_LIBRARIES property. --- Source/cmGeneratorExpressionDAGChecker.cxx | 3 +- Source/cmPolicies.cxx | 22 +++ Source/cmPolicies.h | 1 + Source/cmTarget.cxx | 179 ++++++++++++++++++++- Source/cmTarget.h | 5 + Tests/CMakeLists.txt | 10 ++ Tests/InterfaceLinkLibraries/CMakeLists.txt | 49 ++++++ Tests/InterfaceLinkLibraries/bang.cpp | 15 ++ Tests/InterfaceLinkLibraries/bang.h | 4 + Tests/InterfaceLinkLibraries/bang_vs6_1.cpp | 1 + Tests/InterfaceLinkLibraries/bang_vs6_2.cpp | 1 + Tests/InterfaceLinkLibraries/bar.cpp | 26 +++ Tests/InterfaceLinkLibraries/bar.h | 7 + Tests/InterfaceLinkLibraries/bar_vs6_1.cpp | 1 + Tests/InterfaceLinkLibraries/bar_vs6_2.cpp | 1 + Tests/InterfaceLinkLibraries/bar_vs6_3.cpp | 1 + Tests/InterfaceLinkLibraries/bar_vs6_4.cpp | 1 + Tests/InterfaceLinkLibraries/foo.cpp | 15 ++ Tests/InterfaceLinkLibraries/foo.h | 4 + Tests/InterfaceLinkLibraries/foo_vs6_1.cpp | 1 + Tests/InterfaceLinkLibraries/foo_vs6_2.cpp | 1 + Tests/InterfaceLinkLibraries/foo_vs6_3.cpp | 1 + Tests/InterfaceLinkLibraries/foo_vs6_4.cpp | 1 + Tests/InterfaceLinkLibraries/main.cpp | 19 +++ Tests/InterfaceLinkLibraries/main_vs6_1.cpp | 1 + Tests/InterfaceLinkLibraries/main_vs6_2.cpp | 1 + Tests/InterfaceLinkLibraries/main_vs6_3.cpp | 1 + Tests/InterfaceLinkLibraries/main_vs6_4.cpp | 1 + .../CMP0022/CMP0022-NOWARN-static-stderr.txt | 1 + Tests/RunCMake/CMP0022/CMP0022-NOWARN-static.cmake | 8 + .../CMP0022/CMP0022-WARN-static-result.txt | 1 + .../CMP0022/CMP0022-WARN-static-stderr.txt | 10 ++ Tests/RunCMake/CMP0022/CMP0022-WARN-static.cmake | 11 ++ Tests/RunCMake/CMP0022/CMP0022-WARN-stderr.txt | 8 + Tests/RunCMake/CMP0022/CMP0022-WARN.cmake | 11 ++ Tests/RunCMake/CMP0022/CMakeLists.txt | 3 + Tests/RunCMake/CMP0022/RunCMakeTest.cmake | 5 + Tests/RunCMake/CMP0022/empty.cpp | 7 + Tests/RunCMake/CMP0022/empty_vs6_1.cpp | 1 + Tests/RunCMake/CMP0022/empty_vs6_2.cpp | 1 + Tests/RunCMake/CMP0022/empty_vs6_3.cpp | 1 + Tests/RunCMake/CMakeLists.txt | 1 + 42 files changed, 434 insertions(+), 8 deletions(-) create mode 100644 Tests/InterfaceLinkLibraries/CMakeLists.txt create mode 100644 Tests/InterfaceLinkLibraries/bang.cpp create mode 100644 Tests/InterfaceLinkLibraries/bang.h create mode 100644 Tests/InterfaceLinkLibraries/bang_vs6_1.cpp create mode 100644 Tests/InterfaceLinkLibraries/bang_vs6_2.cpp create mode 100644 Tests/InterfaceLinkLibraries/bar.cpp create mode 100644 Tests/InterfaceLinkLibraries/bar.h create mode 100644 Tests/InterfaceLinkLibraries/bar_vs6_1.cpp create mode 100644 Tests/InterfaceLinkLibraries/bar_vs6_2.cpp create mode 100644 Tests/InterfaceLinkLibraries/bar_vs6_3.cpp create mode 100644 Tests/InterfaceLinkLibraries/bar_vs6_4.cpp create mode 100644 Tests/InterfaceLinkLibraries/foo.cpp create mode 100644 Tests/InterfaceLinkLibraries/foo.h create mode 100644 Tests/InterfaceLinkLibraries/foo_vs6_1.cpp create mode 100644 Tests/InterfaceLinkLibraries/foo_vs6_2.cpp create mode 100644 Tests/InterfaceLinkLibraries/foo_vs6_3.cpp create mode 100644 Tests/InterfaceLinkLibraries/foo_vs6_4.cpp create mode 100644 Tests/InterfaceLinkLibraries/main.cpp create mode 100644 Tests/InterfaceLinkLibraries/main_vs6_1.cpp create mode 100644 Tests/InterfaceLinkLibraries/main_vs6_2.cpp create mode 100644 Tests/InterfaceLinkLibraries/main_vs6_3.cpp create mode 100644 Tests/InterfaceLinkLibraries/main_vs6_4.cpp create mode 100644 Tests/RunCMake/CMP0022/CMP0022-NOWARN-static-stderr.txt create mode 100644 Tests/RunCMake/CMP0022/CMP0022-NOWARN-static.cmake create mode 100644 Tests/RunCMake/CMP0022/CMP0022-WARN-static-result.txt create mode 100644 Tests/RunCMake/CMP0022/CMP0022-WARN-static-stderr.txt create mode 100644 Tests/RunCMake/CMP0022/CMP0022-WARN-static.cmake create mode 100644 Tests/RunCMake/CMP0022/CMP0022-WARN-stderr.txt create mode 100644 Tests/RunCMake/CMP0022/CMP0022-WARN.cmake create mode 100644 Tests/RunCMake/CMP0022/CMakeLists.txt create mode 100644 Tests/RunCMake/CMP0022/RunCMakeTest.cmake create mode 100644 Tests/RunCMake/CMP0022/empty.cpp create mode 100644 Tests/RunCMake/CMP0022/empty_vs6_1.cpp create mode 100644 Tests/RunCMake/CMP0022/empty_vs6_2.cpp create mode 100644 Tests/RunCMake/CMP0022/empty_vs6_3.cpp 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(_)?. " + "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(_)?.", + 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_", 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_", 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_ 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 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; diff --git a/Tests/CMakeLists.txt b/Tests/CMakeLists.txt index 36cd7fd..fcefaf9 100644 --- a/Tests/CMakeLists.txt +++ b/Tests/CMakeLists.txt @@ -2528,6 +2528,16 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/ --test-command IncludeDirectories) list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/IncludeDirectories") + add_test(InterfaceLinkLibraries ${CMAKE_CTEST_COMMAND} + --build-and-test + "${CMake_SOURCE_DIR}/Tests/InterfaceLinkLibraries" + "${CMake_BINARY_DIR}/Tests/InterfaceLinkLibraries" + --build-two-config + ${build_generator_args} + --build-project InterfaceLinkLibraries + --test-command InterfaceLinkLibraries) + list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/InterfaceLinkLibraries") + if(CMAKE_USE_KWSTYLE AND KWSTYLE_EXECUTABLE) # The "make StyleCheck" command line as a test. If the test fails, look # for lines like "Error #0 (624) Line length exceed 88 (max=79)" in the diff --git a/Tests/InterfaceLinkLibraries/CMakeLists.txt b/Tests/InterfaceLinkLibraries/CMakeLists.txt new file mode 100644 index 0000000..bd0cf74 --- /dev/null +++ b/Tests/InterfaceLinkLibraries/CMakeLists.txt @@ -0,0 +1,49 @@ +cmake_minimum_required (VERSION 2.8) + +cmake_policy(SET CMP0022 NEW) + +project(InterfaceLinkLibraries) + +add_library(foo_shared SHARED foo_vs6_1.cpp) +target_compile_definitions(foo_shared INTERFACE FOO_LIBRARY) +add_library(bar_shared SHARED bar_vs6_1.cpp) +target_compile_definitions(bar_shared INTERFACE BAR_LIBRARY) +set_property(TARGET bar_shared APPEND PROPERTY INTERFACE_LINK_LIBRARIES foo_shared) + +add_executable(shared_test main_vs6_1.cpp) +set_property(TARGET shared_test APPEND PROPERTY LINK_LIBRARIES bar_shared) + +add_library(foo_static STATIC foo_vs6_2.cpp) +target_compile_definitions(foo_static INTERFACE FOO_LIBRARY) +add_library(bar_static STATIC bar_vs6_2.cpp) +target_compile_definitions(bar_static INTERFACE BAR_LIBRARY) +set_property(TARGET bar_static APPEND PROPERTY INTERFACE_LINK_LIBRARIES foo_static) + +add_executable(static_test main_vs6_2.cpp) +set_property(TARGET static_test APPEND PROPERTY LINK_LIBRARIES bar_static) + +add_library(foo_shared_private SHARED foo_vs6_3.cpp) +target_compile_definitions(foo_shared_private INTERFACE FOO_LIBRARY) +add_library(bang_shared_private SHARED bang_vs6_1.cpp) +target_compile_definitions(bang_shared_private INTERFACE BANG_LIBRARY) +add_library(bar_shared_private SHARED bar_vs6_3.cpp) +target_compile_definitions(bar_shared_private INTERFACE BAR_LIBRARY) +target_compile_definitions(bar_shared_private PRIVATE BAR_USE_BANG) +set_property(TARGET bar_shared_private APPEND PROPERTY LINK_LIBRARIES bang_shared_private) +set_property(TARGET bar_shared_private APPEND PROPERTY INTERFACE_LINK_LIBRARIES foo_shared_private) + +add_executable(shared_private_test main_vs6_3.cpp) +set_property(TARGET shared_private_test APPEND PROPERTY LINK_LIBRARIES bar_shared_private) + +add_library(foo_static_private STATIC foo_vs6_4.cpp) +target_compile_definitions(foo_static_private INTERFACE FOO_LIBRARY) +add_library(bang_static_private STATIC bang_vs6_2.cpp) +target_compile_definitions(bang_static_private INTERFACE BANG_LIBRARY) +add_library(bar_static_private STATIC bar_vs6_4.cpp) +target_compile_definitions(bar_static_private INTERFACE BAR_LIBRARY) +target_compile_definitions(bar_static_private PRIVATE BAR_USE_BANG) +set_property(TARGET bar_static_private APPEND PROPERTY LINK_LIBRARIES bang_static_private) +set_property(TARGET bar_static_private APPEND PROPERTY INTERFACE_LINK_LIBRARIES $ foo_static_private) + +add_executable(InterfaceLinkLibraries main_vs6_4.cpp) +set_property(TARGET InterfaceLinkLibraries APPEND PROPERTY LINK_LIBRARIES bar_static_private) diff --git a/Tests/InterfaceLinkLibraries/bang.cpp b/Tests/InterfaceLinkLibraries/bang.cpp new file mode 100644 index 0000000..2e95098 --- /dev/null +++ b/Tests/InterfaceLinkLibraries/bang.cpp @@ -0,0 +1,15 @@ + +#ifdef FOO_LIBRARY +#error Unexpected FOO_LIBRARY +#endif + +#ifdef BAR_LIBRARY +#error Unexpected BAR_LIBRARY +#endif + +#include "bang.h" + +int bang() +{ + return 0; +} diff --git a/Tests/InterfaceLinkLibraries/bang.h b/Tests/InterfaceLinkLibraries/bang.h new file mode 100644 index 0000000..acffb39 --- /dev/null +++ b/Tests/InterfaceLinkLibraries/bang.h @@ -0,0 +1,4 @@ +#ifdef _WIN32 +__declspec(dllexport) +#endif +int bang(); diff --git a/Tests/InterfaceLinkLibraries/bang_vs6_1.cpp b/Tests/InterfaceLinkLibraries/bang_vs6_1.cpp new file mode 100644 index 0000000..4886861 --- /dev/null +++ b/Tests/InterfaceLinkLibraries/bang_vs6_1.cpp @@ -0,0 +1 @@ +#include "bang.cpp" diff --git a/Tests/InterfaceLinkLibraries/bang_vs6_2.cpp b/Tests/InterfaceLinkLibraries/bang_vs6_2.cpp new file mode 100644 index 0000000..4886861 --- /dev/null +++ b/Tests/InterfaceLinkLibraries/bang_vs6_2.cpp @@ -0,0 +1 @@ +#include "bang.cpp" diff --git a/Tests/InterfaceLinkLibraries/bar.cpp b/Tests/InterfaceLinkLibraries/bar.cpp new file mode 100644 index 0000000..f39bfa5 --- /dev/null +++ b/Tests/InterfaceLinkLibraries/bar.cpp @@ -0,0 +1,26 @@ + +#ifdef FOO_LIBRARY +#error Unexpected FOO_LIBRARY +#endif + +#ifdef BAR_USE_BANG +# ifndef BANG_LIBRARY +# error Expected BANG_LIBRARY +# endif +# include "bang.h" +#else +# ifdef BANG_LIBRARY +# error Unexpected BANG_LIBRARY +# endif +#endif + +#include "bar.h" + +int bar() +{ +#ifdef BAR_USE_BANG + return bang(); +#else + return 0; +#endif +} diff --git a/Tests/InterfaceLinkLibraries/bar.h b/Tests/InterfaceLinkLibraries/bar.h new file mode 100644 index 0000000..f83b37e --- /dev/null +++ b/Tests/InterfaceLinkLibraries/bar.h @@ -0,0 +1,7 @@ + +#include "foo.h" + +#ifdef _WIN32 +__declspec(dllexport) +#endif +int bar(); diff --git a/Tests/InterfaceLinkLibraries/bar_vs6_1.cpp b/Tests/InterfaceLinkLibraries/bar_vs6_1.cpp new file mode 100644 index 0000000..58a04c4 --- /dev/null +++ b/Tests/InterfaceLinkLibraries/bar_vs6_1.cpp @@ -0,0 +1 @@ +#include "bar.cpp" diff --git a/Tests/InterfaceLinkLibraries/bar_vs6_2.cpp b/Tests/InterfaceLinkLibraries/bar_vs6_2.cpp new file mode 100644 index 0000000..58a04c4 --- /dev/null +++ b/Tests/InterfaceLinkLibraries/bar_vs6_2.cpp @@ -0,0 +1 @@ +#include "bar.cpp" diff --git a/Tests/InterfaceLinkLibraries/bar_vs6_3.cpp b/Tests/InterfaceLinkLibraries/bar_vs6_3.cpp new file mode 100644 index 0000000..58a04c4 --- /dev/null +++ b/Tests/InterfaceLinkLibraries/bar_vs6_3.cpp @@ -0,0 +1 @@ +#include "bar.cpp" diff --git a/Tests/InterfaceLinkLibraries/bar_vs6_4.cpp b/Tests/InterfaceLinkLibraries/bar_vs6_4.cpp new file mode 100644 index 0000000..58a04c4 --- /dev/null +++ b/Tests/InterfaceLinkLibraries/bar_vs6_4.cpp @@ -0,0 +1 @@ +#include "bar.cpp" diff --git a/Tests/InterfaceLinkLibraries/foo.cpp b/Tests/InterfaceLinkLibraries/foo.cpp new file mode 100644 index 0000000..5295707 --- /dev/null +++ b/Tests/InterfaceLinkLibraries/foo.cpp @@ -0,0 +1,15 @@ + +#ifdef BAR_LIBRARY +#error Unexpected BAR_LIBRARY +#endif + +#ifdef BANG_LIBRARY +#error Unexpected BANG_LIBRARY +#endif + +#include "foo.h" + +int foo() +{ + return 0; +} diff --git a/Tests/InterfaceLinkLibraries/foo.h b/Tests/InterfaceLinkLibraries/foo.h new file mode 100644 index 0000000..e12e23c --- /dev/null +++ b/Tests/InterfaceLinkLibraries/foo.h @@ -0,0 +1,4 @@ +#ifdef _WIN32 +__declspec(dllexport) +#endif +int foo(); diff --git a/Tests/InterfaceLinkLibraries/foo_vs6_1.cpp b/Tests/InterfaceLinkLibraries/foo_vs6_1.cpp new file mode 100644 index 0000000..d2e5e52 --- /dev/null +++ b/Tests/InterfaceLinkLibraries/foo_vs6_1.cpp @@ -0,0 +1 @@ +#include "foo.cpp" diff --git a/Tests/InterfaceLinkLibraries/foo_vs6_2.cpp b/Tests/InterfaceLinkLibraries/foo_vs6_2.cpp new file mode 100644 index 0000000..d2e5e52 --- /dev/null +++ b/Tests/InterfaceLinkLibraries/foo_vs6_2.cpp @@ -0,0 +1 @@ +#include "foo.cpp" diff --git a/Tests/InterfaceLinkLibraries/foo_vs6_3.cpp b/Tests/InterfaceLinkLibraries/foo_vs6_3.cpp new file mode 100644 index 0000000..d2e5e52 --- /dev/null +++ b/Tests/InterfaceLinkLibraries/foo_vs6_3.cpp @@ -0,0 +1 @@ +#include "foo.cpp" diff --git a/Tests/InterfaceLinkLibraries/foo_vs6_4.cpp b/Tests/InterfaceLinkLibraries/foo_vs6_4.cpp new file mode 100644 index 0000000..d2e5e52 --- /dev/null +++ b/Tests/InterfaceLinkLibraries/foo_vs6_4.cpp @@ -0,0 +1 @@ +#include "foo.cpp" diff --git a/Tests/InterfaceLinkLibraries/main.cpp b/Tests/InterfaceLinkLibraries/main.cpp new file mode 100644 index 0000000..a54076a --- /dev/null +++ b/Tests/InterfaceLinkLibraries/main.cpp @@ -0,0 +1,19 @@ + +#ifndef FOO_LIBRARY +#error Expected FOO_LIBRARY +#endif + +#ifndef BAR_LIBRARY +#error Expected BAR_LIBRARY +#endif + +#ifdef BANG_LIBRARY +#error Unexpected BANG_LIBRARY +#endif + +#include "bar.h" + +int main(void) +{ + return foo() + bar(); +} diff --git a/Tests/InterfaceLinkLibraries/main_vs6_1.cpp b/Tests/InterfaceLinkLibraries/main_vs6_1.cpp new file mode 100644 index 0000000..9b10ef2 --- /dev/null +++ b/Tests/InterfaceLinkLibraries/main_vs6_1.cpp @@ -0,0 +1 @@ +#include "main.cpp" diff --git a/Tests/InterfaceLinkLibraries/main_vs6_2.cpp b/Tests/InterfaceLinkLibraries/main_vs6_2.cpp new file mode 100644 index 0000000..9b10ef2 --- /dev/null +++ b/Tests/InterfaceLinkLibraries/main_vs6_2.cpp @@ -0,0 +1 @@ +#include "main.cpp" diff --git a/Tests/InterfaceLinkLibraries/main_vs6_3.cpp b/Tests/InterfaceLinkLibraries/main_vs6_3.cpp new file mode 100644 index 0000000..9b10ef2 --- /dev/null +++ b/Tests/InterfaceLinkLibraries/main_vs6_3.cpp @@ -0,0 +1 @@ +#include "main.cpp" diff --git a/Tests/InterfaceLinkLibraries/main_vs6_4.cpp b/Tests/InterfaceLinkLibraries/main_vs6_4.cpp new file mode 100644 index 0000000..9b10ef2 --- /dev/null +++ b/Tests/InterfaceLinkLibraries/main_vs6_4.cpp @@ -0,0 +1 @@ +#include "main.cpp" diff --git a/Tests/RunCMake/CMP0022/CMP0022-NOWARN-static-stderr.txt b/Tests/RunCMake/CMP0022/CMP0022-NOWARN-static-stderr.txt new file mode 100644 index 0000000..10f3293 --- /dev/null +++ b/Tests/RunCMake/CMP0022/CMP0022-NOWARN-static-stderr.txt @@ -0,0 +1 @@ +^$ diff --git a/Tests/RunCMake/CMP0022/CMP0022-NOWARN-static.cmake b/Tests/RunCMake/CMP0022/CMP0022-NOWARN-static.cmake new file mode 100644 index 0000000..3e4144f --- /dev/null +++ b/Tests/RunCMake/CMP0022/CMP0022-NOWARN-static.cmake @@ -0,0 +1,8 @@ + +project(CMP0022-NOWARN-static) + +add_library(foo STATIC empty_vs6_1.cpp) +add_library(bar STATIC empty_vs6_2.cpp) +add_library(bat STATIC empty_vs6_3.cpp) +target_link_libraries(foo bar) +target_link_libraries(bar bat) diff --git a/Tests/RunCMake/CMP0022/CMP0022-WARN-static-result.txt b/Tests/RunCMake/CMP0022/CMP0022-WARN-static-result.txt new file mode 100644 index 0000000..573541a --- /dev/null +++ b/Tests/RunCMake/CMP0022/CMP0022-WARN-static-result.txt @@ -0,0 +1 @@ +0 diff --git a/Tests/RunCMake/CMP0022/CMP0022-WARN-static-stderr.txt b/Tests/RunCMake/CMP0022/CMP0022-WARN-static-stderr.txt new file mode 100644 index 0000000..41d132c --- /dev/null +++ b/Tests/RunCMake/CMP0022/CMP0022-WARN-static-stderr.txt @@ -0,0 +1,10 @@ +CMake Warning \(dev\) in CMakeLists.txt: + Policy CMP0022 is not set: INTERFACE_LINK_LIBRARIES defines the link + interface. Run "cmake --help-policy CMP0022" for policy details. Use the + cmake_policy command to set the policy and suppress this warning. + + Static library target "bar" 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 warning is for project developers. Use -Wno-dev to suppress it.$ diff --git a/Tests/RunCMake/CMP0022/CMP0022-WARN-static.cmake b/Tests/RunCMake/CMP0022/CMP0022-WARN-static.cmake new file mode 100644 index 0000000..b3cb131 --- /dev/null +++ b/Tests/RunCMake/CMP0022/CMP0022-WARN-static.cmake @@ -0,0 +1,11 @@ + +project(CMP0022-WARN) + +add_library(foo STATIC empty_vs6_1.cpp) +add_library(bar STATIC empty_vs6_2.cpp) +add_library(bat STATIC empty_vs6_3.cpp) +set_property(TARGET bar PROPERTY INTERFACE_LINK_LIBRARIES foo) +set_property(TARGET bar PROPERTY LINK_LIBRARIES bat) + +add_library(user empty.cpp) +target_link_libraries(user bar) diff --git a/Tests/RunCMake/CMP0022/CMP0022-WARN-stderr.txt b/Tests/RunCMake/CMP0022/CMP0022-WARN-stderr.txt new file mode 100644 index 0000000..29103c9 --- /dev/null +++ b/Tests/RunCMake/CMP0022/CMP0022-WARN-stderr.txt @@ -0,0 +1,8 @@ +CMake Warning \(dev\) in CMakeLists.txt: + Policy CMP0022 is not set: INTERFACE_LINK_LIBRARIES defines the link + interface. Run "cmake --help-policy CMP0022" for policy details. Use the + cmake_policy command to set the policy and suppress this warning. + + Target "bar" has a INTERFACE_LINK_LIBRARIES property which differs from its + LINK_INTERFACE_LIBRARIES properties. +This warning is for project developers. Use -Wno-dev to suppress it.$ diff --git a/Tests/RunCMake/CMP0022/CMP0022-WARN.cmake b/Tests/RunCMake/CMP0022/CMP0022-WARN.cmake new file mode 100644 index 0000000..24b7f45 --- /dev/null +++ b/Tests/RunCMake/CMP0022/CMP0022-WARN.cmake @@ -0,0 +1,11 @@ + +project(CMP0022-WARN) + +add_library(foo SHARED empty_vs6_1.cpp) +add_library(bar SHARED empty_vs6_2.cpp) +add_library(bat SHARED empty_vs6_3.cpp) +set_property(TARGET bar PROPERTY INTERFACE_LINK_LIBRARIES foo) +set_property(TARGET bar PROPERTY LINK_INTERFACE_LIBRARIES bat) + +add_library(user empty.cpp) +target_link_libraries(user bar) diff --git a/Tests/RunCMake/CMP0022/CMakeLists.txt b/Tests/RunCMake/CMP0022/CMakeLists.txt new file mode 100644 index 0000000..72abfc8 --- /dev/null +++ b/Tests/RunCMake/CMP0022/CMakeLists.txt @@ -0,0 +1,3 @@ +cmake_minimum_required(VERSION 2.8.11) +project(${RunCMake_TEST} NONE) +include(${RunCMake_TEST}.cmake) diff --git a/Tests/RunCMake/CMP0022/RunCMakeTest.cmake b/Tests/RunCMake/CMP0022/RunCMakeTest.cmake new file mode 100644 index 0000000..2e74f17 --- /dev/null +++ b/Tests/RunCMake/CMP0022/RunCMakeTest.cmake @@ -0,0 +1,5 @@ +include(RunCMake) + +run_cmake(CMP0022-WARN) +run_cmake(CMP0022-WARN-static) +run_cmake(CMP0022-NOWARN-static) diff --git a/Tests/RunCMake/CMP0022/empty.cpp b/Tests/RunCMake/CMP0022/empty.cpp new file mode 100644 index 0000000..bfbbdde --- /dev/null +++ b/Tests/RunCMake/CMP0022/empty.cpp @@ -0,0 +1,7 @@ +#ifdef _WIN32 +__declspec(dllexport) +#endif +int empty() +{ + return 0; +} diff --git a/Tests/RunCMake/CMP0022/empty_vs6_1.cpp b/Tests/RunCMake/CMP0022/empty_vs6_1.cpp new file mode 100644 index 0000000..7efedab --- /dev/null +++ b/Tests/RunCMake/CMP0022/empty_vs6_1.cpp @@ -0,0 +1 @@ +#include "empty.cpp" diff --git a/Tests/RunCMake/CMP0022/empty_vs6_2.cpp b/Tests/RunCMake/CMP0022/empty_vs6_2.cpp new file mode 100644 index 0000000..7efedab --- /dev/null +++ b/Tests/RunCMake/CMP0022/empty_vs6_2.cpp @@ -0,0 +1 @@ +#include "empty.cpp" diff --git a/Tests/RunCMake/CMP0022/empty_vs6_3.cpp b/Tests/RunCMake/CMP0022/empty_vs6_3.cpp new file mode 100644 index 0000000..7efedab --- /dev/null +++ b/Tests/RunCMake/CMP0022/empty_vs6_3.cpp @@ -0,0 +1 @@ +#include "empty.cpp" diff --git a/Tests/RunCMake/CMakeLists.txt b/Tests/RunCMake/CMakeLists.txt index c1a08d2..e07c42f 100644 --- a/Tests/RunCMake/CMakeLists.txt +++ b/Tests/RunCMake/CMakeLists.txt @@ -52,6 +52,7 @@ if(XCODE_VERSION AND "${XCODE_VERSION}" VERSION_LESS 3) endif() add_RunCMake_test(CMP0019) +add_RunCMake_test(CMP0022) add_RunCMake_test(CTest) if(UNIX AND "${CMAKE_TEST_GENERATOR}" MATCHES "Unix Makefiles") add_RunCMake_test(CompilerChange) -- cgit v0.12 From 574fec97fd011ea2899abdd05d97ea66f0faa063 Mon Sep 17 00:00:00 2001 From: Stephen Kelly Date: Tue, 4 Jun 2013 16:47:57 +0200 Subject: Export: Generate INTERFACE_LINK_LIBRARIES property on targets. This property is generated only for targets which have recorded policy CMP0022 as NEW, and a compatibility mode is added to additionally export the old interfaces in that case too. If the old interfaces are not exported, the generated export files require CMake 2.8.12. Because the unit tests use a version which is not yet called 2.8.12, temporarily require a lower version. --- Source/cmExportBuildFileGenerator.cxx | 9 ++++ Source/cmExportCommand.cxx | 2 + Source/cmExportCommand.h | 7 ++- Source/cmExportFileGenerator.cxx | 50 ++++++++++++++++++++++ Source/cmExportFileGenerator.h | 11 +++++ Source/cmExportInstallFileGenerator.cxx | 19 ++++++++ Source/cmInstallCommand.cxx | 33 ++++++++++++-- Source/cmInstallCommand.h | 5 +++ Source/cmInstallExportGenerator.cxx | 3 ++ Source/cmInstallExportGenerator.h | 3 +- Source/cmPolicies.cxx | 5 +++ Source/cmTarget.cxx | 11 +++-- Tests/ExportImport/Export/CMakeLists.txt | 29 +++++++++++++ Tests/ExportImport/Export/cmp0022.cpp | 7 +++ Tests/ExportImport/Export/cmp0022.h | 4 ++ Tests/ExportImport/Export/cmp0022_vs6_1.cpp | 1 + Tests/ExportImport/Export/cmp0022_vs6_2.cpp | 1 + Tests/ExportImport/Import/A/CMakeLists.txt | 10 +++++ Tests/ExportImport/Import/A/cmp0022NEW_test.cpp | 12 ++++++ .../Import/A/cmp0022NEW_test_vs6_1.cpp | 1 + .../Import/A/cmp0022NEW_test_vs6_2.cpp | 1 + Tests/ExportImport/Import/A/cmp0022OLD_test.cpp | 12 ++++++ .../Import/A/cmp0022OLD_test_vs6_1.cpp | 1 + .../Import/A/cmp0022OLD_test_vs6_2.cpp | 1 + Tests/RunCMake/CMP0022/CMP0022-export-result.txt | 1 + Tests/RunCMake/CMP0022/CMP0022-export-stderr.txt | 4 ++ Tests/RunCMake/CMP0022/CMP0022-export.cmake | 11 +++++ .../CMP0022/CMP0022-install-export-result.txt | 1 + .../CMP0022/CMP0022-install-export-stderr.txt | 4 ++ .../RunCMake/CMP0022/CMP0022-install-export.cmake | 12 ++++++ Tests/RunCMake/CMP0022/RunCMakeTest.cmake | 2 + 31 files changed, 265 insertions(+), 8 deletions(-) create mode 100644 Tests/ExportImport/Export/cmp0022.cpp create mode 100644 Tests/ExportImport/Export/cmp0022.h create mode 100644 Tests/ExportImport/Export/cmp0022_vs6_1.cpp create mode 100644 Tests/ExportImport/Export/cmp0022_vs6_2.cpp create mode 100644 Tests/ExportImport/Import/A/cmp0022NEW_test.cpp create mode 100644 Tests/ExportImport/Import/A/cmp0022NEW_test_vs6_1.cpp create mode 100644 Tests/ExportImport/Import/A/cmp0022NEW_test_vs6_2.cpp create mode 100644 Tests/ExportImport/Import/A/cmp0022OLD_test.cpp create mode 100644 Tests/ExportImport/Import/A/cmp0022OLD_test_vs6_1.cpp create mode 100644 Tests/ExportImport/Import/A/cmp0022OLD_test_vs6_2.cpp create mode 100644 Tests/RunCMake/CMP0022/CMP0022-export-result.txt create mode 100644 Tests/RunCMake/CMP0022/CMP0022-export-stderr.txt create mode 100644 Tests/RunCMake/CMP0022/CMP0022-export.cmake create mode 100644 Tests/RunCMake/CMP0022/CMP0022-install-export-result.txt create mode 100644 Tests/RunCMake/CMP0022/CMP0022-install-export-stderr.txt create mode 100644 Tests/RunCMake/CMP0022/CMP0022-install-export.cmake diff --git a/Source/cmExportBuildFileGenerator.cxx b/Source/cmExportBuildFileGenerator.cxx index 326663c..cdc3316 100644 --- a/Source/cmExportBuildFileGenerator.cxx +++ b/Source/cmExportBuildFileGenerator.cxx @@ -77,6 +77,15 @@ bool cmExportBuildFileGenerator::GenerateMainFile(std::ostream& os) properties, missingTargets); this->PopulateInterfaceProperty("INTERFACE_POSITION_INDEPENDENT_CODE", te, properties); + const bool newCMP0022Behavior = + te->GetPolicyStatusCMP0022() != cmPolicies::WARN + && te->GetPolicyStatusCMP0022() != cmPolicies::OLD; + if (newCMP0022Behavior) + { + this->PopulateInterfaceLinkLibrariesProperty(te, + cmGeneratorExpression::BuildInterface, + properties, missingTargets); + } this->PopulateCompatibleInterfaceProperties(te, properties); this->GenerateInterfaceProperties(te, os, properties); diff --git a/Source/cmExportCommand.cxx b/Source/cmExportCommand.cxx index ffa8b51..9c3f314 100644 --- a/Source/cmExportCommand.cxx +++ b/Source/cmExportCommand.cxx @@ -30,6 +30,7 @@ cmExportCommand::cmExportCommand() ,Append(&Helper, "APPEND", &ArgumentGroup) ,Namespace(&Helper, "NAMESPACE", &ArgumentGroup) ,Filename(&Helper, "FILE", &ArgumentGroup) +,ExportOld(&Helper, "EXPORT_LINK_INTERFACE_LIBRARIES", &ArgumentGroup) { // at first TARGETS this->Targets.Follows(0); @@ -158,6 +159,7 @@ bool cmExportCommand ebfg.SetAppendMode(this->Append.IsEnabled()); ebfg.SetExports(&targets); ebfg.SetCommand(this); + ebfg.SetExportOld(this->ExportOld.IsEnabled()); // Compute the set of configurations exported. std::vector configurationTypes; diff --git a/Source/cmExportCommand.h b/Source/cmExportCommand.h index ae67b47..87c3452 100644 --- a/Source/cmExportCommand.h +++ b/Source/cmExportCommand.h @@ -63,7 +63,7 @@ public: { return " export(TARGETS [target1 [target2 [...]]] [NAMESPACE ]\n" - " [APPEND] FILE )\n" + " [APPEND] FILE [EXPORT_LINK_INTERFACE_LIBRARIES])\n" "Create a file that may be included by outside projects to " "import targets from the current project's build tree. " "This is useful during cross-compiling to build utility executables " @@ -73,6 +73,10 @@ public: "prepended to all target names written to the file. " "If the APPEND option is given the generated code will be appended " "to the file instead of overwriting it. " + "The EXPORT_LINK_INTERFACE_LIBRARIES keyword, if present, causes the " + "contents of the properties matching " + "(IMPORTED_)?LINK_INTERFACE_LIBRARIES(_)? to be exported, when " + "policy CMP0022 is NEW. " "If a library target is included in the export but " "a target to which it links is not included the behavior is " "unspecified." @@ -104,6 +108,7 @@ private: cmCAEnabler Append; cmCAString Namespace; cmCAString Filename; + cmCAEnabler ExportOld; friend class cmExportBuildFileGenerator; std::string ErrorMessage; diff --git a/Source/cmExportFileGenerator.cxx b/Source/cmExportFileGenerator.cxx index 6bef017..b4e6e81 100644 --- a/Source/cmExportFileGenerator.cxx +++ b/Source/cmExportFileGenerator.cxx @@ -30,6 +30,7 @@ cmExportFileGenerator::cmExportFileGenerator() { this->AppendMode = false; + this->ExportOld = false; } //---------------------------------------------------------------------------- @@ -168,6 +169,39 @@ void cmExportFileGenerator::PopulateInterfaceProperty(const char *propName, } } +void cmExportFileGenerator::GenerateRequiredCMakeVersion(std::ostream& os, + const char *versionString) +{ + os << "if(CMAKE_VERSION VERSION_LESS " << versionString << ")\n" + " message(FATAL_ERROR \"This file relies on consumers using " + "CMake " << versionString << " or greater.\")\n" + "endif()\n\n"; +} + +//---------------------------------------------------------------------------- +bool cmExportFileGenerator::PopulateInterfaceLinkLibrariesProperty( + cmTarget *target, + cmGeneratorExpression::PreprocessContext preprocessRule, + ImportPropertyMap &properties, + std::vector &missingTargets) +{ + const char *input = target->GetProperty("INTERFACE_LINK_LIBRARIES"); + if (input) + { + std::string prepro = cmGeneratorExpression::Preprocess(input, + preprocessRule); + if (!prepro.empty()) + { + this->ResolveTargetsInGeneratorExpressions(prepro, target, + missingTargets, + ReplaceFreeTargets); + properties["INTERFACE_LINK_LIBRARIES"] = prepro; + return true; + } + } + return false; +} + //---------------------------------------------------------------------------- static bool isSubDirectory(const char* a, const char* b) { @@ -583,6 +617,22 @@ cmExportFileGenerator return; } + const bool newCMP0022Behavior = + target->GetPolicyStatusCMP0022() != cmPolicies::WARN + && target->GetPolicyStatusCMP0022() != cmPolicies::OLD; + + if(newCMP0022Behavior && !this->ExportOld) + { + cmMakefile *mf = target->GetMakefile(); + cmOStringStream e; + e << "Target \"" << target->GetName() << "\" has policy CMP0022 enabled, " + "but also has old-style INTERFACE_LINK_LIBRARIES properties " + "populated, but it was exported without the " + "EXPORT_LINK_INTERFACE_LIBRARIES to export the old-style properties"; + mf->IssueMessage(cmake::FATAL_ERROR, e.str()); + return; + } + if (!*propContent) { properties["IMPORTED_LINK_INTERFACE_LIBRARIES" + suffix] = ""; diff --git a/Source/cmExportFileGenerator.h b/Source/cmExportFileGenerator.h index ed2d93b..a624ba6 100644 --- a/Source/cmExportFileGenerator.h +++ b/Source/cmExportFileGenerator.h @@ -35,6 +35,8 @@ public: /** Set the namespace in which to place exported target names. */ void SetNamespace(const char* ns) { this->Namespace = ns; } + void SetExportOld(bool exportOld) { this->ExportOld = exportOld; } + /** Add a configuration to be exported. */ void AddConfiguration(const char* config); @@ -101,6 +103,10 @@ protected: cmGeneratorExpression::PreprocessContext, ImportPropertyMap &properties, std::vector &missingTargets); + bool PopulateInterfaceLinkLibrariesProperty(cmTarget *target, + cmGeneratorExpression::PreprocessContext, + ImportPropertyMap &properties, + std::vector &missingTargets); void PopulateInterfaceProperty(const char *propName, cmTarget *target, ImportPropertyMap &properties); void PopulateCompatibleInterfaceProperties(cmTarget *target, @@ -128,9 +134,14 @@ protected: std::vector &missingTargets, FreeTargetsReplace replace = NoReplaceFreeTargets); + void GenerateRequiredCMakeVersion(std::ostream& os, + const char *versionString); + // The namespace in which the exports are placed in the generated file. std::string Namespace; + bool ExportOld; + // The set of configurations to export. std::vector Configurations; diff --git a/Source/cmExportInstallFileGenerator.cxx b/Source/cmExportInstallFileGenerator.cxx index a966b16..560882e 100644 --- a/Source/cmExportInstallFileGenerator.cxx +++ b/Source/cmExportInstallFileGenerator.cxx @@ -113,6 +113,7 @@ bool cmExportInstallFileGenerator::GenerateMainFile(std::ostream& os) std::vector missingTargets; + bool require2_8_12 = false; // Create all the imported targets. for(std::vector::const_iterator tei = allTargets.begin(); @@ -134,6 +135,20 @@ bool cmExportInstallFileGenerator::GenerateMainFile(std::ostream& os) te, cmGeneratorExpression::InstallInterface, properties, missingTargets); + + const bool newCMP0022Behavior = + te->GetPolicyStatusCMP0022() != cmPolicies::WARN + && te->GetPolicyStatusCMP0022() != cmPolicies::OLD; + if (newCMP0022Behavior) + { + if (this->PopulateInterfaceLinkLibrariesProperty(te, + cmGeneratorExpression::InstallInterface, + properties, missingTargets) + && !this->ExportOld) + { + require2_8_12 = true; + } + } this->PopulateInterfaceProperty("INTERFACE_POSITION_INDEPENDENT_CODE", te, properties); this->PopulateCompatibleInterfaceProperties(te, properties); @@ -141,6 +156,10 @@ bool cmExportInstallFileGenerator::GenerateMainFile(std::ostream& os) this->GenerateInterfaceProperties(te, os, properties); } + if (require2_8_12) + { + this->GenerateRequiredCMakeVersion(os, "2.8.11.20130626"); + } // Now load per-configuration properties for them. os << "# Load information for each installed configuration.\n" diff --git a/Source/cmInstallCommand.cxx b/Source/cmInstallCommand.cxx index dcd418b..d3a8037 100644 --- a/Source/cmInstallCommand.cxx +++ b/Source/cmInstallCommand.cxx @@ -1196,6 +1196,8 @@ bool cmInstallCommand::HandleExportMode(std::vector const& args) cmInstallCommandArguments ica(this->DefaultComponentName); cmCAString exp(&ica.Parser, "EXPORT"); cmCAString name_space(&ica.Parser, "NAMESPACE", &ica.ArgumentGroup); + cmCAEnabler exportOld(&ica.Parser, "EXPORT_LINK_INTERFACE_LIBRARIES", + &ica.ArgumentGroup); cmCAString filename(&ica.Parser, "FILE", &ica.ArgumentGroup); exp.Follows(0); @@ -1268,15 +1270,40 @@ bool cmInstallCommand::HandleExportMode(std::vector const& args) } } + cmExportSet *exportSet = this->Makefile->GetLocalGenerator() + ->GetGlobalGenerator()->GetExportSets()[exp.GetString()]; + if (exportOld.IsEnabled()) + { + for(std::vector::const_iterator + tei = exportSet->GetTargetExports()->begin(); + tei != exportSet->GetTargetExports()->end(); ++tei) + { + cmTargetExport const* te = *tei; + const bool newCMP0022Behavior = + te->Target->GetPolicyStatusCMP0022() != cmPolicies::WARN + && te->Target->GetPolicyStatusCMP0022() != cmPolicies::OLD; + + if(!newCMP0022Behavior) + { + cmOStringStream e; + e << "INSTALL(EXPORT) given keyword \"" + << "EXPORT_LINK_INTERFACE_LIBRARIES" << "\", but target \"" + << te->Target->GetName() + << "\" does not have policy CMP0022 set to NEW."; + this->SetError(e.str().c_str()); + return false; + } + } + } + // Create the export install generator. cmInstallExportGenerator* exportGenerator = new cmInstallExportGenerator( - this->Makefile->GetLocalGenerator() - ->GetGlobalGenerator()->GetExportSets()[exp.GetString()], + exportSet, ica.GetDestination().c_str(), ica.GetPermissions().c_str(), ica.GetConfigurations(), ica.GetComponent().c_str(), fname.c_str(), - name_space.GetCString(), this->Makefile); + name_space.GetCString(), exportOld.IsEnabled(), this->Makefile); this->Makefile->AddInstallGenerator(exportGenerator); return true; diff --git a/Source/cmInstallCommand.h b/Source/cmInstallCommand.h index 7c06009..39acd23 100644 --- a/Source/cmInstallCommand.h +++ b/Source/cmInstallCommand.h @@ -291,6 +291,7 @@ public: " [NAMESPACE ] [FILE .cmake]\n" " [PERMISSIONS permissions...]\n" " [CONFIGURATIONS [Debug|Release|...]]\n" + " [EXPORT_LINK_INTERFACE_LIBRARIES]\n" " [COMPONENT ])\n" "The EXPORT form generates and installs a CMake file containing code " "to import targets from the installation tree into another project. " @@ -306,6 +307,10 @@ public: "installed when one of the named configurations is installed. " "Additionally, the generated import file will reference only the " "matching target configurations. " + "The EXPORT_LINK_INTERFACE_LIBRARIES keyword, if present, causes the " + "contents of the properties matching " + "(IMPORTED_)?LINK_INTERFACE_LIBRARIES(_)? to be exported, when " + "policy CMP0022 is NEW. " "If a COMPONENT option is specified that does not match that given " "to the targets associated with the behavior is " "undefined. " diff --git a/Source/cmInstallExportGenerator.cxx b/Source/cmInstallExportGenerator.cxx index 0a645a8..3e9e6ac 100644 --- a/Source/cmInstallExportGenerator.cxx +++ b/Source/cmInstallExportGenerator.cxx @@ -33,12 +33,14 @@ cmInstallExportGenerator::cmInstallExportGenerator( std::vector const& configurations, const char* component, const char* filename, const char* name_space, + bool exportOld, cmMakefile* mf) :cmInstallGenerator(destination, configurations, component) ,ExportSet(exportSet) ,FilePermissions(file_permissions) ,FileName(filename) ,Namespace(name_space) + ,ExportOld(exportOld) ,Makefile(mf) { this->EFGen = new cmExportInstallFileGenerator(this); @@ -137,6 +139,7 @@ void cmInstallExportGenerator::GenerateScript(std::ostream& os) // Generate the import file for this export set. this->EFGen->SetExportFile(this->MainImportFile.c_str()); this->EFGen->SetNamespace(this->Namespace.c_str()); + this->EFGen->SetExportOld(this->ExportOld); if(this->ConfigurationTypes->empty()) { if(this->ConfigurationName && *this->ConfigurationName) diff --git a/Source/cmInstallExportGenerator.h b/Source/cmInstallExportGenerator.h index 7aff731..37b5593 100644 --- a/Source/cmInstallExportGenerator.h +++ b/Source/cmInstallExportGenerator.h @@ -31,7 +31,7 @@ public: const std::vector& configurations, const char* component, const char* filename, const char* name_space, - cmMakefile* mf); + bool exportOld, cmMakefile* mf); ~cmInstallExportGenerator(); cmExportSet* GetExportSet() {return this->ExportSet;} @@ -52,6 +52,7 @@ protected: std::string FilePermissions; std::string FileName; std::string Namespace; + bool ExportOld; cmMakefile* Makefile; std::string TempDir; diff --git a/Source/cmPolicies.cxx b/Source/cmPolicies.cxx index 20c3058..15303c8 100644 --- a/Source/cmPolicies.cxx +++ b/Source/cmPolicies.cxx @@ -559,6 +559,11 @@ cmPolicies::cmPolicies() "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. " + "When exporting a target which has this policy set to NEW, only the " + "INTERFACE_LINK_LIBRARIES property will be processed and generated for " + "the IMPORTED target by default. A new option to the install(EXPORT) " + "and export commands allows export of the old-style properties for " + "compatibility with downstream users of CMake versions older than 2.8.12." "\n" "The OLD behavior for this policy is to ignore the " "INTERFACE_LINK_LIBRARIES property for in-build targets. " diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx index 3bad407..f08399f 100644 --- a/Source/cmTarget.cxx +++ b/Source/cmTarget.cxx @@ -5938,11 +5938,16 @@ void cmTarget::ComputeImportInfo(std::string const& desired_config, // Get the link interface. { - std::string linkProp = "IMPORTED_LINK_INTERFACE_LIBRARIES"; - linkProp += suffix; - + std::string linkProp = "INTERFACE_LINK_LIBRARIES"; const char *propertyLibs = this->GetProperty(linkProp.c_str()); + if (!propertyLibs) + { + linkProp = "IMPORTED_LINK_INTERFACE_LIBRARIES"; + linkProp += suffix; + propertyLibs = this->GetProperty(linkProp.c_str()); + } + if(!propertyLibs) { linkProp = "IMPORTED_LINK_INTERFACE_LIBRARIES"; diff --git a/Tests/ExportImport/Export/CMakeLists.txt b/Tests/ExportImport/Export/CMakeLists.txt index efecd03..da15d62 100644 --- a/Tests/ExportImport/Export/CMakeLists.txt +++ b/Tests/ExportImport/Export/CMakeLists.txt @@ -232,6 +232,33 @@ target_link_libraries(testSharedLibDepends LINK_PUBLIC renamed_on_export) target_link_libraries(testSharedLibDepends LINK_INTERFACE_LIBRARIES $<$,EXECUTABLE>:$>) +add_library(cmp0022OLD SHARED cmp0022_vs6_1.cpp) +generate_export_header(cmp0022OLD BASE_NAME cmp0022) +target_include_directories(cmp0022OLD PUBLIC + "$" + "$/include/cmp0022>" +) +cmake_policy(SET CMP0022 NEW) +add_library(cmp0022NEW SHARED cmp0022_vs6_1.cpp) +target_include_directories(cmp0022NEW PUBLIC + "$" + "$/include/cmp0022>" +) +cmake_policy(SET CMP0022 OLD) +install(FILES + "${CMAKE_CURRENT_SOURCE_DIR}/cmp0022.h" + "${CMAKE_CURRENT_BINARY_DIR}/cmp0022_export.h" + DESTINATION include/cmp0022 +) + +set_property(TARGET testLib2 APPEND PROPERTY INTERFACE_COMPILE_DEFINITIONS USING_TESTLIB2) +set_property(TARGET testLib3 APPEND PROPERTY INTERFACE_COMPILE_DEFINITIONS USING_TESTLIB3) + +set_property(TARGET cmp0022NEW APPEND PROPERTY INTERFACE_LINK_LIBRARIES testLib2) +# set_property(TARGET cmp0022NEW APPEND PROPERTY LINK_INTERFACE_LIBRARIES testLibIncludeRequired2) # TODO: Test for error +set_property(TARGET cmp0022OLD APPEND PROPERTY INTERFACE_LINK_LIBRARIES testLib2) +set_property(TARGET cmp0022OLD APPEND PROPERTY LINK_INTERFACE_LIBRARIES testLib3) + install(TARGETS testLibRequired testLibIncludeRequired1 testLibIncludeRequired2 @@ -273,6 +300,7 @@ install( testExe2lib testLib4lib testLib4libdbg testLib4libopt testLib6 testLibCycleA testLibCycleB + cmp0022NEW cmp0022OLD EXPORT exp RUNTIME DESTINATION bin LIBRARY DESTINATION lib NAMELINK_SKIP @@ -316,6 +344,7 @@ add_subdirectory(sublib) # For CMAKE_INCLUDE_CURRENT_DIR_IN_INTERFACE test. export(TARGETS testExe1 testLib1 testLib2 testLib3 testExe2libImp testLib3Imp testLib3ImpDep subdirlib testSharedLibRequired testSharedLibDepends renamed_on_export + cmp0022NEW cmp0022OLD NAMESPACE bld_ FILE ExportBuildTree.cmake ) diff --git a/Tests/ExportImport/Export/cmp0022.cpp b/Tests/ExportImport/Export/cmp0022.cpp new file mode 100644 index 0000000..bef8e61 --- /dev/null +++ b/Tests/ExportImport/Export/cmp0022.cpp @@ -0,0 +1,7 @@ + +#include "cmp0022.h" + +int cmp0022() +{ + return 0; +} diff --git a/Tests/ExportImport/Export/cmp0022.h b/Tests/ExportImport/Export/cmp0022.h new file mode 100644 index 0000000..32bf71a --- /dev/null +++ b/Tests/ExportImport/Export/cmp0022.h @@ -0,0 +1,4 @@ + +#include "cmp0022_export.h" + +int CMP0022_EXPORT cmp0022(); diff --git a/Tests/ExportImport/Export/cmp0022_vs6_1.cpp b/Tests/ExportImport/Export/cmp0022_vs6_1.cpp new file mode 100644 index 0000000..a6ec838 --- /dev/null +++ b/Tests/ExportImport/Export/cmp0022_vs6_1.cpp @@ -0,0 +1 @@ +#include "cmp0022.cpp" diff --git a/Tests/ExportImport/Export/cmp0022_vs6_2.cpp b/Tests/ExportImport/Export/cmp0022_vs6_2.cpp new file mode 100644 index 0000000..a6ec838 --- /dev/null +++ b/Tests/ExportImport/Export/cmp0022_vs6_2.cpp @@ -0,0 +1 @@ +#include "cmp0022.cpp" diff --git a/Tests/ExportImport/Import/A/CMakeLists.txt b/Tests/ExportImport/Import/A/CMakeLists.txt index 3bfbc46..376abac 100644 --- a/Tests/ExportImport/Import/A/CMakeLists.txt +++ b/Tests/ExportImport/Import/A/CMakeLists.txt @@ -68,6 +68,16 @@ target_link_libraries(imp_testExe1b bld_testLibCycleA ) +add_executable(cmp0022OLD_test cmp0022OLD_test_vs6_1.cpp) +target_link_libraries(cmp0022OLD_test bld_cmp0022OLD) +add_executable(cmp0022NEW_test cmp0022NEW_test_vs6_1.cpp) +target_link_libraries(cmp0022NEW_test bld_cmp0022NEW) + +add_executable(cmp0022OLD_exp_test cmp0022OLD_test_vs6_2.cpp) +target_link_libraries(cmp0022OLD_exp_test exp_cmp0022OLD) +add_executable(cmp0022NEW_exp_test cmp0022NEW_test_vs6_2.cpp) +target_link_libraries(cmp0022NEW_exp_test exp_cmp0022NEW) + # Try building a plugin to an executable imported from the build tree. add_library(imp_mod1b MODULE imp_mod1.c) target_link_libraries(imp_mod1b bld_testExe2) diff --git a/Tests/ExportImport/Import/A/cmp0022NEW_test.cpp b/Tests/ExportImport/Import/A/cmp0022NEW_test.cpp new file mode 100644 index 0000000..5878349 --- /dev/null +++ b/Tests/ExportImport/Import/A/cmp0022NEW_test.cpp @@ -0,0 +1,12 @@ + +#ifndef USING_TESTLIB2 +#error Expected USING_TESTLIB2 +#endif +#ifdef USING_TESTLIB3 +#error Unexpected USING_TESTLIB3 +#endif + +int main(void) +{ + return 0; +} diff --git a/Tests/ExportImport/Import/A/cmp0022NEW_test_vs6_1.cpp b/Tests/ExportImport/Import/A/cmp0022NEW_test_vs6_1.cpp new file mode 100644 index 0000000..033b746 --- /dev/null +++ b/Tests/ExportImport/Import/A/cmp0022NEW_test_vs6_1.cpp @@ -0,0 +1 @@ +#include "cmp0022NEW_test.cpp" diff --git a/Tests/ExportImport/Import/A/cmp0022NEW_test_vs6_2.cpp b/Tests/ExportImport/Import/A/cmp0022NEW_test_vs6_2.cpp new file mode 100644 index 0000000..033b746 --- /dev/null +++ b/Tests/ExportImport/Import/A/cmp0022NEW_test_vs6_2.cpp @@ -0,0 +1 @@ +#include "cmp0022NEW_test.cpp" diff --git a/Tests/ExportImport/Import/A/cmp0022OLD_test.cpp b/Tests/ExportImport/Import/A/cmp0022OLD_test.cpp new file mode 100644 index 0000000..e50158b --- /dev/null +++ b/Tests/ExportImport/Import/A/cmp0022OLD_test.cpp @@ -0,0 +1,12 @@ + +#ifdef USING_TESTLIB2 +#error Unexpected USING_TESTLIB2 +#endif +#ifndef USING_TESTLIB3 +#error Expected USING_TESTLIB3 +#endif + +int main(void) +{ + return 0; +} diff --git a/Tests/ExportImport/Import/A/cmp0022OLD_test_vs6_1.cpp b/Tests/ExportImport/Import/A/cmp0022OLD_test_vs6_1.cpp new file mode 100644 index 0000000..90d804c --- /dev/null +++ b/Tests/ExportImport/Import/A/cmp0022OLD_test_vs6_1.cpp @@ -0,0 +1 @@ +#include "cmp0022OLD_test.cpp" diff --git a/Tests/ExportImport/Import/A/cmp0022OLD_test_vs6_2.cpp b/Tests/ExportImport/Import/A/cmp0022OLD_test_vs6_2.cpp new file mode 100644 index 0000000..90d804c --- /dev/null +++ b/Tests/ExportImport/Import/A/cmp0022OLD_test_vs6_2.cpp @@ -0,0 +1 @@ +#include "cmp0022OLD_test.cpp" diff --git a/Tests/RunCMake/CMP0022/CMP0022-export-result.txt b/Tests/RunCMake/CMP0022/CMP0022-export-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/CMP0022/CMP0022-export-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/CMP0022/CMP0022-export-stderr.txt b/Tests/RunCMake/CMP0022/CMP0022-export-stderr.txt new file mode 100644 index 0000000..6c29057 --- /dev/null +++ b/Tests/RunCMake/CMP0022/CMP0022-export-stderr.txt @@ -0,0 +1,4 @@ +CMake Error at CMP0022-export.cmake:11 \(export\): + Target "cmp0022NEW" has policy CMP0022 enabled, but also has old-style + INTERFACE_LINK_LIBRARIES properties populated, but it was exported without + the EXPORT_LINK_INTERFACE_LIBRARIES to export the old-style properties diff --git a/Tests/RunCMake/CMP0022/CMP0022-export.cmake b/Tests/RunCMake/CMP0022/CMP0022-export.cmake new file mode 100644 index 0000000..06147f3 --- /dev/null +++ b/Tests/RunCMake/CMP0022/CMP0022-export.cmake @@ -0,0 +1,11 @@ + +project(cmp0022NEW) + +cmake_policy(SET CMP0022 NEW) + +add_library(cmp0022NEW SHARED empty_vs6_1.cpp) +add_library(testLib SHARED empty_vs6_2.cpp) + +set_property(TARGET cmp0022NEW APPEND PROPERTY LINK_INTERFACE_LIBRARIES testLib) + +export(TARGETS cmp0022NEW testLib FILE "${CMAKE_CURRENT_BINARY_DIR}/cmp0022NEW.cmake") diff --git a/Tests/RunCMake/CMP0022/CMP0022-install-export-result.txt b/Tests/RunCMake/CMP0022/CMP0022-install-export-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/CMP0022/CMP0022-install-export-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/CMP0022/CMP0022-install-export-stderr.txt b/Tests/RunCMake/CMP0022/CMP0022-install-export-stderr.txt new file mode 100644 index 0000000..3425e8e --- /dev/null +++ b/Tests/RunCMake/CMP0022/CMP0022-install-export-stderr.txt @@ -0,0 +1,4 @@ +CMake Error in CMakeLists.txt: + Target "cmp0022NEW" has policy CMP0022 enabled, but also has old-style + INTERFACE_LINK_LIBRARIES properties populated, but it was exported without + the EXPORT_LINK_INTERFACE_LIBRARIES to export the old-style properties diff --git a/Tests/RunCMake/CMP0022/CMP0022-install-export.cmake b/Tests/RunCMake/CMP0022/CMP0022-install-export.cmake new file mode 100644 index 0000000..171febe --- /dev/null +++ b/Tests/RunCMake/CMP0022/CMP0022-install-export.cmake @@ -0,0 +1,12 @@ + +project(cmp0022NEW) + +cmake_policy(SET CMP0022 NEW) + +add_library(cmp0022NEW SHARED empty_vs6_1.cpp) +add_library(testLib SHARED empty_vs6_2.cpp) + +set_property(TARGET cmp0022NEW APPEND PROPERTY LINK_INTERFACE_LIBRARIES testLib) + +install(TARGETS cmp0022NEW testLib EXPORT exp DESTINATION lib) +install(EXPORT exp FILE expTargets.cmake DESTINATION lib/cmake/exp) diff --git a/Tests/RunCMake/CMP0022/RunCMakeTest.cmake b/Tests/RunCMake/CMP0022/RunCMakeTest.cmake index 2e74f17..616d664 100644 --- a/Tests/RunCMake/CMP0022/RunCMakeTest.cmake +++ b/Tests/RunCMake/CMP0022/RunCMakeTest.cmake @@ -3,3 +3,5 @@ include(RunCMake) run_cmake(CMP0022-WARN) run_cmake(CMP0022-WARN-static) run_cmake(CMP0022-NOWARN-static) +run_cmake(CMP0022-export) +run_cmake(CMP0022-install-export) -- cgit v0.12 From 3e30d9ed67f963af15b8d57d24a5fa377299e43a Mon Sep 17 00:00:00 2001 From: Stephen Kelly Date: Tue, 4 Jun 2013 16:21:33 +0200 Subject: TLL: Don't populate old link interface if CMP0022 is NEW. Always populate the INTERFACE_LINK_LIBRARIES for interface entries. Don't populate the old interface properties matching (IMPORTED_)?LINK_INTERFACE_LIBRARIES(_)? if CMP0022 is NEW. Because the INTERFACE_LINK_LIBRARIES property is now populated by the target_link_libraries when operating on a static library, make an equivalent change which populates the property with the same value when the old link_libraries() command is used. This silences the policy warning in that case. --- Source/cmPolicies.cxx | 6 ++++- Source/cmTarget.cxx | 8 +++++++ Source/cmTargetLinkLibrariesCommand.cxx | 26 +++++++++++++++++++++- Source/cmTargetLinkLibrariesCommand.h | 23 ++++++++++++------- .../target_link_libraries/CMakeLists.txt | 2 ++ .../target_link_libraries/cmp0022/CMakeLists.txt | 18 +++++++++++++++ .../target_link_libraries/cmp0022/cmp0022exe.cpp | 7 ++++++ .../cmp0022/cmp0022ifacelib.cpp | 9 ++++++++ .../cmp0022/cmp0022ifacelib.h | 9 ++++++++ .../target_link_libraries/cmp0022/cmp0022lib.cpp | 7 ++++++ .../target_link_libraries/cmp0022/cmp0022lib.h | 6 +++++ ...CMP0022-NOWARN-static-link_libraries-stderr.txt | 1 + .../CMP0022-NOWARN-static-link_libraries.cmake | 9 ++++++++ Tests/RunCMake/CMP0022/CMP0022-WARN-tll-result.txt | 1 + Tests/RunCMake/CMP0022/CMP0022-WARN-tll-stderr.txt | 8 +++++++ Tests/RunCMake/CMP0022/CMP0022-WARN-tll.cmake | 11 +++++++++ Tests/RunCMake/CMP0022/RunCMakeTest.cmake | 2 ++ Tests/RunCMake/CMP0022/dep1/CMakeLists.txt | 2 ++ Tests/RunCMake/CMP0022/dep2/CMakeLists.txt | 2 ++ Tests/RunCMake/CMP0022/dep3/CMakeLists.txt | 5 +++++ 20 files changed, 152 insertions(+), 10 deletions(-) create mode 100644 Tests/CMakeCommands/target_link_libraries/cmp0022/CMakeLists.txt create mode 100644 Tests/CMakeCommands/target_link_libraries/cmp0022/cmp0022exe.cpp create mode 100644 Tests/CMakeCommands/target_link_libraries/cmp0022/cmp0022ifacelib.cpp create mode 100644 Tests/CMakeCommands/target_link_libraries/cmp0022/cmp0022ifacelib.h create mode 100644 Tests/CMakeCommands/target_link_libraries/cmp0022/cmp0022lib.cpp create mode 100644 Tests/CMakeCommands/target_link_libraries/cmp0022/cmp0022lib.h create mode 100644 Tests/RunCMake/CMP0022/CMP0022-NOWARN-static-link_libraries-stderr.txt create mode 100644 Tests/RunCMake/CMP0022/CMP0022-NOWARN-static-link_libraries.cmake create mode 100644 Tests/RunCMake/CMP0022/CMP0022-WARN-tll-result.txt create mode 100644 Tests/RunCMake/CMP0022/CMP0022-WARN-tll-stderr.txt create mode 100644 Tests/RunCMake/CMP0022/CMP0022-WARN-tll.cmake create mode 100644 Tests/RunCMake/CMP0022/dep1/CMakeLists.txt create mode 100644 Tests/RunCMake/CMP0022/dep2/CMakeLists.txt create mode 100644 Tests/RunCMake/CMP0022/dep3/CMakeLists.txt diff --git a/Source/cmPolicies.cxx b/Source/cmPolicies.cxx index 15303c8..70c28d4 100644 --- a/Source/cmPolicies.cxx +++ b/Source/cmPolicies.cxx @@ -563,7 +563,11 @@ cmPolicies::cmPolicies() "INTERFACE_LINK_LIBRARIES property will be processed and generated for " "the IMPORTED target by default. A new option to the install(EXPORT) " "and export commands allows export of the old-style properties for " - "compatibility with downstream users of CMake versions older than 2.8.12." + "compatibility with downstream users of CMake versions older than " + "2.8.12. " + "The target_link_libraries command will no longer populate the " + "properties matching LINK_INTERFACE_LIBRARIES(_)? if this policy " + "is NEW." "\n" "The OLD behavior for this policy is to ignore the " "INTERFACE_LINK_LIBRARIES property for in-build targets. " diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx index f08399f..1dbf665 100644 --- a/Source/cmTarget.cxx +++ b/Source/cmTarget.cxx @@ -2321,6 +2321,14 @@ void cmTarget::MergeLinkLibraries( cmMakefile& mf, { // We call this so that the dependencies get written to the cache this->AddLinkLibrary( mf, selfname, i->first.c_str(), i->second ); + + if (this->GetType() == cmTarget::STATIC_LIBRARY) + { + this->AppendProperty("INTERFACE_LINK_LIBRARIES", + ("$GetDebugGeneratorExpressions(i->first.c_str(), i->second) + + ">").c_str()); + } } this->PrevLinkedLibraries = libs; } diff --git a/Source/cmTargetLinkLibrariesCommand.cxx b/Source/cmTargetLinkLibrariesCommand.cxx index b7b7691..c5f490e 100644 --- a/Source/cmTargetLinkLibrariesCommand.cxx +++ b/Source/cmTargetLinkLibrariesCommand.cxx @@ -224,12 +224,17 @@ bool cmTargetLinkLibrariesCommand cmSystemTools::SetFatalErrorOccured(); } + const cmPolicies::PolicyStatus policy22Status + = this->Target->GetPolicyStatusCMP0022(); + // If any of the LINK_ options were given, make sure the // LINK_INTERFACE_LIBRARIES target property exists. // Use of any of the new keywords implies awareness of // this property. And if no libraries are named, it should // result in an empty link interface. - if(this->CurrentProcessingState != ProcessingLinkLibraries && + if((policy22Status == cmPolicies::OLD || + policy22Status == cmPolicies::WARN) && + this->CurrentProcessingState != ProcessingLinkLibraries && !this->Target->GetProperty("LINK_INTERFACE_LIBRARIES")) { this->Target->SetProperty("LINK_INTERFACE_LIBRARIES", ""); @@ -263,11 +268,30 @@ cmTargetLinkLibrariesCommand::HandleLibrary(const char* lib, ->AddLinkLibraryForTarget(this->Target->GetName(), lib, llt); if (this->CurrentProcessingState != ProcessingPublicInterface) { + if (this->Target->GetType() == cmTarget::STATIC_LIBRARY) + { + this->Target->AppendProperty("INTERFACE_LINK_LIBRARIES", + ("$Target->GetDebugGeneratorExpressions(lib, llt) + + ">").c_str()); + } // Not LINK_INTERFACE_LIBRARIES or LINK_PUBLIC, do not add to interface. return; } } + this->Target->AppendProperty("INTERFACE_LINK_LIBRARIES", + this->Target->GetDebugGeneratorExpressions(lib, llt).c_str()); + + const cmPolicies::PolicyStatus policy22Status + = this->Target->GetPolicyStatusCMP0022(); + + if (policy22Status != cmPolicies::OLD + && policy22Status != cmPolicies::WARN) + { + return; + } + // Get the list of configurations considered to be DEBUG. std::vector const& debugConfigs = this->Makefile->GetCMakeInstance()->GetDebugConfigs(); diff --git a/Source/cmTargetLinkLibrariesCommand.h b/Source/cmTargetLinkLibrariesCommand.h index c683016..ca651d0 100644 --- a/Source/cmTargetLinkLibrariesCommand.h +++ b/Source/cmTargetLinkLibrariesCommand.h @@ -92,7 +92,7 @@ public: "When this target is linked into another target then the libraries " "linked to this target will appear on the link line for the other " "target too. " - "See the LINK_INTERFACE_LIBRARIES target property to override the " + "See the INTERFACE_LINK_LIBRARIES target property to override the " "set of transitive link dependencies for a target. " "Calls to other signatures of this command may set the property " "making any libraries linked exclusively by this signature private." @@ -112,14 +112,19 @@ public: " target_link_libraries( LINK_INTERFACE_LIBRARIES\n" " [[debug|optimized|general] ] ...)\n" "The LINK_INTERFACE_LIBRARIES mode appends the libraries " - "to the LINK_INTERFACE_LIBRARIES and its per-configuration equivalent " - "target properties instead of using them for linking. " - "Libraries specified as \"debug\" are appended to the " + "to the INTERFACE_LINK_LIBRARIES target property instead of using them " + "for linking. If policy CMP0022 is not NEW, then this mode also " + "appends libraries to the LINK_INTERFACE_LIBRARIES and its " + "per-configuration equivalent. " + "Libraries specified as \"debug\" are wrapped in a generator " + "expression to correspond to debug builds. If policy CMP0022 is not " + "NEW, the libraries are also appended to the " "LINK_INTERFACE_LIBRARIES_DEBUG property (or to the properties " "corresponding to configurations listed in the DEBUG_CONFIGURATIONS " "global property if it is set). " "Libraries specified as \"optimized\" are appended to the " - "LINK_INTERFACE_LIBRARIES property. " + "INTERFACE_LINK_LIBRARIES property. If policy CMP0022 is not NEW, " + "they are also appended to the LINK_INTERFACE_LIBRARIES property. " "Libraries specified as \"general\" (or without any keyword) are " "treated as if specified for both \"debug\" and \"optimized\"." "\n" @@ -131,9 +136,11 @@ public: "The LINK_PUBLIC and LINK_PRIVATE modes can be used to specify both " "the link dependencies and the link interface in one command. " "Libraries and targets following LINK_PUBLIC are linked to, and are " - "made part of the LINK_INTERFACE_LIBRARIES. Libraries and targets " - "following LINK_PRIVATE are linked to, but are not made part of the " - "LINK_INTERFACE_LIBRARIES. " + "made part of the INTERFACE_LINK_LIBRARIES. If policy CMP0022 is not " + "NEW, they are also made part of the LINK_INTERFACE_LIBRARIES. " + "Libraries and targets following LINK_PRIVATE are linked to, but are " + "not made part of the INTERFACE_LINK_LIBRARIES (or " + "LINK_INTERFACE_LIBRARIES)." "\n" "The library dependency graph is normally acyclic (a DAG), but in the " "case of mutually-dependent STATIC libraries CMake allows the graph " diff --git a/Tests/CMakeCommands/target_link_libraries/CMakeLists.txt b/Tests/CMakeCommands/target_link_libraries/CMakeLists.txt index b003a1b..2240539 100644 --- a/Tests/CMakeCommands/target_link_libraries/CMakeLists.txt +++ b/Tests/CMakeCommands/target_link_libraries/CMakeLists.txt @@ -122,3 +122,5 @@ add_library(libConsumer empty.cpp) # evaluates to the empty string in non-Debug cases, ensure that that causes # no problems. target_link_libraries(libConsumer debug depA) + +add_subdirectory(cmp0022) diff --git a/Tests/CMakeCommands/target_link_libraries/cmp0022/CMakeLists.txt b/Tests/CMakeCommands/target_link_libraries/cmp0022/CMakeLists.txt new file mode 100644 index 0000000..dd6ab41 --- /dev/null +++ b/Tests/CMakeCommands/target_link_libraries/cmp0022/CMakeLists.txt @@ -0,0 +1,18 @@ + +include(GenerateExportHeader) +set(CMAKE_INCLUDE_CURRENT_DIR ON) + +cmake_policy(SET CMP0022 NEW) +add_library(cmp0022lib SHARED cmp0022lib.cpp) +generate_export_header(cmp0022lib) +add_library(cmp0022ifacelib SHARED cmp0022ifacelib.cpp) +generate_export_header(cmp0022ifacelib) +target_link_libraries(cmp0022lib LINK_PUBLIC cmp0022ifacelib) + +assert_property(cmp0022lib LINK_INTERFACE_LIBRARIES "") +assert_property(cmp0022ifacelib LINK_INTERFACE_LIBRARIES "") +assert_property(cmp0022lib INTERFACE_LINK_LIBRARIES "cmp0022ifacelib") +assert_property(cmp0022ifacelib INTERFACE_LINK_LIBRARIES "") + +add_executable(cmp0022exe cmp0022exe.cpp) +target_link_libraries(cmp0022exe cmp0022lib) diff --git a/Tests/CMakeCommands/target_link_libraries/cmp0022/cmp0022exe.cpp b/Tests/CMakeCommands/target_link_libraries/cmp0022/cmp0022exe.cpp new file mode 100644 index 0000000..008bb74 --- /dev/null +++ b/Tests/CMakeCommands/target_link_libraries/cmp0022/cmp0022exe.cpp @@ -0,0 +1,7 @@ + +#include "cmp0022lib.h" + +int main(void) +{ + return cmp0022().Value; +} diff --git a/Tests/CMakeCommands/target_link_libraries/cmp0022/cmp0022ifacelib.cpp b/Tests/CMakeCommands/target_link_libraries/cmp0022/cmp0022ifacelib.cpp new file mode 100644 index 0000000..b285be0 --- /dev/null +++ b/Tests/CMakeCommands/target_link_libraries/cmp0022/cmp0022ifacelib.cpp @@ -0,0 +1,9 @@ + +#include "cmp0022ifacelib.h" + +CMP0022Iface cmp0022iface() +{ + CMP0022Iface iface; + iface.Value = 0; + return iface; +} diff --git a/Tests/CMakeCommands/target_link_libraries/cmp0022/cmp0022ifacelib.h b/Tests/CMakeCommands/target_link_libraries/cmp0022/cmp0022ifacelib.h new file mode 100644 index 0000000..616dbf6 --- /dev/null +++ b/Tests/CMakeCommands/target_link_libraries/cmp0022/cmp0022ifacelib.h @@ -0,0 +1,9 @@ + +#include "cmp0022ifacelib_export.h" + +struct CMP0022Iface +{ + int Value; +}; + +CMP0022Iface CMP0022IFACELIB_EXPORT cmp0022iface(); diff --git a/Tests/CMakeCommands/target_link_libraries/cmp0022/cmp0022lib.cpp b/Tests/CMakeCommands/target_link_libraries/cmp0022/cmp0022lib.cpp new file mode 100644 index 0000000..381d463 --- /dev/null +++ b/Tests/CMakeCommands/target_link_libraries/cmp0022/cmp0022lib.cpp @@ -0,0 +1,7 @@ + +#include "cmp0022lib.h" + +CMP0022Iface cmp0022() +{ + return cmp0022iface(); +} diff --git a/Tests/CMakeCommands/target_link_libraries/cmp0022/cmp0022lib.h b/Tests/CMakeCommands/target_link_libraries/cmp0022/cmp0022lib.h new file mode 100644 index 0000000..3235b9b --- /dev/null +++ b/Tests/CMakeCommands/target_link_libraries/cmp0022/cmp0022lib.h @@ -0,0 +1,6 @@ + +#include "cmp0022lib_export.h" + +#include "cmp0022ifacelib.h" + +CMP0022Iface CMP0022LIB_EXPORT cmp0022(); diff --git a/Tests/RunCMake/CMP0022/CMP0022-NOWARN-static-link_libraries-stderr.txt b/Tests/RunCMake/CMP0022/CMP0022-NOWARN-static-link_libraries-stderr.txt new file mode 100644 index 0000000..10f3293 --- /dev/null +++ b/Tests/RunCMake/CMP0022/CMP0022-NOWARN-static-link_libraries-stderr.txt @@ -0,0 +1 @@ +^$ diff --git a/Tests/RunCMake/CMP0022/CMP0022-NOWARN-static-link_libraries.cmake b/Tests/RunCMake/CMP0022/CMP0022-NOWARN-static-link_libraries.cmake new file mode 100644 index 0000000..42c4084 --- /dev/null +++ b/Tests/RunCMake/CMP0022/CMP0022-NOWARN-static-link_libraries.cmake @@ -0,0 +1,9 @@ + +enable_language(CXX) + +add_subdirectory(dep1) +add_subdirectory(dep2) +add_subdirectory(dep3) + +add_library(somelib empty.cpp) +target_link_libraries(somelib dep3) diff --git a/Tests/RunCMake/CMP0022/CMP0022-WARN-tll-result.txt b/Tests/RunCMake/CMP0022/CMP0022-WARN-tll-result.txt new file mode 100644 index 0000000..573541a --- /dev/null +++ b/Tests/RunCMake/CMP0022/CMP0022-WARN-tll-result.txt @@ -0,0 +1 @@ +0 diff --git a/Tests/RunCMake/CMP0022/CMP0022-WARN-tll-stderr.txt b/Tests/RunCMake/CMP0022/CMP0022-WARN-tll-stderr.txt new file mode 100644 index 0000000..5a5ad27 --- /dev/null +++ b/Tests/RunCMake/CMP0022/CMP0022-WARN-tll-stderr.txt @@ -0,0 +1,8 @@ +CMake Warning \(dev\) in CMakeLists.txt: + Policy CMP0022 is not set: INTERFACE_LINK_LIBRARIES defines the link + interface. Run "cmake --help-policy CMP0022" for policy details. Use the + cmake_policy command to set the policy and suppress this warning. + + Target "bar" has a INTERFACE_LINK_LIBRARIES property which differs from its + LINK_INTERFACE_LIBRARIES properties. +This warning is for project developers. Use -Wno-dev to suppress it. diff --git a/Tests/RunCMake/CMP0022/CMP0022-WARN-tll.cmake b/Tests/RunCMake/CMP0022/CMP0022-WARN-tll.cmake new file mode 100644 index 0000000..11b4e22 --- /dev/null +++ b/Tests/RunCMake/CMP0022/CMP0022-WARN-tll.cmake @@ -0,0 +1,11 @@ + +project(CMP0022-WARN-tll) + +add_library(foo SHARED empty_vs6_1.cpp) +add_library(bar SHARED empty_vs6_2.cpp) +add_library(bat SHARED empty_vs6_3.cpp) +target_link_libraries(bar LINK_PUBLIC foo) +set_property(TARGET bar PROPERTY LINK_INTERFACE_LIBRARIES bat) + +add_library(user SHARED empty.cpp) +target_link_libraries(user bar) diff --git a/Tests/RunCMake/CMP0022/RunCMakeTest.cmake b/Tests/RunCMake/CMP0022/RunCMakeTest.cmake index 616d664..dcef0f5 100644 --- a/Tests/RunCMake/CMP0022/RunCMakeTest.cmake +++ b/Tests/RunCMake/CMP0022/RunCMakeTest.cmake @@ -1,7 +1,9 @@ include(RunCMake) run_cmake(CMP0022-WARN) +run_cmake(CMP0022-WARN-tll) run_cmake(CMP0022-WARN-static) run_cmake(CMP0022-NOWARN-static) +run_cmake(CMP0022-NOWARN-static-link_libraries) run_cmake(CMP0022-export) run_cmake(CMP0022-install-export) diff --git a/Tests/RunCMake/CMP0022/dep1/CMakeLists.txt b/Tests/RunCMake/CMP0022/dep1/CMakeLists.txt new file mode 100644 index 0000000..f0a8179 --- /dev/null +++ b/Tests/RunCMake/CMP0022/dep1/CMakeLists.txt @@ -0,0 +1,2 @@ + +add_library(dep1 ../empty_vs6_1.cpp) diff --git a/Tests/RunCMake/CMP0022/dep2/CMakeLists.txt b/Tests/RunCMake/CMP0022/dep2/CMakeLists.txt new file mode 100644 index 0000000..4f90162 --- /dev/null +++ b/Tests/RunCMake/CMP0022/dep2/CMakeLists.txt @@ -0,0 +1,2 @@ + +add_library(dep2 ../empty_vs6_2.cpp) diff --git a/Tests/RunCMake/CMP0022/dep3/CMakeLists.txt b/Tests/RunCMake/CMP0022/dep3/CMakeLists.txt new file mode 100644 index 0000000..e85cb54 --- /dev/null +++ b/Tests/RunCMake/CMP0022/dep3/CMakeLists.txt @@ -0,0 +1,5 @@ + +link_libraries(dep1) + +add_library(dep3 ../empty_vs6_3.cpp) +target_link_libraries(dep3 dep2) -- cgit v0.12