diff options
22 files changed, 265 insertions, 256 deletions
diff --git a/Help/manual/cmake-generator-expressions.7.rst b/Help/manual/cmake-generator-expressions.7.rst index 9e82674..bc24798 100644 --- a/Help/manual/cmake-generator-expressions.7.rst +++ b/Help/manual/cmake-generator-expressions.7.rst @@ -188,6 +188,13 @@ property is non-empty:: Marks ``...`` as being the name of a target. This is required if exporting targets to multiple dependent export sets. The ``...`` must be a literal name of a target- it may not contain generator expressions. +``$<LINK_ONLY:...>`` + Content of ``...`` except when evaluated in a link interface while + propagating :ref:`Target Usage Requirements`, in which case it is the + empty string. + Intended for use only in an :prop_tgt:`INTERFACE_LINK_LIBRARIES` target + property, perhaps via the :command:`target_link_libraries` command, + to specify private link dependencies without other usage requirements. ``$<INSTALL_INTERFACE:...>`` Content of ``...`` when the property is exported using :command:`install(EXPORT)`, and empty otherwise. diff --git a/Help/release/dev/generalize-LINK_ONLY.rst b/Help/release/dev/generalize-LINK_ONLY.rst new file mode 100644 index 0000000..6dccbd5 --- /dev/null +++ b/Help/release/dev/generalize-LINK_ONLY.rst @@ -0,0 +1,6 @@ +generalize-LINK_ONLY +-------------------- + +* The :prop_tgt:`INTERFACE_LINK_LIBRARIES` target property now supports + a ``$<LINK_ONLY:...>`` + :manual:`generator expression <cmake-generator-expressions(7)>`. diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake index eb5dd2e..b0a7f64 100644 --- a/Source/CMakeVersion.cmake +++ b/Source/CMakeVersion.cmake @@ -1,5 +1,5 @@ # CMake version number components. set(CMake_VERSION_MAJOR 3) set(CMake_VERSION_MINOR 0) -set(CMake_VERSION_PATCH 20140717) +set(CMake_VERSION_PATCH 20140718) #set(CMake_VERSION_RC 1) diff --git a/Source/CTest/cmCTestSubmitHandler.cxx b/Source/CTest/cmCTestSubmitHandler.cxx index 7c72cba..109905c 100644 --- a/Source/CTest/cmCTestSubmitHandler.cxx +++ b/Source/CTest/cmCTestSubmitHandler.cxx @@ -225,8 +225,8 @@ bool cmCTestSubmitHandler::SubmitUsingFTP(const std::string& localprefix, std::string upload_as = url + "/" + remoteprefix + cmSystemTools::GetFilenameName(*file); - struct stat st; - if ( ::stat(local_file.c_str(), &st) ) + + if ( !cmSystemTools::FileExists(local_file.c_str()) ) { cmCTestLog(this->CTest, ERROR_MESSAGE, " Cannot find file: " << local_file << std::endl); @@ -234,6 +234,7 @@ bool cmCTestSubmitHandler::SubmitUsingFTP(const std::string& localprefix, ::curl_global_cleanup(); return false; } + unsigned long filelen = cmSystemTools::FileLength(local_file.c_str()); ftpfile = cmsys::SystemTools::Fopen(local_file.c_str(), "rb"); *this->LogFile << "\tUpload file: " << local_file << " to " @@ -252,7 +253,7 @@ bool cmCTestSubmitHandler::SubmitUsingFTP(const std::string& localprefix, // and give the size of the upload (optional) ::curl_easy_setopt(curl, CURLOPT_INFILESIZE, - static_cast<long>(st.st_size)); + static_cast<long>(filelen)); // and give curl the buffer for errors ::curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, &error_buffer); @@ -466,8 +467,7 @@ bool cmCTestSubmitHandler::SubmitUsingHTTP(const std::string& localprefix, upload_as += md5; } - struct stat st; - if ( ::stat(local_file.c_str(), &st) ) + if( !cmSystemTools::FileExists(local_file.c_str()) ) { cmCTestLog(this->CTest, ERROR_MESSAGE, " Cannot find file: " << local_file << std::endl); @@ -475,11 +475,12 @@ bool cmCTestSubmitHandler::SubmitUsingHTTP(const std::string& localprefix, ::curl_global_cleanup(); return false; } + unsigned long filelen = cmSystemTools::FileLength(local_file.c_str()); ftpfile = cmsys::SystemTools::Fopen(local_file.c_str(), "rb"); cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, " Upload file: " << local_file << " to " - << upload_as << " Size: " << st.st_size << std::endl); + << upload_as << " Size: " << filelen << std::endl); // specify target ::curl_easy_setopt(curl,CURLOPT_URL, upload_as.c_str()); @@ -489,7 +490,7 @@ bool cmCTestSubmitHandler::SubmitUsingHTTP(const std::string& localprefix, // and give the size of the upload (optional) ::curl_easy_setopt(curl, CURLOPT_INFILESIZE, - static_cast<long>(st.st_size)); + static_cast<long>(filelen)); // and give curl the buffer for errors ::curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, &error_buffer); diff --git a/Source/cmGeneratorExpressionEvaluator.cxx b/Source/cmGeneratorExpressionEvaluator.cxx index 3b83cd3..28879f1 100644 --- a/Source/cmGeneratorExpressionEvaluator.cxx +++ b/Source/cmGeneratorExpressionEvaluator.cxx @@ -799,70 +799,51 @@ static const char* targetPropertyTransitiveWhitelist[] = { #undef TRANSITIVE_PROPERTY_NAME +template <typename T> std::string getLinkedTargetsContent( - std::vector<cmTarget const*> &targets, + std::vector<T> const &libraries, cmTarget const* target, cmTarget const* headTarget, cmGeneratorExpressionContext *context, cmGeneratorExpressionDAGChecker *dagChecker, const std::string &interfacePropertyName) { - cmGeneratorExpression ge(&context->Backtrace); - + std::string linkedTargetsContent; std::string sep; std::string depString; - for (std::vector<cmTarget const*>::const_iterator - it = targets.begin(); - it != targets.end(); ++it) + for (typename std::vector<T>::const_iterator it = libraries.begin(); + it != libraries.end(); ++it) { - if (*it == target) - { - // Broken code can have a target in its own link interface. - // Don't follow such link interface entries so as not to create a - // self-referencing loop. - continue; + // Broken code can have a target in its own link interface. + // Don't follow such link interface entries so as not to create a + // self-referencing loop. + if (it->Target && it->Target != target) + { + depString += + sep + "$<TARGET_PROPERTY:" + + it->Target->GetName() + "," + interfacePropertyName + ">"; + sep = ";"; } - depString += - sep + "$<TARGET_PROPERTY:" + - (*it)->GetName() + "," + interfacePropertyName + ">"; - sep = ";"; } - cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(depString); - std::string linkedTargetsContent = cge->Evaluate(target->GetMakefile(), - context->Config, - context->Quiet, - headTarget, - target, - dagChecker); - if (cge->GetHadContextSensitiveCondition()) + if(!depString.empty()) { - context->HadContextSensitiveCondition = true; - } - return linkedTargetsContent; -} - -std::string -getLinkedTargetsContent( - std::vector<cmLinkImplItem> const &libraries, - cmTarget const* target, - cmTarget const* headTarget, - cmGeneratorExpressionContext *context, - cmGeneratorExpressionDAGChecker *dagChecker, - const std::string &interfacePropertyName) -{ - std::vector<cmTarget const*> tgts; - for (std::vector<cmLinkImplItem>::const_iterator - it = libraries.begin(); - it != libraries.end(); ++it) - { - if (it->Target) - { - tgts.push_back(it->Target); + cmGeneratorExpression ge(&context->Backtrace); + cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(depString); + linkedTargetsContent = cge->Evaluate(target->GetMakefile(), + context->Config, + context->Quiet, + headTarget, + target, + dagChecker); + if (cge->GetHadContextSensitiveCondition()) + { + context->HadContextSensitiveCondition = true; } } - return getLinkedTargetsContent(tgts, target, headTarget, context, - dagChecker, interfacePropertyName); + linkedTargetsContent = + cmGeneratorExpression::StripEmptyListElements(linkedTargetsContent); + return linkedTargetsContent; } //---------------------------------------------------------------------------- @@ -1058,18 +1039,24 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode CM_FOR_EACH_TRANSITIVE_PROPERTY_METHOD( ASSERT_TRANSITIVE_PROPERTY_METHOD) false); - } #undef ASSERT_TRANSITIVE_PROPERTY_METHOD + } } std::string linkedTargetsContent; std::string interfacePropertyName; + bool isInterfaceProperty = false; #define POPULATE_INTERFACE_PROPERTY_NAME(prop) \ - if (propertyName == #prop || propertyName == "INTERFACE_" #prop) \ + if (propertyName == #prop) \ + { \ + interfacePropertyName = "INTERFACE_" #prop; \ + } \ + else if (propertyName == "INTERFACE_" #prop) \ { \ interfacePropertyName = "INTERFACE_" #prop; \ + isInterfaceProperty = true; \ } \ else @@ -1086,49 +1073,34 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode } } #undef POPULATE_INTERFACE_PROPERTY_NAME - cmTarget const* headTarget = context->HeadTarget ? context->HeadTarget : target; - const char * const *transBegin = - cmArrayBegin(targetPropertyTransitiveWhitelist) + 1; - const char * const *transEnd = - cmArrayEnd(targetPropertyTransitiveWhitelist); - - if (std::find_if(transBegin, transEnd, - cmStrCmp(propertyName)) != transEnd) + if(isInterfaceProperty) { - - std::vector<cmTarget const*> tgts; - target->GetTransitivePropertyTargets(context->Config, - headTarget, tgts); - if (!tgts.empty()) + if(cmTarget::LinkInterfaceLibraries const* iface = + target->GetLinkInterfaceLibraries(context->Config, headTarget, true)) { linkedTargetsContent = - getLinkedTargetsContent(tgts, target, - headTarget, - context, &dagChecker, - interfacePropertyName); + getLinkedTargetsContent(iface->Libraries, target, + headTarget, + context, &dagChecker, + interfacePropertyName); } } - else if (std::find_if(transBegin, transEnd, - cmStrCmp(interfacePropertyName)) != transEnd) + else if(!interfacePropertyName.empty()) { - const cmTarget::LinkImplementation *impl - = target->GetLinkImplementationLibraries(context->Config); - if(impl) + if(cmTarget::LinkImplementationLibraries const* impl = + target->GetLinkImplementationLibraries(context->Config)) { linkedTargetsContent = - getLinkedTargetsContent(impl->Libraries, target, - headTarget, - context, &dagChecker, - interfacePropertyName); + getLinkedTargetsContent(impl->Libraries, target, + headTarget, + context, &dagChecker, + interfacePropertyName); } } - linkedTargetsContent = - cmGeneratorExpression::StripEmptyListElements(linkedTargetsContent); - if (!prop) { if (target->IsImported() @@ -1202,32 +1174,27 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode return propContent ? propContent : ""; } } - for (size_t i = 1; - i < cmArraySize(targetPropertyTransitiveWhitelist); - ++i) + if(!interfacePropertyName.empty()) { - if (targetPropertyTransitiveWhitelist[i] == interfacePropertyName) - { - cmGeneratorExpression ge(&context->Backtrace); - cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(prop); - cge->SetEvaluateForBuildsystem(context->EvaluateForBuildsystem); - std::string result = cge->Evaluate(context->Makefile, + cmGeneratorExpression ge(&context->Backtrace); + cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(prop); + cge->SetEvaluateForBuildsystem(context->EvaluateForBuildsystem); + std::string result = cge->Evaluate(context->Makefile, context->Config, context->Quiet, headTarget, target, &dagChecker); - if (cge->GetHadContextSensitiveCondition()) - { - context->HadContextSensitiveCondition = true; - } - if (!linkedTargetsContent.empty()) - { - result += (result.empty() ? "" : ";") + linkedTargetsContent; - } - return result; + if (cge->GetHadContextSensitiveCondition()) + { + context->HadContextSensitiveCondition = true; + } + if (!linkedTargetsContent.empty()) + { + result += (result.empty() ? "" : ";") + linkedTargetsContent; } + return result; } return prop; } diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx index 64c5822..f9b68d4 100644 --- a/Source/cmGeneratorTarget.cxx +++ b/Source/cmGeneratorTarget.cxx @@ -445,13 +445,6 @@ bool cmGeneratorTarget::IsSystemIncludeDirectory(const std::string& dir, if (iter == this->SystemIncludesCache.end()) { - cmTarget::LinkImplementation const* impl - = this->Target->GetLinkImplementation(config); - if(!impl) - { - return false; - } - cmGeneratorExpressionDAGChecker dagChecker( this->GetName(), "SYSTEM_INCLUDE_DIRECTORIES", 0, 0); @@ -471,35 +464,15 @@ bool cmGeneratorTarget::IsSystemIncludeDirectory(const std::string& dir, &dagChecker), result); } - std::set<cmTarget const*> uniqueDeps; - for(std::vector<cmLinkImplItem>::const_iterator - li = impl->Libraries.begin(); li != impl->Libraries.end(); ++li) + std::vector<cmTarget const*> const& deps = + this->Target->GetLinkImplementationClosure(config); + for(std::vector<cmTarget const*>::const_iterator + li = deps.begin(), le = deps.end(); li != le; ++li) { - cmTarget const* tgt = li->Target; - if (!tgt) - { - continue; - } - - if (uniqueDeps.insert(tgt).second) - { - handleSystemIncludesDep(this->Makefile, tgt, config, this->Target, - &dagChecker, result, excludeImported); - - std::vector<cmTarget const*> deps; - tgt->GetTransitivePropertyTargets(config, this->Target, deps); - - for(std::vector<cmTarget const*>::const_iterator di = deps.begin(); - di != deps.end(); ++di) - { - if (uniqueDeps.insert(*di).second) - { - handleSystemIncludesDep(this->Makefile, *di, config, this->Target, - &dagChecker, result, excludeImported); - } - } - } + handleSystemIncludesDep(this->Makefile, *li, config, this->Target, + &dagChecker, result, excludeImported); } + std::set<std::string> unique; for(std::vector<std::string>::iterator li = result.begin(); li != result.end(); ++li) diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx index b4688c4..29029eb 100644 --- a/Source/cmTarget.cxx +++ b/Source/cmTarget.cxx @@ -164,6 +164,20 @@ public: typedef std::map<std::string, cmTarget::LinkClosure> LinkClosureMapType; LinkClosureMapType LinkClosureMap; + struct LinkImplClosure: public std::vector<cmTarget const*> + { + LinkImplClosure(): Done(false) {} + bool Done; + }; + std::map<std::string, LinkImplClosure> LinkImplClosureMap; + + struct CompatibleInterfaces: public cmTarget::CompatibleInterfaces + { + CompatibleInterfaces(): Done(false) {} + bool Done; + }; + std::map<std::string, CompatibleInterfaces> CompatibleInterfacesMap; + typedef std::map<std::string, std::vector<cmSourceFile*> > SourceFilesMapType; SourceFilesMapType SourceFilesMap; @@ -203,15 +217,12 @@ public: CachedLinkInterfaceSourcesEntries; std::map<std::string, std::vector<TargetPropertyEntry*> > CachedLinkInterfaceCompileFeaturesEntries; - std::map<std::string, std::vector<cmTarget const*> > - CachedLinkImplementationClosure; std::map<std::string, bool> CacheLinkInterfaceIncludeDirectoriesDone; std::map<std::string, bool> CacheLinkInterfaceCompileDefinitionsDone; std::map<std::string, bool> CacheLinkInterfaceCompileOptionsDone; std::map<std::string, bool> CacheLinkInterfaceSourcesDone; std::map<std::string, bool> CacheLinkInterfaceCompileFeaturesDone; - std::map<std::string, bool> CacheLinkImplementationClosureDone; }; cmLinkImplItem cmTargetInternals::TargetPropertyEntry::NoLinkImplItem; @@ -3555,6 +3566,8 @@ void cmTarget::ExpandLinkItems(std::string const& prop, { cmGeneratorExpression ge; cmGeneratorExpressionDAGChecker dagChecker(this->GetName(), prop, 0, 0); + // The $<LINK_ONLY> expression may be in a link interface to specify private + // link dependencies that are otherwise excluded from usage requirements. if(usage_requirements_only) { dagChecker.SetTransitivePropertiesOnly(); @@ -4377,7 +4390,7 @@ bool cmTarget::HaveBuildTreeRPATH(const std::string& config) const { return false; } - if(LinkImplementation const* impl = + if(LinkImplementationLibraries const* impl = this->GetLinkImplementationLibraries(config)) { return !impl->Libraries.empty(); @@ -5297,44 +5310,6 @@ const char * cmTarget::GetLinkInterfaceDependentNumberMaxProperty( } //---------------------------------------------------------------------------- -bool isLinkDependentProperty(cmTarget const* tgt, const std::string &p, - const std::string& interfaceProperty, - const std::string& config) -{ - std::vector<cmTarget const*> const& deps = - tgt->GetLinkImplementationClosure(config); - - if(deps.empty()) - { - return false; - } - - for(std::vector<cmTarget const*>::const_iterator li = deps.begin(); - li != deps.end(); ++li) - { - const char *prop = (*li)->GetProperty(interfaceProperty); - if (!prop) - { - continue; - } - - std::vector<std::string> props; - cmSystemTools::ExpandListArgument(prop, props); - - for(std::vector<std::string>::iterator pi = props.begin(); - pi != props.end(); ++pi) - { - if (*pi == p) - { - return true; - } - } - } - - return false; -} - -//---------------------------------------------------------------------------- bool cmTarget::IsLinkInterfaceDependentBoolProperty(const std::string &p, const std::string& config) const { @@ -5343,9 +5318,7 @@ bool cmTarget::IsLinkInterfaceDependentBoolProperty(const std::string &p, { return false; } - return (p == "POSITION_INDEPENDENT_CODE") || - isLinkDependentProperty(this, p, "COMPATIBLE_INTERFACE_BOOL", - config); + return this->GetCompatibleInterfaces(config).PropsBool.count(p) > 0; } //---------------------------------------------------------------------------- @@ -5357,9 +5330,7 @@ bool cmTarget::IsLinkInterfaceDependentStringProperty(const std::string &p, { return false; } - return (p == "AUTOUIC_OPTIONS") || - isLinkDependentProperty(this, p, "COMPATIBLE_INTERFACE_STRING", - config); + return this->GetCompatibleInterfaces(config).PropsString.count(p) > 0; } //---------------------------------------------------------------------------- @@ -5371,8 +5342,7 @@ bool cmTarget::IsLinkInterfaceDependentNumberMinProperty(const std::string &p, { return false; } - return isLinkDependentProperty(this, p, "COMPATIBLE_INTERFACE_NUMBER_MIN", - config); + return this->GetCompatibleInterfaces(config).PropsNumberMin.count(p) > 0; } //---------------------------------------------------------------------------- @@ -5384,8 +5354,7 @@ bool cmTarget::IsLinkInterfaceDependentNumberMaxProperty(const std::string &p, { return false; } - return isLinkDependentProperty(this, p, "COMPATIBLE_INTERFACE_NUMBER_MAX", - config); + return this->GetCompatibleInterfaces(config).PropsNumberMax.count(p) > 0; } //---------------------------------------------------------------------------- @@ -5933,7 +5902,7 @@ cmTarget::LinkInterface const* cmTarget::GetLinkInterface( } //---------------------------------------------------------------------------- -cmTarget::LinkInterface const* +cmTarget::LinkInterfaceLibraries const* cmTarget::GetLinkInterfaceLibraries(const std::string& config, cmTarget const* head, bool usage_requirements_only) const @@ -6015,8 +5984,8 @@ void processILibs(const std::string& config, if (item.Target && emitted.insert(item.Target).second) { tgts.push_back(item.Target); - if(cmTarget::LinkInterface const* iface = - item.Target->GetLinkInterfaceLibraries(config, headTarget, false)) + if(cmTarget::LinkInterfaceLibraries const* iface = + item.Target->GetLinkInterfaceLibraries(config, headTarget, true)) { for(std::vector<cmLinkItem>::const_iterator it = iface->Libraries.begin(); @@ -6032,14 +6001,14 @@ void processILibs(const std::string& config, std::vector<cmTarget const*> const& cmTarget::GetLinkImplementationClosure(const std::string& config) const { - std::vector<cmTarget const*>& tgts = - this->Internal->CachedLinkImplementationClosure[config]; - if(!this->Internal->CacheLinkImplementationClosureDone[config]) + cmTargetInternals::LinkImplClosure& tgts = + this->Internal->LinkImplClosureMap[config]; + if(!tgts.Done) { - this->Internal->CacheLinkImplementationClosureDone[config] = true; + tgts.Done = true; std::set<cmTarget const*> emitted; - cmTarget::LinkImplementation const* impl + cmTarget::LinkImplementationLibraries const* impl = this->GetLinkImplementationLibraries(config); for(std::vector<cmLinkImplItem>::const_iterator @@ -6053,32 +6022,37 @@ cmTarget::GetLinkImplementationClosure(const std::string& config) const } //---------------------------------------------------------------------------- -void cmTarget::GetTransitivePropertyTargets(const std::string& config, - cmTarget const* headTarget, - std::vector<cmTarget const*> &tgts) const +cmTarget::CompatibleInterfaces const& +cmTarget::GetCompatibleInterfaces(std::string const& config) const { - // The $<LINK_ONLY> expression may be in a link interface to specify private - // link dependencies that are otherwise excluded from usage requirements. - // Currently $<LINK_ONLY> is internal to CMake and only ever added by - // target_link_libraries for PRIVATE dependencies of STATIC libraries in - // INTERFACE_LINK_LIBRARIES which is used under CMP0022 NEW behavior. - bool usage_requirements_only = - this->GetType() == STATIC_LIBRARY && - this->GetPolicyStatusCMP0022() != cmPolicies::WARN && - this->GetPolicyStatusCMP0022() != cmPolicies::OLD; - if(cmTarget::LinkInterface const* iface = - this->GetLinkInterfaceLibraries(config, headTarget, - usage_requirements_only)) - { - for(std::vector<cmLinkItem>::const_iterator it = iface->Libraries.begin(); - it != iface->Libraries.end(); ++it) - { - if (it->Target) - { - tgts.push_back(it->Target); + cmTargetInternals::CompatibleInterfaces& compat = + this->Internal->CompatibleInterfacesMap[config]; + if(!compat.Done) + { + compat.Done = true; + compat.PropsBool.insert("POSITION_INDEPENDENT_CODE"); + compat.PropsString.insert("AUTOUIC_OPTIONS"); + std::vector<cmTarget const*> const& deps = + this->GetLinkImplementationClosure(config); + for(std::vector<cmTarget const*>::const_iterator li = deps.begin(); + li != deps.end(); ++li) + { +#define CM_READ_COMPATIBLE_INTERFACE(X, x) \ + if(const char* prop = (*li)->GetProperty("COMPATIBLE_INTERFACE_" #X)) \ + { \ + std::vector<std::string> props; \ + cmSystemTools::ExpandListArgument(prop, props); \ + std::copy(props.begin(), props.end(), \ + std::inserter(compat.Props##x, compat.Props##x.begin())); \ } + CM_READ_COMPATIBLE_INTERFACE(BOOL, Bool) + CM_READ_COMPATIBLE_INTERFACE(STRING, String) + CM_READ_COMPATIBLE_INTERFACE(NUMBER_MIN, NumberMin) + CM_READ_COMPATIBLE_INTERFACE(NUMBER_MAX, NumberMax) +#undef CM_READ_COMPATIBLE_INTERFACE } } + return compat; } //---------------------------------------------------------------------------- @@ -6185,7 +6159,7 @@ cmTargetInternals::ComputeLinkInterfaceLibraries( // to the link implementation. { // The link implementation is the default link interface. - cmTarget::LinkImplementation const* impl = + cmTarget::LinkImplementationLibraries const* impl = thisTarget->GetLinkImplementationLibrariesInternal(config, headTarget); std::copy(impl->Libraries.begin(), impl->Libraries.end(), std::back_inserter(iface.Libraries)); @@ -6302,7 +6276,7 @@ void cmTargetInternals::ComputeLinkInterface(cmTarget const* thisTarget, || thisTarget->PolicyStatusCMP0022 == cmPolicies::OLD) { // The link implementation is the default link interface. - cmTarget::LinkImplementation const* + cmTarget::LinkImplementationLibraries const* impl = thisTarget->GetLinkImplementationLibrariesInternal(config, headTarget); iface.ImplementationIsInterface = true; @@ -6353,7 +6327,7 @@ void cmTargetInternals::AddInterfaceEntries( cmTarget const* thisTarget, std::string const& config, std::string const& prop, std::vector<TargetPropertyEntry*>& entries) { - if(cmTarget::LinkImplementation const* impl = + if(cmTarget::LinkImplementationLibraries const* impl = thisTarget->GetLinkImplementationLibraries(config)) { for (std::vector<cmLinkImplItem>::const_iterator @@ -6391,7 +6365,7 @@ cmTarget::GetLinkImplementation(const std::string& config) const if(!impl.LibrariesDone) { impl.LibrariesDone = true; - this->ComputeLinkImplementation(config, impl, this); + this->ComputeLinkImplementationLibraries(config, impl, this); } if(!impl.LanguagesDone) { @@ -6402,14 +6376,14 @@ cmTarget::GetLinkImplementation(const std::string& config) const } //---------------------------------------------------------------------------- -cmTarget::LinkImplementation const* +cmTarget::LinkImplementationLibraries const* cmTarget::GetLinkImplementationLibraries(const std::string& config) const { return this->GetLinkImplementationLibrariesInternal(config, this); } //---------------------------------------------------------------------------- -cmTarget::LinkImplementation const* +cmTarget::LinkImplementationLibraries const* cmTarget::GetLinkImplementationLibrariesInternal(const std::string& config, cmTarget const* head) const { @@ -6426,15 +6400,16 @@ cmTarget::GetLinkImplementationLibrariesInternal(const std::string& config, if(!impl.LibrariesDone) { impl.LibrariesDone = true; - this->ComputeLinkImplementation(config, impl, head); + this->ComputeLinkImplementationLibraries(config, impl, head); } return &impl; } //---------------------------------------------------------------------------- -void cmTarget::ComputeLinkImplementation(const std::string& config, - LinkImplementation& impl, - cmTarget const* head) const +void +cmTarget::ComputeLinkImplementationLibraries(const std::string& config, + LinkImplementation& impl, + cmTarget const* head) const { // Collect libraries directly linked in this configuration. for (std::vector<cmValueWithOrigin>::const_iterator diff --git a/Source/cmTarget.h b/Source/cmTarget.h index 4005443..486315e 100644 --- a/Source/cmTarget.h +++ b/Source/cmTarget.h @@ -262,13 +262,15 @@ public: /** The link interface specifies transitive library dependencies and other information needed by targets that link to this target. */ - struct LinkInterface + struct LinkInterfaceLibraries { - // Languages whose runtime libraries must be linked. - std::vector<std::string> Languages; - // Libraries listed in the interface. std::vector<cmLinkItem> Libraries; + }; + struct LinkInterface: public LinkInterfaceLibraries + { + // Languages whose runtime libraries must be linked. + std::vector<std::string> Languages; // Shared library dependencies needed for linking on some platforms. std::vector<cmLinkItem> SharedDeps; @@ -290,22 +292,28 @@ public: if the target cannot be linked. */ LinkInterface const* GetLinkInterface(const std::string& config, cmTarget const* headTarget) const; - LinkInterface const* GetLinkInterfaceLibraries(const std::string& config, - cmTarget const* headTarget, - bool usage_requirements_only) const; - void GetTransitivePropertyTargets(const std::string& config, - cmTarget const* headTarget, - std::vector<cmTarget const*> &libs) const; + LinkInterfaceLibraries const* + GetLinkInterfaceLibraries(const std::string& config, + cmTarget const* headTarget, + bool usage_requirements_only) const; + std::vector<cmTarget const*> const& GetLinkImplementationClosure(const std::string& config) const; + struct CompatibleInterfaces + { + std::set<std::string> PropsBool; + std::set<std::string> PropsString; + std::set<std::string> PropsNumberMax; + std::set<std::string> PropsNumberMin; + }; + CompatibleInterfaces const& + GetCompatibleInterfaces(std::string const& config) const; + /** The link implementation specifies the direct library dependencies needed by the object files of the target. */ - struct LinkImplementation + struct LinkImplementationLibraries { - // Languages whose runtime libraries must be linked. - std::vector<std::string> Languages; - // Libraries linked directly in this configuration. std::vector<cmLinkImplItem> Libraries; @@ -313,10 +321,15 @@ public: // Needed only for OLD behavior of CMP0003. std::vector<cmLinkItem> WrongConfigLibraries; }; + struct LinkImplementation: public LinkImplementationLibraries + { + // Languages whose runtime libraries must be linked. + std::vector<std::string> Languages; + }; LinkImplementation const* GetLinkImplementation(const std::string& config) const; - LinkImplementation const* + LinkImplementationLibraries const* GetLinkImplementationLibraries(const std::string& config) const; /** Link information from the transitive closure of the link @@ -778,12 +791,12 @@ private: GetImportLinkInterface(const std::string& config, cmTarget const* head, bool usage_requirements_only) const; - LinkImplementation const* + LinkImplementationLibraries const* GetLinkImplementationLibrariesInternal(const std::string& config, cmTarget const* head) const; - void ComputeLinkImplementation(const std::string& config, - LinkImplementation& impl, - cmTarget const* head) const; + void ComputeLinkImplementationLibraries(const std::string& config, + LinkImplementation& impl, + cmTarget const* head) const; void ComputeLinkImplementationLanguages(const std::string& config, LinkImplementation& impl) const; void ComputeLinkClosure(const std::string& config, LinkClosure& lc) const; diff --git a/Tests/CTestTestMemcheck/memtester.cxx.in b/Tests/CTestTestMemcheck/memtester.cxx.in index 55a34e3..43c0ba7 100644 --- a/Tests/CTestTestMemcheck/memtester.cxx.in +++ b/Tests/CTestTestMemcheck/memtester.cxx.in @@ -1,11 +1,19 @@ #include <cmSystemTools.h> +#include <cmsys/Encoding.hxx> #include <string> +#include <locale.h> #define RETVAL @_retval@ int -main(int argc, char **argv) +main(int ac, char **av) { + setlocale(LC_CTYPE, ""); + cmsys::Encoding::CommandLineArguments args = + cmsys::Encoding::CommandLineArguments::Main(ac, av); + int argc = args.argc(); + const char* const* argv = args.argv(); + std::string exename = argv[0]; std::string logarg; bool nextarg = false; diff --git a/Tests/CompatibleInterface/CMakeLists.txt b/Tests/CompatibleInterface/CMakeLists.txt index 350b518..668a97b 100644 --- a/Tests/CompatibleInterface/CMakeLists.txt +++ b/Tests/CompatibleInterface/CMakeLists.txt @@ -1,5 +1,5 @@ -cmake_minimum_required(VERSION 2.8) +cmake_minimum_required(VERSION 3.0) project(CompatibleInterface) @@ -54,6 +54,15 @@ set_property(TARGET iface1 PROPERTY INTERFACE_NUMBER_MAX_PROP2 200) add_executable(CompatibleInterface main.cpp) target_link_libraries(CompatibleInterface iface1) +add_library(foo STATIC foo.cpp) +add_library(bar SHARED bar.cpp) +set_property(TARGET foo APPEND PROPERTY COMPATIBLE_INTERFACE_BOOL SOMEPROP) +set_property(TARGET foo PROPERTY INTERFACE_SOMEPROP ON) +# Use LINK_ONLY to suppress usage requirements and allow the check to pass. +set_property(TARGET bar PROPERTY INTERFACE_LINK_LIBRARIES $<LINK_ONLY:foo>) +set_property(TARGET CompatibleInterface PROPERTY SOMEPROP OFF) +target_link_libraries(CompatibleInterface bar) + set_property(TARGET CompatibleInterface PROPERTY BOOL_PROP2 ON) set_property(TARGET CompatibleInterface PROPERTY BOOL_PROP3 ON) set_property(TARGET CompatibleInterface PROPERTY STRING_PROP2 prop2) diff --git a/Tests/CompatibleInterface/bar.cpp b/Tests/CompatibleInterface/bar.cpp new file mode 100644 index 0000000..2e09900 --- /dev/null +++ b/Tests/CompatibleInterface/bar.cpp @@ -0,0 +1,7 @@ +#ifdef _WIN32 +__declspec(dllexport) +#endif +int bar() +{ + return 0; +} diff --git a/Tests/CompatibleInterface/foo.cpp b/Tests/CompatibleInterface/foo.cpp new file mode 100644 index 0000000..e05eb7e --- /dev/null +++ b/Tests/CompatibleInterface/foo.cpp @@ -0,0 +1,4 @@ +int foo() +{ + return 0; +} diff --git a/Tests/CompatibleInterface/main.cpp b/Tests/CompatibleInterface/main.cpp index e23625a..d20b64b 100644 --- a/Tests/CompatibleInterface/main.cpp +++ b/Tests/CompatibleInterface/main.cpp @@ -40,8 +40,14 @@ enum { #include "iface2.h" +int foo(); +#ifdef _WIN32 +__declspec(dllimport) +#endif +int bar(); + int main(int argc, char **argv) { Iface2 if2; - return if2.foo(); + return if2.foo() + foo() + bar(); } diff --git a/Tests/InterfaceLinkLibraries/CMakeLists.txt b/Tests/InterfaceLinkLibraries/CMakeLists.txt index bd0cf74..9e14c44 100644 --- a/Tests/InterfaceLinkLibraries/CMakeLists.txt +++ b/Tests/InterfaceLinkLibraries/CMakeLists.txt @@ -9,6 +9,9 @@ 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_library(zot_shared SHARED zot_vs6_1.cpp) +target_compile_definitions(zot_shared INTERFACE ZOT_LIBRARY) +set_property(TARGET bar_shared APPEND PROPERTY INTERFACE_LINK_LIBRARIES $<LINK_ONLY:zot_shared>) add_executable(shared_test main_vs6_1.cpp) set_property(TARGET shared_test APPEND PROPERTY LINK_LIBRARIES bar_shared) @@ -18,6 +21,9 @@ 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_library(zot_static STATIC zot_vs6_2.cpp) +target_compile_definitions(zot_static INTERFACE ZOT_LIBRARY) +set_property(TARGET bar_static APPEND PROPERTY INTERFACE_LINK_LIBRARIES $<LINK_ONLY:zot_static>) add_executable(static_test main_vs6_2.cpp) set_property(TARGET static_test APPEND PROPERTY LINK_LIBRARIES bar_static) @@ -31,6 +37,9 @@ 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_library(zot_shared_private SHARED zot_vs6_3.cpp) +target_compile_definitions(zot_shared_private INTERFACE ZOT_LIBRARY) +set_property(TARGET bar_shared_private APPEND PROPERTY INTERFACE_LINK_LIBRARIES $<LINK_ONLY:zot_shared_private>) add_executable(shared_private_test main_vs6_3.cpp) set_property(TARGET shared_private_test APPEND PROPERTY LINK_LIBRARIES bar_shared_private) @@ -44,6 +53,9 @@ 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 $<LINK_ONLY:bang_static_private> foo_static_private) +add_library(zot_static_private STATIC zot_vs6_4.cpp) +target_compile_definitions(zot_static_private INTERFACE ZOT_LIBRARY) +set_property(TARGET bar_static_private APPEND PROPERTY INTERFACE_LINK_LIBRARIES $<LINK_ONLY:zot_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/main.cpp b/Tests/InterfaceLinkLibraries/main.cpp index a54076a..6e1295a 100644 --- a/Tests/InterfaceLinkLibraries/main.cpp +++ b/Tests/InterfaceLinkLibraries/main.cpp @@ -11,9 +11,13 @@ #error Unexpected BANG_LIBRARY #endif -#include "bar.h" +#ifdef ZOT_LIBRARY +#error Unexpected ZOT_LIBRARY +#endif + +#include "zot.h" int main(void) { - return foo() + bar(); + return foo() + bar() + zot(); } diff --git a/Tests/InterfaceLinkLibraries/zot.cpp b/Tests/InterfaceLinkLibraries/zot.cpp new file mode 100644 index 0000000..69462b0 --- /dev/null +++ b/Tests/InterfaceLinkLibraries/zot.cpp @@ -0,0 +1,6 @@ +#include "zot.h" + +int zot() +{ + return 0; +} diff --git a/Tests/InterfaceLinkLibraries/zot.h b/Tests/InterfaceLinkLibraries/zot.h new file mode 100644 index 0000000..5e4fb1e --- /dev/null +++ b/Tests/InterfaceLinkLibraries/zot.h @@ -0,0 +1,7 @@ + +#include "bar.h" + +#ifdef _WIN32 +__declspec(dllexport) +#endif +int zot(); diff --git a/Tests/InterfaceLinkLibraries/zot_vs6_1.cpp b/Tests/InterfaceLinkLibraries/zot_vs6_1.cpp new file mode 100644 index 0000000..c588c5f --- /dev/null +++ b/Tests/InterfaceLinkLibraries/zot_vs6_1.cpp @@ -0,0 +1 @@ +#include "zot.cpp" diff --git a/Tests/InterfaceLinkLibraries/zot_vs6_2.cpp b/Tests/InterfaceLinkLibraries/zot_vs6_2.cpp new file mode 100644 index 0000000..c588c5f --- /dev/null +++ b/Tests/InterfaceLinkLibraries/zot_vs6_2.cpp @@ -0,0 +1 @@ +#include "zot.cpp" diff --git a/Tests/InterfaceLinkLibraries/zot_vs6_3.cpp b/Tests/InterfaceLinkLibraries/zot_vs6_3.cpp new file mode 100644 index 0000000..c588c5f --- /dev/null +++ b/Tests/InterfaceLinkLibraries/zot_vs6_3.cpp @@ -0,0 +1 @@ +#include "zot.cpp" diff --git a/Tests/InterfaceLinkLibraries/zot_vs6_4.cpp b/Tests/InterfaceLinkLibraries/zot_vs6_4.cpp new file mode 100644 index 0000000..c588c5f --- /dev/null +++ b/Tests/InterfaceLinkLibraries/zot_vs6_4.cpp @@ -0,0 +1 @@ +#include "zot.cpp" diff --git a/Utilities/cmcurl/hostip.c b/Utilities/cmcurl/hostip.c index fd555ef..83f1564 100644 --- a/Utilities/cmcurl/hostip.c +++ b/Utilities/cmcurl/hostip.c @@ -609,7 +609,7 @@ Curl_addrinfo *Curl_ip2addr(in_addr_t num, const char *hostname, int port) h = &buf->hostentry; h->h_addr_list = &buf->h_addr_list[0]; addrentry = &buf->addrentry; -#ifdef _CRAYC +#ifdef _CRAY /* On UNICOS, s_addr is a bit field and for some reason assigning to it * doesn't work. There must be a better fix than this ugly hack. */ |