diff options
28 files changed, 559 insertions, 398 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/Modules/DartConfiguration.tcl.in b/Modules/DartConfiguration.tcl.in index 68fadf6..0420882 100644 --- a/Modules/DartConfiguration.tcl.in +++ b/Modules/DartConfiguration.tcl.in @@ -71,6 +71,7 @@ Compiler: @CMAKE_CXX_COMPILER@ PurifyCommand: @PURIFYCOMMAND@ ValgrindCommand: @VALGRIND_COMMAND@ ValgrindCommandOptions: @VALGRIND_COMMAND_OPTIONS@ +MemoryCheckType: @MEMORYCHECK_TYPE@ MemoryCheckCommand: @MEMORYCHECK_COMMAND@ MemoryCheckCommandOptions: @MEMORYCHECK_COMMAND_OPTIONS@ MemoryCheckSuppressionFile: @MEMORYCHECK_SUPPRESSIONS_FILE@ diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake index 9a1bcdd..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 20140715) +set(CMake_VERSION_PATCH 20140718) #set(CMake_VERSION_RC 1) diff --git a/Source/CTest/cmCTestMemCheckHandler.cxx b/Source/CTest/cmCTestMemCheckHandler.cxx index bcf09ad..ed57949 100644 --- a/Source/CTest/cmCTestMemCheckHandler.cxx +++ b/Source/CTest/cmCTestMemCheckHandler.cxx @@ -45,11 +45,23 @@ static CatToErrorType cmCTestMemCheckBoundsChecker[] = { {0,0} }; +static void xmlReportError(int line, const char* msg, void* data) +{ + cmCTest* ctest = (cmCTest*)data; + cmCTestLog(ctest, ERROR_MESSAGE, + "Error parsing XML in stream at line " + << line << ": " << msg << std::endl); +} + // parse the xml file containing the results of last BoundsChecker run class cmBoundsCheckerParser : public cmXMLParser { public: - cmBoundsCheckerParser(cmCTest* c) { this->CTest = c;} + cmBoundsCheckerParser(cmCTest* c) + { + this->CTest = c; + this->SetErrorCallback(xmlReportError, (void*)c); + } void StartElement(const std::string& name, const char** atts) { if(name == "MemoryLeak" || @@ -334,8 +346,8 @@ void cmCTestMemCheckHandler::PopulateCustomVectors(cmMakefile *mf) this->CTest->PopulateCustomVector(mf, "CTEST_CUSTOM_MEMCHECK_IGNORE", this->CustomTestsIgnore); - this->CTest->SetCTestConfigurationFromCMakeVariable( - mf, "CMakeCommand", "CMAKE_COMMAND"); + std::string cmake = cmSystemTools::GetCMakeCommand(); + this->CTest->SetCTestConfiguration("CMakeCommand", cmake.c_str()); } //---------------------------------------------------------------------- @@ -361,6 +373,9 @@ void cmCTestMemCheckHandler::GenerateDartOutput(std::ostream& os) case cmCTestMemCheckHandler::THREAD_SANITIZER: os << "ThreadSanitizer"; break; + case cmCTestMemCheckHandler::ADDRESS_SANITIZER: + os << "AddressSanitizer"; + break; default: os << "Unknown"; } @@ -529,6 +544,14 @@ bool cmCTestMemCheckHandler::InitializeMemoryChecking() this->MemoryTesterStyle = cmCTestMemCheckHandler::THREAD_SANITIZER; this->LogWithPID = true; // even if we give the log file the pid is added } + if ( this->CTest->GetCTestConfiguration("MemoryCheckType") + == "AddressSanitizer") + { + this->MemoryTester + = this->CTest->GetCTestConfiguration("CMakeCommand").c_str(); + this->MemoryTesterStyle = cmCTestMemCheckHandler::ADDRESS_SANITIZER; + this->LogWithPID = true; // even if we give the log file the pid is added + } // Check the MemoryCheckType if(this->MemoryTesterStyle == cmCTestMemCheckHandler::UNKNOWN) { @@ -651,6 +674,9 @@ bool cmCTestMemCheckHandler::InitializeMemoryChecking() this->MemoryTesterOptions.push_back("/M"); break; } + // these two are almost the same but the env var used + // is different + case cmCTestMemCheckHandler::ADDRESS_SANITIZER: case cmCTestMemCheckHandler::THREAD_SANITIZER: { // To pass arguments to ThreadSanitizer the environment variable @@ -660,9 +686,16 @@ bool cmCTestMemCheckHandler::InitializeMemoryChecking() // TSAN_OPTIONS string with the log_path in it. this->MemoryTesterDynamicOptions.push_back("-E"); this->MemoryTesterDynamicOptions.push_back("env"); - std::string outputFile = "TSAN_OPTIONS=log_path=\"" + std::string envVar = "TSAN_OPTIONS"; + std::string extraOptions; + if(this->MemoryTesterStyle == cmCTestMemCheckHandler::ADDRESS_SANITIZER) + { + envVar = "ASAN_OPTIONS"; + extraOptions = " detect_leaks=1"; + } + std::string outputFile = envVar + "=log_path=\"" + this->MemoryTesterOutputFile + "\""; - this->MemoryTesterEnvironmentVariable = outputFile; + this->MemoryTesterEnvironmentVariable = outputFile + extraOptions; break; } default: @@ -695,9 +728,11 @@ ProcessMemCheckOutput(const std::string& str, return this->ProcessMemCheckPurifyOutput(str, log, results); } else if ( this->MemoryTesterStyle == - cmCTestMemCheckHandler::THREAD_SANITIZER ) + cmCTestMemCheckHandler::THREAD_SANITIZER || + this->MemoryTesterStyle == + cmCTestMemCheckHandler::ADDRESS_SANITIZER) { - return this->ProcessMemCheckThreadSanitizerOutput(str, log, results); + return this->ProcessMemCheckSanitizerOutput(str, log, results); } else if ( this->MemoryTesterStyle == cmCTestMemCheckHandler::BOUNDS_CHECKER ) @@ -730,12 +765,21 @@ std::vector<int>::size_type cmCTestMemCheckHandler::FindOrAddWarning( return this->ResultStrings.size()-1; } //---------------------------------------------------------------------- -bool cmCTestMemCheckHandler::ProcessMemCheckThreadSanitizerOutput( +bool cmCTestMemCheckHandler::ProcessMemCheckSanitizerOutput( const std::string& str, std::string& log, std::vector<int>& result) { - cmsys::RegularExpression - sanitizerWarning("WARNING: ThreadSanitizer: (.*) \\(pid=.*\\)"); + std::string regex; + if(this->MemoryTesterStyle == cmCTestMemCheckHandler::THREAD_SANITIZER) + { + regex = "WARNING: ThreadSanitizer: (.*) \\(pid=.*\\)"; + } + else + { + regex = "ERROR: AddressSanitizer: (.*) on.*"; + } + cmsys::RegularExpression sanitizerWarning(regex); + cmsys::RegularExpression leakWarning("(Direct|Indirect) leak of .*"); int defects = 0; std::vector<std::string> lines; cmSystemTools::Split(str.c_str(), lines); @@ -744,10 +788,18 @@ bool cmCTestMemCheckHandler::ProcessMemCheckThreadSanitizerOutput( for( std::vector<std::string>::iterator i = lines.begin(); i != lines.end(); ++i) { - if(sanitizerWarning.find(*i)) + std::string resultFound; + if(leakWarning.find(*i)) + { + resultFound = leakWarning.match(1)+" leak"; + } + else if (sanitizerWarning.find(*i)) + { + resultFound = sanitizerWarning.match(1); + } + if(resultFound.size()) { - std::string warning = sanitizerWarning.match(1); - std::vector<int>::size_type idx = this->FindOrAddWarning(warning); + std::vector<int>::size_type idx = this->FindOrAddWarning(resultFound); if(result.size() == 0 || idx > result.size()-1) { result.push_back(1); diff --git a/Source/CTest/cmCTestMemCheckHandler.h b/Source/CTest/cmCTestMemCheckHandler.h index ffe57f6..2630fde 100644 --- a/Source/CTest/cmCTestMemCheckHandler.h +++ b/Source/CTest/cmCTestMemCheckHandler.h @@ -50,7 +50,8 @@ private: PURIFY, BOUNDS_CHECKER, // checkers after hear do not use the standard error list - THREAD_SANITIZER + THREAD_SANITIZER, + ADDRESS_SANITIZER }; public: enum { // Memory faults @@ -132,9 +133,9 @@ private: bool ProcessMemCheckPurifyOutput(const std::string& str, std::string& log, std::vector<int>& results); - bool ProcessMemCheckThreadSanitizerOutput(const std::string& str, - std::string& log, - std::vector<int>& results); + bool ProcessMemCheckSanitizerOutput(const std::string& str, + std::string& log, + std::vector<int>& results); bool ProcessMemCheckBoundsCheckerOutput(const std::string& str, std::string& log, std::vector<int>& results); 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 aaae457..29029eb 100644 --- a/Source/cmTarget.cxx +++ b/Source/cmTarget.cxx @@ -112,16 +112,22 @@ public: struct OptionalLinkInterface: public cmTarget::LinkInterface { OptionalLinkInterface(): - Exists(false), Complete(false), ExplicitLibraries(0) {} + LibrariesDone(false), AllDone(false), + Exists(false), ExplicitLibraries(0) {} + bool LibrariesDone; + bool AllDone; bool Exists; - bool Complete; const char* ExplicitLibraries; }; void ComputeLinkInterface(cmTarget const* thisTarget, const std::string& config, OptionalLinkInterface& iface, - cmTarget const* head, - const char *explicitLibraries) const; + cmTarget const* head) const; + void ComputeLinkInterfaceLibraries(cmTarget const* thisTarget, + const std::string& config, + OptionalLinkInterface& iface, + cmTarget const* head, + bool usage_requirements_only); typedef std::map<TargetConfigPair, OptionalLinkInterface> LinkInterfaceMapType; @@ -129,7 +135,7 @@ public: LinkInterfaceMapType LinkInterfaceUsageRequirementsOnlyMap; bool PolicyWarnedCMP0022; - typedef std::map<TargetConfigPair, cmTarget::LinkInterface> + typedef std::map<TargetConfigPair, OptionalLinkInterface> ImportLinkInterfaceMapType; ImportLinkInterfaceMapType ImportLinkInterfaceMap; ImportLinkInterfaceMapType ImportLinkInterfaceUsageRequirementsOnlyMap; @@ -158,8 +164,22 @@ public: typedef std::map<std::string, cmTarget::LinkClosure> LinkClosureMapType; LinkClosureMapType LinkClosureMap; - typedef std::map<TargetConfigPair, std::vector<cmSourceFile*> > - SourceFilesMapType; + 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; std::set<cmLinkItem> UtilityItems; @@ -197,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; @@ -631,7 +648,6 @@ static bool processSources(cmTarget const* tgt, std::vector<std::string> &srcs, std::set<std::string> &uniqueSrcs, cmGeneratorExpressionDAGChecker *dagChecker, - cmTarget const* head, std::string const& config, bool debugSources) { cmMakefile *mf = tgt->GetMakefile(); @@ -648,7 +664,7 @@ static bool processSources(cmTarget const* tgt, cmSystemTools::ExpandListArgument((*it)->ge->Evaluate(mf, config, false, - head ? head : tgt, + tgt, tgt, dagChecker), entrySources); @@ -714,8 +730,7 @@ static bool processSources(cmTarget const* tgt, //---------------------------------------------------------------------------- void cmTarget::GetSourceFiles(std::vector<std::string> &files, - const std::string& config, - cmTarget const* head) const + const std::string& config) const { assert(this->GetType() != INTERFACE_LIBRARY); @@ -779,7 +794,6 @@ void cmTarget::GetSourceFiles(std::vector<std::string> &files, files, uniqueSrcs, &dagChecker, - head, config, debugSources); @@ -796,7 +810,6 @@ void cmTarget::GetSourceFiles(std::vector<std::string> &files, files, uniqueSrcs, &dagChecker, - head, config, debugSources); @@ -875,12 +888,11 @@ cmTarget::GetConfigCommonSourceFiles(std::vector<cmSourceFile*>& files) const //---------------------------------------------------------------------------- void cmTarget::GetSourceFiles(std::vector<cmSourceFile*> &files, - const std::string& config, - cmTarget const* head) const + const std::string& config) const { // Lookup any existing link implementation for this configuration. - TargetConfigPair key(head, cmSystemTools::UpperCase(config)); + std::string key = cmSystemTools::UpperCase(config); if(!this->LinkImplementationLanguageIsContextDependent) { @@ -897,7 +909,7 @@ void cmTarget::GetSourceFiles(std::vector<cmSourceFile*> &files, else { std::vector<std::string> srcs; - this->GetSourceFiles(srcs, config, head); + this->GetSourceFiles(srcs, config); std::set<cmSourceFile*> emitted; @@ -3554,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(); @@ -4376,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(); @@ -5296,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 { @@ -5342,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; } //---------------------------------------------------------------------------- @@ -5356,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; } //---------------------------------------------------------------------------- @@ -5370,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; } //---------------------------------------------------------------------------- @@ -5383,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; } //---------------------------------------------------------------------------- @@ -5430,11 +5400,10 @@ cmTarget::GetObjectLibrariesCMP0026(std::vector<cmTarget*>& objlibs) const //---------------------------------------------------------------------------- void cmTarget::GetLanguages(std::set<std::string>& languages, - const std::string& config, - cmTarget const* head) const + const std::string& config) const { std::vector<cmSourceFile*> sourceFiles; - this->GetSourceFiles(sourceFiles, config, head); + this->GetSourceFiles(sourceFiles, config); for(std::vector<cmSourceFile*>::const_iterator i = sourceFiles.begin(); i != sourceFiles.end(); ++i) { @@ -5470,7 +5439,7 @@ void cmTarget::GetLanguages(std::set<std::string>& languages, for(std::vector<cmTarget*>::const_iterator i = objectLibraries.begin(); i != objectLibraries.end(); ++i) { - (*i)->GetLanguages(languages, config, head); + (*i)->GetLanguages(languages, config); } } @@ -5912,36 +5881,28 @@ cmTarget::LinkInterface const* cmTarget::GetLinkInterface( // Lookup any existing link interface for this configuration. TargetConfigPair key(head, cmSystemTools::UpperCase(config)); - cmTargetInternals::LinkInterfaceMapType::iterator - i = this->Internal->LinkInterfaceMap.find(key); - if(i == this->Internal->LinkInterfaceMap.end()) + cmTargetInternals::OptionalLinkInterface& + iface = this->Internal->LinkInterfaceMap[key]; + if(!iface.LibrariesDone) { - // Compute the link interface for this configuration. - cmTargetInternals::OptionalLinkInterface iface; - iface.ExplicitLibraries = - this->ComputeLinkInterfaceLibraries(config, iface, head, false, - iface.Exists); - if (iface.Exists) - { - this->Internal->ComputeLinkInterface(this, config, iface, - head, iface.ExplicitLibraries); - } - - // Store the information for this configuration. - cmTargetInternals::LinkInterfaceMapType::value_type entry(key, iface); - i = this->Internal->LinkInterfaceMap.insert(entry).first; + iface.LibrariesDone = true; + this->Internal->ComputeLinkInterfaceLibraries( + this, config, iface, head, false); } - else if(!i->second.Complete && i->second.Exists) + if(!iface.AllDone) { - this->Internal->ComputeLinkInterface(this, config, i->second, head, - i->second.ExplicitLibraries); + iface.AllDone = true; + if(iface.Exists) + { + this->Internal->ComputeLinkInterface(this, config, iface, head); + } } - return i->second.Exists ? &i->second : 0; + return iface.Exists? &iface : 0; } //---------------------------------------------------------------------------- -cmTarget::LinkInterface const* +cmTarget::LinkInterfaceLibraries const* cmTarget::GetLinkInterfaceLibraries(const std::string& config, cmTarget const* head, bool usage_requirements_only) const @@ -5967,22 +5928,15 @@ cmTarget::GetLinkInterfaceLibraries(const std::string& config, this->Internal->LinkInterfaceUsageRequirementsOnlyMap : this->Internal->LinkInterfaceMap); - cmTargetInternals::LinkInterfaceMapType::iterator i = lim.find(key); - if(i == lim.end()) + cmTargetInternals::OptionalLinkInterface& iface = lim[key]; + if(!iface.LibrariesDone) { - // Compute the link interface for this configuration. - cmTargetInternals::OptionalLinkInterface iface; - iface.ExplicitLibraries = - this->ComputeLinkInterfaceLibraries(config, iface, head, - usage_requirements_only, - iface.Exists); - - // Store the information for this configuration. - cmTargetInternals::LinkInterfaceMapType::value_type entry(key, iface); - i = lim.insert(entry).first; + iface.LibrariesDone = true; + this->Internal->ComputeLinkInterfaceLibraries( + this, config, iface, head, usage_requirements_only); } - return i->second.Exists ? &i->second : 0; + return iface.Exists? &iface : 0; } //---------------------------------------------------------------------------- @@ -6003,26 +5957,21 @@ cmTarget::GetImportLinkInterface(const std::string& config, this->Internal->ImportLinkInterfaceUsageRequirementsOnlyMap : this->Internal->ImportLinkInterfaceMap); - cmTargetInternals::ImportLinkInterfaceMapType::iterator i = lim.find(key); - if(i == lim.end()) + cmTargetInternals::OptionalLinkInterface& iface = lim[key]; + if(!iface.AllDone) { - LinkInterface iface; + iface.AllDone = true; iface.Multiplicity = info->Multiplicity; cmSystemTools::ExpandListArgument(info->Languages, iface.Languages); this->ExpandLinkItems(info->LibrariesProp, info->Libraries, config, headTarget, usage_requirements_only, iface.Libraries); - { std::vector<std::string> deps; cmSystemTools::ExpandListArgument(info->SharedDeps, deps); this->LookupLinkItems(deps, iface.SharedDeps); } - cmTargetInternals::ImportLinkInterfaceMapType::value_type - entry(key, iface); - i = lim.insert(entry).first; - } - return &i->second; + return &iface; } //---------------------------------------------------------------------------- @@ -6035,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(); @@ -6052,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 @@ -6073,40 +6022,47 @@ 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; } //---------------------------------------------------------------------------- -const char* cmTarget::ComputeLinkInterfaceLibraries(const std::string& config, - LinkInterface& iface, - cmTarget const* headTarget, - bool usage_requirements_only, - bool &exists) const +void +cmTargetInternals::ComputeLinkInterfaceLibraries( + cmTarget const* thisTarget, + const std::string& config, + OptionalLinkInterface& iface, + cmTarget const* headTarget, + bool usage_requirements_only) { // Construct the property name suffix for this configuration. std::string suffix = "_"; @@ -6123,15 +6079,15 @@ const char* cmTarget::ComputeLinkInterfaceLibraries(const std::string& config, // libraries and executables that export symbols. const char* explicitLibraries = 0; std::string linkIfaceProp; - if(this->PolicyStatusCMP0022 != cmPolicies::OLD && - this->PolicyStatusCMP0022 != cmPolicies::WARN) + if(thisTarget->PolicyStatusCMP0022 != cmPolicies::OLD && + thisTarget->PolicyStatusCMP0022 != cmPolicies::WARN) { // CMP0022 NEW behavior is to use INTERFACE_LINK_LIBRARIES. linkIfaceProp = "INTERFACE_LINK_LIBRARIES"; - explicitLibraries = this->GetProperty(linkIfaceProp); + explicitLibraries = thisTarget->GetProperty(linkIfaceProp); } - else if(this->GetType() == cmTarget::SHARED_LIBRARY || - this->IsExecutableWithExports()) + else if(thisTarget->GetType() == cmTarget::SHARED_LIBRARY || + thisTarget->IsExecutableWithExports()) { // CMP0022 OLD behavior is to use LINK_INTERFACE_LIBRARIES if set on a // shared lib or executable. @@ -6139,31 +6095,32 @@ const char* cmTarget::ComputeLinkInterfaceLibraries(const std::string& config, // Lookup the per-configuration property. linkIfaceProp = "LINK_INTERFACE_LIBRARIES"; linkIfaceProp += suffix; - explicitLibraries = this->GetProperty(linkIfaceProp); + explicitLibraries = thisTarget->GetProperty(linkIfaceProp); // If not set, try the generic property. if(!explicitLibraries) { linkIfaceProp = "LINK_INTERFACE_LIBRARIES"; - explicitLibraries = this->GetProperty(linkIfaceProp); + explicitLibraries = thisTarget->GetProperty(linkIfaceProp); } } - if(explicitLibraries && this->PolicyStatusCMP0022 == cmPolicies::WARN && - !this->Internal->PolicyWarnedCMP0022) + if(explicitLibraries && + thisTarget->PolicyStatusCMP0022 == cmPolicies::WARN && + !this->PolicyWarnedCMP0022) { // Compare the explicitly set old link interface properties to the // preferred new link interface property one and warn if different. const char* newExplicitLibraries = - this->GetProperty("INTERFACE_LINK_LIBRARIES"); + thisTarget->GetProperty("INTERFACE_LINK_LIBRARIES"); if (newExplicitLibraries && strcmp(newExplicitLibraries, explicitLibraries) != 0) { cmOStringStream w; w << - (this->Makefile->GetPolicies() + (thisTarget->Makefile->GetPolicies() ->GetPolicyWarning(cmPolicies::CMP0022)) << "\n" - "Target \"" << this->GetName() << "\" has an " + "Target \"" << thisTarget->GetName() << "\" has an " "INTERFACE_LINK_LIBRARIES property which differs from its " << linkIfaceProp << " properties." "\n" @@ -6171,53 +6128,53 @@ const char* cmTarget::ComputeLinkInterfaceLibraries(const std::string& config, " " << newExplicitLibraries << "\n" << linkIfaceProp << ":\n" " " << (explicitLibraries ? explicitLibraries : "(empty)") << "\n"; - this->Makefile->IssueMessage(cmake::AUTHOR_WARNING, w.str()); - this->Internal->PolicyWarnedCMP0022 = true; + thisTarget->Makefile->IssueMessage(cmake::AUTHOR_WARNING, w.str()); + this->PolicyWarnedCMP0022 = true; } } // There is no implicit link interface for executables or modules // so if none was explicitly set then there is no link interface. if(!explicitLibraries && - (this->GetType() == cmTarget::EXECUTABLE || - (this->GetType() == cmTarget::MODULE_LIBRARY))) + (thisTarget->GetType() == cmTarget::EXECUTABLE || + (thisTarget->GetType() == cmTarget::MODULE_LIBRARY))) { - exists = false; - return 0; + return; } - exists = true; + iface.Exists = true; + iface.ExplicitLibraries = explicitLibraries; if(explicitLibraries) { // The interface libraries have been explicitly set. - this->ExpandLinkItems(linkIfaceProp, explicitLibraries, config, - headTarget, usage_requirements_only, - iface.Libraries); + thisTarget->ExpandLinkItems(linkIfaceProp, explicitLibraries, config, + headTarget, usage_requirements_only, + iface.Libraries); } - else if (this->PolicyStatusCMP0022 == cmPolicies::WARN - || this->PolicyStatusCMP0022 == cmPolicies::OLD) + else if (thisTarget->PolicyStatusCMP0022 == cmPolicies::WARN + || thisTarget->PolicyStatusCMP0022 == cmPolicies::OLD) // If CMP0022 is NEW then the plain tll signature sets the // INTERFACE_LINK_LIBRARIES, so if we get here then the project // cleared the property explicitly and we should not fall back // to the link implementation. { // The link implementation is the default link interface. - LinkImplementation const* impl = - this->GetLinkImplementationLibrariesInternal(config, headTarget); + cmTarget::LinkImplementationLibraries const* impl = + thisTarget->GetLinkImplementationLibrariesInternal(config, headTarget); std::copy(impl->Libraries.begin(), impl->Libraries.end(), std::back_inserter(iface.Libraries)); - if(this->PolicyStatusCMP0022 == cmPolicies::WARN && - !this->Internal->PolicyWarnedCMP0022 && !usage_requirements_only) + if(thisTarget->PolicyStatusCMP0022 == cmPolicies::WARN && + !this->PolicyWarnedCMP0022 && !usage_requirements_only) { // Compare the link implementation fallback link interface to the // preferred new link interface property and warn if different. std::vector<cmLinkItem> ifaceLibs; std::string newProp = "INTERFACE_LINK_LIBRARIES"; - if(const char* newExplicitLibraries = this->GetProperty(newProp)) + if(const char* newExplicitLibraries = thisTarget->GetProperty(newProp)) { - this->ExpandLinkItems(newProp, newExplicitLibraries, config, - headTarget, usage_requirements_only, - ifaceLibs); + thisTarget->ExpandLinkItems(newProp, newExplicitLibraries, config, + headTarget, usage_requirements_only, + ifaceLibs); } if (ifaceLibs != iface.Libraries) { @@ -6246,9 +6203,9 @@ const char* cmTarget::ComputeLinkInterfaceLibraries(const std::string& config, cmOStringStream w; w << - (this->Makefile->GetPolicies() + (thisTarget->Makefile->GetPolicies() ->GetPolicyWarning(cmPolicies::CMP0022)) << "\n" - "Target \"" << this->GetName() << "\" has an " + "Target \"" << thisTarget->GetName() << "\" has an " "INTERFACE_LINK_LIBRARIES property. " "This should be preferred as the source of the link interface " "for this library but because CMP0022 is not set CMake is " @@ -6259,22 +6216,20 @@ const char* cmTarget::ComputeLinkInterfaceLibraries(const std::string& config, " " << newLibraries << "\n" "Link implementation:\n" " " << oldLibraries << "\n"; - this->Makefile->IssueMessage(cmake::AUTHOR_WARNING, w.str()); - this->Internal->PolicyWarnedCMP0022 = true; + thisTarget->Makefile->IssueMessage(cmake::AUTHOR_WARNING, w.str()); + this->PolicyWarnedCMP0022 = true; } } } - return explicitLibraries; } //---------------------------------------------------------------------------- void cmTargetInternals::ComputeLinkInterface(cmTarget const* thisTarget, const std::string& config, OptionalLinkInterface& iface, - cmTarget const* headTarget, - const char* explicitLibraries) const + cmTarget const* headTarget) const { - if(explicitLibraries) + if(iface.ExplicitLibraries) { if(thisTarget->GetType() == cmTarget::SHARED_LIBRARY || thisTarget->GetType() == cmTarget::STATIC_LIBRARY @@ -6321,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; @@ -6365,7 +6320,6 @@ void cmTargetInternals::ComputeLinkInterface(cmTarget const* thisTarget, sscanf(reps, "%u", &iface.Multiplicity); } } - iface.Complete = true; } //---------------------------------------------------------------------------- @@ -6373,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 @@ -6411,25 +6365,25 @@ 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) { impl.LanguagesDone = true; - this->ComputeLinkImplementationLanguages(config, impl, this); + this->ComputeLinkImplementationLanguages(config, impl); } return &impl; } //---------------------------------------------------------------------------- -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 { @@ -6446,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 @@ -6557,13 +6512,12 @@ void cmTarget::ComputeLinkImplementation(const std::string& config, //---------------------------------------------------------------------------- void cmTarget::ComputeLinkImplementationLanguages(const std::string& config, - LinkImplementation& impl, - cmTarget const* head) const + LinkImplementation& impl) const { // This target needs runtime libraries for its source languages. std::set<std::string> languages; // Get languages used in our source files. - this->GetLanguages(languages, config, head); + this->GetLanguages(languages, config); // Copy the set of langauges to the link implementation. for(std::set<std::string>::iterator li = languages.begin(); li != languages.end(); ++li) diff --git a/Source/cmTarget.h b/Source/cmTarget.h index c2efb14..486315e 100644 --- a/Source/cmTarget.h +++ b/Source/cmTarget.h @@ -161,8 +161,7 @@ public: * Get the list of the source files used by this target */ void GetSourceFiles(std::vector<cmSourceFile*> &files, - const std::string& config, - cmTarget const* head = 0) const; + const std::string& config) const; bool GetConfigCommonSourceFiles(std::vector<cmSourceFile*>& files) const; /** @@ -263,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; @@ -291,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; @@ -314,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 @@ -489,8 +501,7 @@ public: // information to forward these property changes to the targets // until we have per-target object file properties. void GetLanguages(std::set<std::string>& languages, - std::string const& config, - cmTarget const* head = 0) const; + std::string const& config) const; /** Return whether this target is an executable with symbol exports enabled. */ @@ -717,8 +728,7 @@ private: bool contentOnly) const; void GetSourceFiles(std::vector<std::string> &files, - const std::string& config, - cmTarget const* head = 0) const; + const std::string& config) const; private: std::string Name; std::vector<cmCustomCommand> PreBuildCommands; @@ -781,21 +791,14 @@ private: GetImportLinkInterface(const std::string& config, cmTarget const* head, bool usage_requirements_only) const; - const char* ComputeLinkInterfaceLibraries(const std::string& config, - LinkInterface& iface, - cmTarget const* head, - bool usage_requirements_only, - bool &exists) 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 ComputeLinkImplementationLanguages(const std::string& config, + 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; void ExpandLinkItems(std::string const& prop, std::string const& value, diff --git a/Source/cmXMLParser.cxx b/Source/cmXMLParser.cxx index a73fd70..391b874 100644 --- a/Source/cmXMLParser.cxx +++ b/Source/cmXMLParser.cxx @@ -20,6 +20,8 @@ cmXMLParser::cmXMLParser() { this->Parser = 0; this->ParseError = 0; + this->ReportCallback = 0; + this->ReportCallbackData = 0; } //---------------------------------------------------------------------------- @@ -233,6 +235,13 @@ void cmXMLParser::ReportXmlParseError() //---------------------------------------------------------------------------- void cmXMLParser::ReportError(int line, int, const char* msg) { - std::cerr << "Error parsing XML in stream at line " - << line << ": " << msg << std::endl; + if(this->ReportCallback) + { + this->ReportCallback(line, msg, this->ReportCallbackData); + } + else + { + std::cerr << "Error parsing XML in stream at line " + << line << ": " << msg << std::endl; + } } diff --git a/Source/cmXMLParser.h b/Source/cmXMLParser.h index 84a5a7d..e72da66 100644 --- a/Source/cmXMLParser.h +++ b/Source/cmXMLParser.h @@ -50,11 +50,18 @@ public: virtual int ParseChunk(const char* inputString, std::string::size_type length); virtual int CleanupParser(); - + typedef void (*ReportFunction)(int, const char*, void*); + void SetErrorCallback(ReportFunction f, void* d) + { + this->ReportCallback = f; + this->ReportCallbackData = d; + } protected: //! This variable is true if there was a parse error while parsing in //chunks. int ParseError; + ReportFunction ReportCallback; + void* ReportCallbackData; //1 Expat parser structure. Exists only during call to Parse(). void* Parser; diff --git a/Tests/CTestTestMemcheck/CMakeLists.txt b/Tests/CTestTestMemcheck/CMakeLists.txt index f470835..d16d432 100644 --- a/Tests/CTestTestMemcheck/CMakeLists.txt +++ b/Tests/CTestTestMemcheck/CMakeLists.txt @@ -113,9 +113,44 @@ set(CMAKELISTS_EXTRA_CODE -P \"${CMAKE_CURRENT_SOURCE_DIR}/testThreadSanitizer.cmake\") ") gen_mc_test_internal(DummyThreadSanitizer "" -DMEMCHECK_TYPE=ThreadSanitizer) +set_tests_properties(CTestTestMemcheckDummyThreadSanitizer PROPERTIES + PASS_REGULAR_EXPRESSION + ".*Memory checking results:.*data race.* - 1.*data race on vptr .ctor/dtor vs virtual call. - 1.*heap-use-after-free - 1.*thread leak - 1.*destroy of a locked mutex - 1.*double lock of a mutex - 1.*unlock of an unlocked mutex .or by a wrong thread. - 1.*read lock of a write locked mutex - 1.*read unlock of a write locked mutex - 1.*signal-unsafe call inside of a signal - 1.*signal handler spoils errno - 1.*lock-order-inversion .potential deadlock. - 1.*") set(CMAKELISTS_EXTRA_CODE ) set(CTEST_EXTRA_CODE) +# add LeakSanitizer test +set(CTEST_EXTRA_CODE +"set(CTEST_MEMORYCHECK_COMMAND_OPTIONS \"report_bugs=1 history_size=5 exitcode=55\") +") + +set(CMAKELISTS_EXTRA_CODE +"add_test(NAME TestSan COMMAND \"${CMAKE_COMMAND}\" +-P \"${CMAKE_CURRENT_SOURCE_DIR}/testLeakSanitizer.cmake\") +") +gen_mc_test_internal(DummyLeakSanitizer "" -DMEMCHECK_TYPE=AddressSanitizer) +set(CMAKELISTS_EXTRA_CODE ) +set(CTEST_EXTRA_CODE) +set_tests_properties(CTestTestMemcheckDummyLeakSanitizer PROPERTIES + PASS_REGULAR_EXPRESSION + ".*Memory checking results:.*Direct leak - 2.*Indirect leak - 1.*") +# add AddressSanitizer test +set(CTEST_EXTRA_CODE +"set(CTEST_MEMORYCHECK_COMMAND_OPTIONS \"report_bugs=1 history_size=5 exitcode=55\") +") + +set(CMAKELISTS_EXTRA_CODE +"add_test(NAME TestSan COMMAND \"${CMAKE_COMMAND}\" +-P \"${CMAKE_CURRENT_SOURCE_DIR}/testAddressSanitizer.cmake\") +") +gen_mc_test_internal(DummyAddressSanitizer "" -DMEMCHECK_TYPE=AddressSanitizer) +set(CMAKELISTS_EXTRA_CODE ) +set(CTEST_EXTRA_CODE) +set_tests_properties(CTestTestMemcheckDummyAddressSanitizer PROPERTIES + PASS_REGULAR_EXPRESSION + ".*Memory checking results:.*heap-buffer-overflow - 1.*") + + gen_mc_test(DummyPurify "\${PSEUDO_PURIFY}") gen_mc_test(DummyValgrind "\${PSEUDO_VALGRIND}") gen_mc_test(DummyBC "\${PSEUDO_BC}") @@ -202,10 +237,6 @@ set_tests_properties(CTestTestMemcheckDummyValgrindTwoTargets PROPERTIES PASS_REGULAR_EXPRESSION "\nMemory check project ${CTEST_ESCAPED_CMAKE_CURRENT_BINARY_DIR}/DummyValgrindTwoTargets\n.*\n *Start 1: RunCMake\n(.*\n)?Memory check command: .* \"--log-file=${CTEST_ESCAPED_CMAKE_CURRENT_BINARY_DIR}/DummyValgrindTwoTargets/Testing/Temporary/MemoryChecker.1.log\" \"-q\".*\n *Start 2: RunCMakeAgain\n(.*\n)?Memory check command: .* \"--log-file=${CTEST_ESCAPED_CMAKE_CURRENT_BINARY_DIR}/DummyValgrindTwoTargets/Testing/Temporary/MemoryChecker.2.log\" \"-q\".*\n") -set_tests_properties(CTestTestMemcheckDummyThreadSanitizer PROPERTIES - PASS_REGULAR_EXPRESSION - ".*Memory checking results:.*data race.* - 1.*data race on vptr .ctor/dtor vs virtual call. - 1.*heap-use-after-free - 1.*thread leak - 1.*destroy of a locked mutex - 1.*double lock of a mutex - 1.*unlock of an unlocked mutex .or by a wrong thread. - 1.*read lock of a write locked mutex - 1.*read unlock of a write locked mutex - 1.*signal-unsafe call inside of a signal - 1.*signal handler spoils errno - 1.*lock-order-inversion .potential deadlock. - 1.*") - # Xcode 2.x forgets to create the output directory before linking # the individual architectures. diff --git a/Tests/CTestTestMemcheck/testAddressSanitizer.cmake b/Tests/CTestTestMemcheck/testAddressSanitizer.cmake new file mode 100644 index 0000000..a359e28 --- /dev/null +++ b/Tests/CTestTestMemcheck/testAddressSanitizer.cmake @@ -0,0 +1,55 @@ +# this file simulates a program that has been built with thread sanitizer +# options + +message("ASAN_OPTIONS = [$ENV{ASAN_OPTIONS}]") +string(REGEX REPLACE ".*log_path=\"([^\"]*)\".*" "\\1" LOG_FILE "$ENV{ASAN_OPTIONS}") +message("LOG_FILE=[${LOG_FILE}]") + +# clear the log file +file(REMOVE "${LOG_FILE}.2343") + +# create an error of each type of thread santizer +# these names come from tsan_report.cc in llvm + +file(APPEND "${LOG_FILE}.2343" +"================================================================= +==19278== ERROR: AddressSanitizer: heap-buffer-overflow on address 0x60080000bffc at pc 0x4009f1 bp 0x7fff82de6520 sp 0x7fff82de6518 +WRITE of size 4 at 0x60080000bffc thread T0 + #0 0x4009f0 (/home/kitware/msan/a.out+0x4009f0) + #1 0x7f18b02c876c (/lib/x86_64-linux-gnu/libc-2.15.so+0x2176c) + #2 0x400858 (/home/kitware/msan/a.out+0x400858) +0x60080000bffc is located 4 bytes to the right of 40-byte region [0x60080000bfd0,0x60080000bff8) +allocated by thread T0 here: + #0 0x7f18b088f9ca (/usr/lib/x86_64-linux-gnu/libasan.so.0.0.0+0x119ca) + #1 0x4009a2 (/home/kitware/msan/a.out+0x4009a2) + #2 0x7f18b02c876c (/lib/x86_64-linux-gnu/libc-2.15.so+0x2176c) +Shadow bytes around the buggy address: + 0x0c017fff97a0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa + 0x0c017fff97b0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa + 0x0c017fff97c0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa + 0x0c017fff97d0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa + 0x0c017fff97e0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa +=>0x0c017fff97f0: fa fa fa fa fa fa fa fa fa fa 00 00 00 00 00[fa] + 0x0c017fff9800:fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa + 0x0c017fff9810: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa + 0x0c017fff9820: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa + 0x0c017fff9830: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa + 0x0c017fff9840: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa +Shadow byte legend (one shadow byte represents 8 application bytes): + Addressable: 00 + Partially addressable: 01 02 03 04 05 06 07 + Heap left redzone: fa + Heap righ redzone: fb + Freed Heap region: fd + Stack left redzone: f1 + Stack mid redzone: f2 + Stack right redzone: f3 + Stack partial redzone: f4 + Stack after return: f5 + Stack use after scope: f8 + Global redzone: f9 + Global init order: f6 + Poisoned by user: f7 + ASan internal: fe +==19278== ABORTING +") diff --git a/Tests/CTestTestMemcheck/testLeakSanitizer.cmake b/Tests/CTestTestMemcheck/testLeakSanitizer.cmake new file mode 100644 index 0000000..ca0a264 --- /dev/null +++ b/Tests/CTestTestMemcheck/testLeakSanitizer.cmake @@ -0,0 +1,36 @@ +# this file simulates a program that has been built with thread sanitizer +# options + +message("ASAN_OPTIONS = [$ENV{ASAN_OPTIONS}]") +string(REGEX REPLACE ".*log_path=\"([^\"]*)\".*" "\\1" LOG_FILE "$ENV{ASAN_OPTIONS}") +message("LOG_FILE=[${LOG_FILE}]") + +# clear the log file +file(REMOVE "${LOG_FILE}.2343") + +# create an error of each type of thread santizer +# these names come from tsan_report.cc in llvm + +file(APPEND "${LOG_FILE}.2343" +"================================================================= +==25308==ERROR: LeakSanitizer: detected memory leaks + +Direct leak of 4360 byte(s) in 1 object(s) allocated from: + #0 0x46c669 in operator new[](unsigned long) (/home/kitware/msan/a.out+0x46c669) + #1 0x4823b4 in main /home/kitware/msan/memcheck.cxx:12 + #2 0x7fa72bee476c in __libc_start_main /build/buildd/eglibc-2.15/csu/libc-start.c:226 + +Direct leak of 76 byte(s) in 1 object(s) allocated from: + #0 0x46c669 in operator new[](unsigned long) (/home/kitware/msan/a.out+0x46c669) + #1 0x4821b8 in foo() /home/kitware/msan/memcheck.cxx:4 + #2 0x4823f2 in main /home/kitware/msan/memcheck.cxx:14 + #3 0x7fa72bee476c in __libc_start_main /build/buildd/eglibc-2.15/csu/libc-start.c:226 + +Indirect leak of 76 byte(s) in 1 object(s) allocated from: + #0 0x46c669 in operator new[](unsigned long) (/home/kitware/msan/a.out+0x46c669) + #1 0x4821b8 in foo() /home/kitware/msan/memcheck.cxx:4 + #2 0x4823f2 in main /home/kitware/msan/memcheck.cxx:14 + #3 0x7fa72bee476c in __libc_start_main /build/buildd/eglibc-2.15/csu/libc-start.c:226 + +SUMMARY: AddressSanitizer: 4436 byte(s) leaked in 2 allocation(s). +") 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. */ |