diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx index 29029eb89..07f08deb9 100644 --- a/Source/cmTarget.cxx +++ b/Source/cmTarget.cxx @@ -25,6 +25,12 @@ #include // required for atof #include #include +#if defined(CMAKE_BUILD_WITH_CMAKE) +#include +#define UNORDERED_SET cmsys::hash_set +#else +#define UNORDERED_SET std::set +#endif const char* cmTarget::GetTargetTypeName(TargetType targetType) { @@ -190,10 +196,11 @@ public: public: TargetPropertyEntry(cmsys::auto_ptr cge, cmLinkImplItem const& item = NoLinkImplItem) - : ge(cge), LinkImplItem(item) + : ge(cge), Cached(false), LinkImplItem(item) {} const cmsys::auto_ptr ge; std::vector CachedEntries; + bool Cached; cmLinkImplItem const& LinkImplItem; }; std::vector IncludeDirectoriesEntries; @@ -228,7 +235,7 @@ public: cmLinkImplItem cmTargetInternals::TargetPropertyEntry::NoLinkImplItem; //---------------------------------------------------------------------------- -void deleteAndClear( +static void deleteAndClear( std::vector &entries) { for (std::vector::const_iterator @@ -242,7 +249,7 @@ void deleteAndClear( } //---------------------------------------------------------------------------- -void deleteAndClear( +static void deleteAndClear( std::map > &entries) { @@ -339,7 +346,7 @@ void cmTarget::SetMakefile(cmMakefile* mf) this->IsApple = this->Makefile->IsOn("APPLE"); // Setup default property values. - if (this->GetType() != INTERFACE_LIBRARY) + if (this->GetType() != INTERFACE_LIBRARY && this->GetType() != UTILITY) { this->SetPropertyDefault("INSTALL_NAME_DIR", 0); this->SetPropertyDefault("INSTALL_RPATH", ""); @@ -380,41 +387,44 @@ void cmTarget::SetMakefile(cmMakefile* mf) mf->GetConfigurations(configNames); // Setup per-configuration property default values. - const char* configProps[] = { - "ARCHIVE_OUTPUT_DIRECTORY_", - "LIBRARY_OUTPUT_DIRECTORY_", - "RUNTIME_OUTPUT_DIRECTORY_", - "PDB_OUTPUT_DIRECTORY_", - "COMPILE_PDB_OUTPUT_DIRECTORY_", - "MAP_IMPORTED_CONFIG_", - 0}; - for(std::vector::iterator ci = configNames.begin(); - ci != configNames.end(); ++ci) + if (this->GetType() != UTILITY) { - std::string configUpper = cmSystemTools::UpperCase(*ci); - for(const char** p = configProps; *p; ++p) + const char* configProps[] = { + "ARCHIVE_OUTPUT_DIRECTORY_", + "LIBRARY_OUTPUT_DIRECTORY_", + "RUNTIME_OUTPUT_DIRECTORY_", + "PDB_OUTPUT_DIRECTORY_", + "COMPILE_PDB_OUTPUT_DIRECTORY_", + "MAP_IMPORTED_CONFIG_", + 0}; + for(std::vector::iterator ci = configNames.begin(); + ci != configNames.end(); ++ci) { - if (this->TargetTypeValue == INTERFACE_LIBRARY - && strcmp(*p, "MAP_IMPORTED_CONFIG_") != 0) + std::string configUpper = cmSystemTools::UpperCase(*ci); + for(const char** p = configProps; *p; ++p) { - continue; + if (this->TargetTypeValue == INTERFACE_LIBRARY + && strcmp(*p, "MAP_IMPORTED_CONFIG_") != 0) + { + continue; + } + std::string property = *p; + property += configUpper; + this->SetPropertyDefault(property, 0); } - std::string property = *p; - property += configUpper; - this->SetPropertyDefault(property, 0); - } - // Initialize per-configuration name postfix property from the - // variable only for non-executable targets. This preserves - // compatibility with previous CMake versions in which executables - // did not support this variable. Projects may still specify the - // property directly. - if(this->TargetTypeValue != cmTarget::EXECUTABLE - && this->TargetTypeValue != cmTarget::INTERFACE_LIBRARY) - { - std::string property = cmSystemTools::UpperCase(*ci); - property += "_POSTFIX"; - this->SetPropertyDefault(property, 0); + // Initialize per-configuration name postfix property from the + // variable only for non-executable targets. This preserves + // compatibility with previous CMake versions in which executables + // did not support this variable. Projects may still specify the + // property directly. + if(this->TargetTypeValue != cmTarget::EXECUTABLE + && this->TargetTypeValue != cmTarget::INTERFACE_LIBRARY) + { + std::string property = cmSystemTools::UpperCase(*ci); + property += "_POSTFIX"; + this->SetPropertyDefault(property, 0); + } } } @@ -453,7 +463,7 @@ void cmTarget::SetMakefile(cmMakefile* mf) } } - if (this->GetType() != INTERFACE_LIBRARY) + if (this->GetType() != INTERFACE_LIBRARY && this->GetType() != UTILITY) { this->SetPropertyDefault("C_VISIBILITY_PRESET", 0); this->SetPropertyDefault("CXX_VISIBILITY_PRESET", 0); @@ -465,7 +475,7 @@ void cmTarget::SetMakefile(cmMakefile* mf) { this->SetProperty("POSITION_INDEPENDENT_CODE", "True"); } - if (this->GetType() != INTERFACE_LIBRARY) + if (this->GetType() != INTERFACE_LIBRARY && this->GetType() != UTILITY) { this->SetPropertyDefault("POSITION_INDEPENDENT_CODE", 0); } @@ -487,8 +497,11 @@ void cmTarget::SetMakefile(cmMakefile* mf) this->PolicyStatusCMP0022 = cmPolicies::NEW; } - this->SetPropertyDefault("JOB_POOL_COMPILE", 0); - this->SetPropertyDefault("JOB_POOL_LINK", 0); + if (this->GetType() != INTERFACE_LIBRARY && this->GetType() != UTILITY) + { + this->SetPropertyDefault("JOB_POOL_COMPILE", 0); + this->SetPropertyDefault("JOB_POOL_LINK", 0); + } } //---------------------------------------------------------------------------- @@ -646,7 +659,7 @@ bool cmTarget::IsBundleOnApple() const static bool processSources(cmTarget const* tgt, const std::vector &entries, std::vector &srcs, - std::set &uniqueSrcs, + UNORDERED_SET &uniqueSrcs, cmGeneratorExpressionDAGChecker *dagChecker, std::string const& config, bool debugSources) { @@ -788,7 +801,7 @@ void cmTarget::GetSourceFiles(std::vector &files, cmGeneratorExpressionDAGChecker dagChecker(this->GetName(), "SOURCES", 0, 0); - std::set uniqueSrcs; + UNORDERED_SET uniqueSrcs; bool contextDependentDirectSources = processSources(this, this->Internal->SourceEntries, files, @@ -1302,7 +1315,7 @@ void cmTarget::GetTllSignatureTraces(cmOStringStream &s, = (sig == cmTarget::KeywordTLLSignature ? "keyword" : "plain"); s << "The uses of the " << sigString << " signature are here:\n"; - std::set emitted; + UNORDERED_SET emitted; for(std::vector::iterator it = sigs.begin(); it != sigs.end(); ++it) { @@ -1721,22 +1734,20 @@ static bool whiteListedInterfaceProperty(const std::string& prop) { return true; } - static const char* builtIns[] = { - // ###: This must remain sorted. It is processed with a binary search. - "COMPATIBLE_INTERFACE_BOOL", - "COMPATIBLE_INTERFACE_NUMBER_MAX", - "COMPATIBLE_INTERFACE_NUMBER_MIN", - "COMPATIBLE_INTERFACE_STRING", - "EXPORT_NAME", - "IMPORTED", - "NAME", - "TYPE" - }; + static UNORDERED_SET builtIns; + if (builtIns.empty()) + { + builtIns.insert("COMPATIBLE_INTERFACE_BOOL"); + builtIns.insert("COMPATIBLE_INTERFACE_NUMBER_MAX"); + builtIns.insert("COMPATIBLE_INTERFACE_NUMBER_MIN"); + builtIns.insert("COMPATIBLE_INTERFACE_STRING"); + builtIns.insert("EXPORT_NAME"); + builtIns.insert("IMPORTED"); + builtIns.insert("NAME"); + builtIns.insert("TYPE"); + } - if (std::binary_search(cmArrayBegin(builtIns), - cmArrayEnd(builtIns), - prop.c_str(), - cmStrCmp(prop))) + if (builtIns.count(prop)) { return true; } @@ -1761,15 +1772,14 @@ void cmTarget::SetProperty(const std::string& prop, const char* value) this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str()); return; } - - if (prop == "NAME") + else if (prop == "NAME") { cmOStringStream e; e << "NAME property is read-only\n"; this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str()); return; } - if(prop == "INCLUDE_DIRECTORIES") + else if(prop == "INCLUDE_DIRECTORIES") { cmListFileBacktrace lfbt = this->Makefile->GetBacktrace(); cmGeneratorExpression ge(&lfbt); @@ -1777,9 +1787,8 @@ void cmTarget::SetProperty(const std::string& prop, const char* value) cmsys::auto_ptr cge = ge.Parse(value); this->Internal->IncludeDirectoriesEntries.push_back( new cmTargetInternals::TargetPropertyEntry(cge)); - return; } - if(prop == "COMPILE_OPTIONS") + else if(prop == "COMPILE_OPTIONS") { cmListFileBacktrace lfbt = this->Makefile->GetBacktrace(); cmGeneratorExpression ge(&lfbt); @@ -1787,9 +1796,8 @@ void cmTarget::SetProperty(const std::string& prop, const char* value) cmsys::auto_ptr cge = ge.Parse(value); this->Internal->CompileOptionsEntries.push_back( new cmTargetInternals::TargetPropertyEntry(cge)); - return; } - if(prop == "COMPILE_FEATURES") + else if(prop == "COMPILE_FEATURES") { cmListFileBacktrace lfbt = this->Makefile->GetBacktrace(); cmGeneratorExpression ge(&lfbt); @@ -1797,9 +1805,8 @@ void cmTarget::SetProperty(const std::string& prop, const char* value) cmsys::auto_ptr cge = ge.Parse(value); this->Internal->CompileFeaturesEntries.push_back( new cmTargetInternals::TargetPropertyEntry(cge)); - return; } - if(prop == "COMPILE_DEFINITIONS") + else if(prop == "COMPILE_DEFINITIONS") { cmListFileBacktrace lfbt = this->Makefile->GetBacktrace(); cmGeneratorExpression ge(&lfbt); @@ -1807,25 +1814,22 @@ void cmTarget::SetProperty(const std::string& prop, const char* value) cmsys::auto_ptr cge = ge.Parse(value); this->Internal->CompileDefinitionsEntries.push_back( new cmTargetInternals::TargetPropertyEntry(cge)); - return; } - if(prop == "EXPORT_NAME" && this->IsImported()) + else if(prop == "EXPORT_NAME" && this->IsImported()) { cmOStringStream e; e << "EXPORT_NAME property can't be set on imported targets (\"" << this->Name << "\")\n"; this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str()); - return; } - if (prop == "LINK_LIBRARIES") + else if (prop == "LINK_LIBRARIES") { this->Internal->LinkImplementationPropertyEntries.clear(); cmListFileBacktrace lfbt = this->Makefile->GetBacktrace(); cmValueWithOrigin entry(value, lfbt); this->Internal->LinkImplementationPropertyEntries.push_back(entry); - return; } - if (prop == "SOURCES") + else if (prop == "SOURCES") { if(this->IsImported()) { @@ -1842,10 +1846,12 @@ void cmTarget::SetProperty(const std::string& prop, const char* value) cmsys::auto_ptr cge = ge.Parse(value); this->Internal->SourceEntries.push_back( new cmTargetInternals::TargetPropertyEntry(cge)); - return; } - this->Properties.SetProperty(prop, value, cmProperty::TARGET); - this->MaybeInvalidatePropertyCache(prop); + else + { + this->Properties.SetProperty(prop, value, cmProperty::TARGET); + this->MaybeInvalidatePropertyCache(prop); + } } //---------------------------------------------------------------------------- @@ -1861,61 +1867,55 @@ void cmTarget::AppendProperty(const std::string& prop, const char* value, this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str()); return; } - if (prop == "NAME") + else if (prop == "NAME") { cmOStringStream e; e << "NAME property is read-only\n"; this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str()); return; } - if(prop == "INCLUDE_DIRECTORIES") + else if(prop == "INCLUDE_DIRECTORIES") { cmListFileBacktrace lfbt = this->Makefile->GetBacktrace(); cmGeneratorExpression ge(&lfbt); this->Internal->IncludeDirectoriesEntries.push_back( new cmTargetInternals::TargetPropertyEntry(ge.Parse(value))); - return; } - if(prop == "COMPILE_OPTIONS") + else if(prop == "COMPILE_OPTIONS") { cmListFileBacktrace lfbt = this->Makefile->GetBacktrace(); cmGeneratorExpression ge(&lfbt); this->Internal->CompileOptionsEntries.push_back( new cmTargetInternals::TargetPropertyEntry(ge.Parse(value))); - return; } - if(prop == "COMPILE_FEATURES") + else if(prop == "COMPILE_FEATURES") { cmListFileBacktrace lfbt = this->Makefile->GetBacktrace(); cmGeneratorExpression ge(&lfbt); this->Internal->CompileFeaturesEntries.push_back( new cmTargetInternals::TargetPropertyEntry(ge.Parse(value))); - return; } - if(prop == "COMPILE_DEFINITIONS") + else if(prop == "COMPILE_DEFINITIONS") { cmListFileBacktrace lfbt = this->Makefile->GetBacktrace(); cmGeneratorExpression ge(&lfbt); this->Internal->CompileDefinitionsEntries.push_back( new cmTargetInternals::TargetPropertyEntry(ge.Parse(value))); - return; } - if(prop == "EXPORT_NAME" && this->IsImported()) + else if(prop == "EXPORT_NAME" && this->IsImported()) { cmOStringStream e; e << "EXPORT_NAME property can't be set on imported targets (\"" << this->Name << "\")\n"; this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str()); - return; } - if (prop == "LINK_LIBRARIES") + else if (prop == "LINK_LIBRARIES") { cmListFileBacktrace lfbt = this->Makefile->GetBacktrace(); cmValueWithOrigin entry(value, lfbt); this->Internal->LinkImplementationPropertyEntries.push_back(entry); - return; } - if (prop == "SOURCES") + else if (prop == "SOURCES") { if(this->IsImported()) { @@ -1931,10 +1931,12 @@ void cmTarget::AppendProperty(const std::string& prop, const char* value, cmsys::auto_ptr cge = ge.Parse(value); this->Internal->SourceEntries.push_back( new cmTargetInternals::TargetPropertyEntry(cge)); - return; } - this->Properties.AppendProperty(prop, value, cmProperty::TARGET, asString); - this->MaybeInvalidatePropertyCache(prop); + else + { + this->Properties.AppendProperty(prop, value, cmProperty::TARGET, asString); + this->MaybeInvalidatePropertyCache(prop); + } } //---------------------------------------------------------------------------- @@ -2030,7 +2032,7 @@ void cmTarget::InsertCompileDefinition(const cmValueWithOrigin &entry) static void processIncludeDirectories(cmTarget const* tgt, const std::vector &entries, std::vector &includes, - std::set &uniqueIncludes, + UNORDERED_SET &uniqueIncludes, cmGeneratorExpressionDAGChecker *dagChecker, const std::string& config, bool debugIncludes) { @@ -2179,7 +2181,7 @@ std::vector cmTarget::GetIncludeDirectories(const std::string& config) const { std::vector includes; - std::set uniqueIncludes; + UNORDERED_SET uniqueIncludes; cmGeneratorExpressionDAGChecker dagChecker(this->GetName(), "INCLUDE_DIRECTORIES", 0, 0); @@ -2271,7 +2273,7 @@ cmTarget::GetIncludeDirectories(const std::string& config) const static void processCompileOptionsInternal(cmTarget const* tgt, const std::vector &entries, std::vector &options, - std::set &uniqueOptions, + UNORDERED_SET &uniqueOptions, cmGeneratorExpressionDAGChecker *dagChecker, const std::string& config, bool debugOptions, const char *logName) { @@ -2280,27 +2282,35 @@ static void processCompileOptionsInternal(cmTarget const* tgt, for (std::vector::const_iterator it = entries.begin(), end = entries.end(); it != end; ++it) { - bool cacheOptions = false; - std::vector entryOptions = (*it)->CachedEntries; - if(entryOptions.empty()) + std::vector& entriesRef = (*it)->CachedEntries; + std::vector localEntries; + std::vector* entryOptions = &entriesRef; + if(!(*it)->Cached) { cmSystemTools::ExpandListArgument((*it)->ge->Evaluate(mf, config, false, tgt, dagChecker), - entryOptions); + localEntries); if (mf->IsGeneratingBuildSystem() && !(*it)->ge->GetHadContextSensitiveCondition()) { - cacheOptions = true; + // Cache the result. + *entryOptions = localEntries; + (*it)->Cached = true; + } + else + { + // Use the context-sensitive results here. + entryOptions = &localEntries; } } std::string usedOptions; for(std::vector::iterator - li = entryOptions.begin(); li != entryOptions.end(); ++li) + li = entryOptions->begin(); li != entryOptions->end(); ++li) { - std::string opt = *li; + std::string const& opt = *li; if(uniqueOptions.insert(opt).second) { @@ -2311,10 +2321,6 @@ static void processCompileOptionsInternal(cmTarget const* tgt, } } } - if (cacheOptions) - { - (*it)->CachedEntries = entryOptions; - } if (!usedOptions.empty()) { mf->GetCMakeInstance()->IssueMessage(cmake::LOG, @@ -2330,7 +2336,7 @@ static void processCompileOptionsInternal(cmTarget const* tgt, static void processCompileOptions(cmTarget const* tgt, const std::vector &entries, std::vector &options, - std::set &uniqueOptions, + UNORDERED_SET &uniqueOptions, cmGeneratorExpressionDAGChecker *dagChecker, const std::string& config, bool debugOptions) { @@ -2367,7 +2373,7 @@ void cmTarget::GetAutoUicOptions(std::vector &result, void cmTarget::GetCompileOptions(std::vector &result, const std::string& config) const { - std::set uniqueOptions; + UNORDERED_SET uniqueOptions; cmGeneratorExpressionDAGChecker dagChecker(this->GetName(), "COMPILE_OPTIONS", 0, 0); @@ -2428,7 +2434,7 @@ void cmTarget::GetCompileOptions(std::vector &result, static void processCompileDefinitions(cmTarget const* tgt, const std::vector &entries, std::vector &options, - std::set &uniqueOptions, + UNORDERED_SET &uniqueOptions, cmGeneratorExpressionDAGChecker *dagChecker, const std::string& config, bool debugOptions) { @@ -2441,7 +2447,7 @@ static void processCompileDefinitions(cmTarget const* tgt, void cmTarget::GetCompileDefinitions(std::vector &list, const std::string& config) const { - std::set uniqueOptions; + UNORDERED_SET uniqueOptions; cmGeneratorExpressionDAGChecker dagChecker(this->GetName(), "COMPILE_DEFINITIONS", 0, 0); @@ -2539,7 +2545,7 @@ void cmTarget::GetCompileDefinitions(std::vector &list, static void processCompileFeatures(cmTarget const* tgt, const std::vector &entries, std::vector &options, - std::set &uniqueOptions, + UNORDERED_SET &uniqueOptions, cmGeneratorExpressionDAGChecker *dagChecker, const std::string& config, bool debugOptions) { @@ -2551,7 +2557,7 @@ static void processCompileFeatures(cmTarget const* tgt, void cmTarget::GetCompileFeatures(std::vector &result, const std::string& config) const { - std::set uniqueFeatures; + UNORDERED_SET uniqueFeatures; cmGeneratorExpressionDAGChecker dagChecker(this->GetName(), "COMPILE_FEATURES", @@ -3013,6 +3019,22 @@ bool cmTarget::HandleLocationPropertyPolicy(cmMakefile* context) const return messageType != cmake::FATAL_ERROR; } +//---------------------------------------------------------------------------- +static void MakePropertyList(std::string& output, + std::vector const& values) +{ + output = ""; + std::string sep; + for (std::vector::const_iterator + it = values.begin(), end = values.end(); + it != end; ++it) + { + output += sep; + output += (*it)->ge->GetInput(); + sep = ";"; + } +} + //---------------------------------------------------------------------------- const char *cmTarget::GetProperty(const std::string& prop) const { @@ -3033,11 +3055,6 @@ const char *cmTarget::GetProperty(const std::string& prop, return 0; } - if (prop == "NAME") - { - return this->GetName().c_str(); - } - // Watch for special "computed" properties that are dependent on // other properties or variables. Always recompute them. if(this->GetType() == cmTarget::EXECUTABLE || @@ -3046,7 +3063,8 @@ const char *cmTarget::GetProperty(const std::string& prop, this->GetType() == cmTarget::MODULE_LIBRARY || this->GetType() == cmTarget::UNKNOWN_LIBRARY) { - if(prop == "LOCATION") + static const std::string propLOCATION = "LOCATION"; + if(prop == propLOCATION) { if (!this->HandleLocationPropertyPolicy(context)) { @@ -3062,12 +3080,12 @@ const char *cmTarget::GetProperty(const std::string& prop, // cannot take into account the per-configuration name of the // target because the configuration type may not be known at // CMake time. - this->Properties.SetProperty("LOCATION", this->GetLocationForBuild(), + this->Properties.SetProperty(propLOCATION, this->GetLocationForBuild(), cmProperty::TARGET); } // Support "LOCATION_". - if(cmHasLiteralPrefix(prop, "LOCATION_")) + else if(cmHasLiteralPrefix(prop, "LOCATION_")) { if (!this->HandleLocationPropertyPolicy(context)) { @@ -3079,7 +3097,7 @@ const char *cmTarget::GetProperty(const std::string& prop, cmProperty::TARGET); } // Support "_LOCATION". - if(cmHasLiteralSuffix(prop, "_LOCATION")) + else if(cmHasLiteralSuffix(prop, "_LOCATION")) { std::string configName(prop.c_str(), prop.size() - 9); if(configName != "IMPORTED") @@ -3094,228 +3112,210 @@ const char *cmTarget::GetProperty(const std::string& prop, } } } - if(prop == "INCLUDE_DIRECTORIES") + static UNORDERED_SET specialProps; +#define MAKE_STATIC_PROP(PROP) \ + static const std::string prop##PROP = #PROP + MAKE_STATIC_PROP(LINK_LIBRARIES); + MAKE_STATIC_PROP(TYPE); + MAKE_STATIC_PROP(INCLUDE_DIRECTORIES); + MAKE_STATIC_PROP(COMPILE_FEATURES); + MAKE_STATIC_PROP(COMPILE_OPTIONS); + MAKE_STATIC_PROP(COMPILE_DEFINITIONS); + MAKE_STATIC_PROP(IMPORTED); + MAKE_STATIC_PROP(NAME); + MAKE_STATIC_PROP(SOURCES); +#undef MAKE_STATIC_PROP + if(specialProps.empty()) { - if (this->Internal->IncludeDirectoriesEntries.empty()) - { - return 0; - } - - static std::string output; - output = ""; - std::string sep; - typedef cmTargetInternals::TargetPropertyEntry - TargetPropertyEntry; - for (std::vector::const_iterator - it = this->Internal->IncludeDirectoriesEntries.begin(), - end = this->Internal->IncludeDirectoriesEntries.end(); - it != end; ++it) - { - output += sep; - output += (*it)->ge->GetInput(); - sep = ";"; - } - return output.c_str(); + specialProps.insert(propLINK_LIBRARIES); + specialProps.insert(propTYPE); + specialProps.insert(propINCLUDE_DIRECTORIES); + specialProps.insert(propCOMPILE_FEATURES); + specialProps.insert(propCOMPILE_OPTIONS); + specialProps.insert(propCOMPILE_DEFINITIONS); + specialProps.insert(propIMPORTED); + specialProps.insert(propNAME); + specialProps.insert(propSOURCES); } - if(prop == "COMPILE_OPTIONS") + if(specialProps.count(prop)) { - if (this->Internal->CompileOptionsEntries.empty()) + if(prop == propLINK_LIBRARIES) { - return 0; - } - - static std::string output; - output = ""; - std::string sep; - typedef cmTargetInternals::TargetPropertyEntry - TargetPropertyEntry; - for (std::vector::const_iterator - it = this->Internal->CompileOptionsEntries.begin(), - end = this->Internal->CompileOptionsEntries.end(); - it != end; ++it) - { - output += sep; - output += (*it)->ge->GetInput(); - sep = ";"; - } - return output.c_str(); - } - if(prop == "COMPILE_FEATURES") - { - if (this->Internal->CompileFeaturesEntries.empty()) - { - return 0; - } - - static std::string output; - output = ""; - std::string sep; - typedef cmTargetInternals::TargetPropertyEntry - TargetPropertyEntry; - for (std::vector::const_iterator - it = this->Internal->CompileFeaturesEntries.begin(), - end = this->Internal->CompileFeaturesEntries.end(); - it != end; ++it) - { - output += sep; - output += (*it)->ge->GetInput(); - sep = ";"; - } - return output.c_str(); - } - if(prop == "COMPILE_DEFINITIONS") - { - if (this->Internal->CompileDefinitionsEntries.empty()) - { - return 0; - } - - static std::string output; - output = ""; - std::string sep; - typedef cmTargetInternals::TargetPropertyEntry - TargetPropertyEntry; - for (std::vector::const_iterator - it = this->Internal->CompileDefinitionsEntries.begin(), - end = this->Internal->CompileDefinitionsEntries.end(); - it != end; ++it) - { - output += sep; - output += (*it)->ge->GetInput(); - sep = ";"; - } - return output.c_str(); - } - if(prop == "LINK_LIBRARIES") - { - if (this->Internal->LinkImplementationPropertyEntries.empty()) - { - return 0; - } - - static std::string output; - output = ""; - std::string sep; - for (std::vector::const_iterator - it = this->Internal->LinkImplementationPropertyEntries.begin(), - end = this->Internal->LinkImplementationPropertyEntries.end(); - it != end; ++it) - { - output += sep; - output += it->Value; - sep = ";"; - } - return output.c_str(); - } - - if (prop == "IMPORTED") - { - return this->IsImported()?"TRUE":"FALSE"; - } - - if(prop == "SOURCES") - { - if (this->Internal->SourceEntries.empty()) - { - return 0; - } - - cmOStringStream ss; - const char* sep = ""; - typedef cmTargetInternals::TargetPropertyEntry - TargetPropertyEntry; - for(std::vector::const_iterator - i = this->Internal->SourceEntries.begin(); - i != this->Internal->SourceEntries.end(); ++i) - { - std::string entry = (*i)->ge->GetInput(); - - std::vector files; - cmSystemTools::ExpandListArgument(entry, files); - for (std::vector::const_iterator - li = files.begin(); li != files.end(); ++li) + if (this->Internal->LinkImplementationPropertyEntries.empty()) { - if(cmHasLiteralPrefix(*li, "$size() - 1] == '>') + return 0; + } + + static std::string output; + output = ""; + std::string sep; + for (std::vector::const_iterator + it = this->Internal->LinkImplementationPropertyEntries.begin(), + end = this->Internal->LinkImplementationPropertyEntries.end(); + it != end; ++it) + { + output += sep; + output += it->Value; + sep = ";"; + } + return output.c_str(); + } + // the type property returns what type the target is + else if (prop == propTYPE) + { + return cmTarget::GetTargetTypeName(this->GetType()); + } + else if(prop == propINCLUDE_DIRECTORIES) + { + if (this->Internal->IncludeDirectoriesEntries.empty()) + { + return 0; + } + + static std::string output; + MakePropertyList(output, this->Internal->IncludeDirectoriesEntries); + return output.c_str(); + } + else if(prop == propCOMPILE_FEATURES) + { + if (this->Internal->CompileFeaturesEntries.empty()) + { + return 0; + } + + static std::string output; + MakePropertyList(output, this->Internal->CompileFeaturesEntries); + return output.c_str(); + } + else if(prop == propCOMPILE_OPTIONS) + { + if (this->Internal->CompileOptionsEntries.empty()) + { + return 0; + } + + static std::string output; + MakePropertyList(output, this->Internal->CompileOptionsEntries); + return output.c_str(); + } + else if(prop == propCOMPILE_DEFINITIONS) + { + if (this->Internal->CompileDefinitionsEntries.empty()) + { + return 0; + } + + static std::string output; + MakePropertyList(output, this->Internal->CompileDefinitionsEntries); + return output.c_str(); + } + else if (prop == propIMPORTED) + { + return this->IsImported()?"TRUE":"FALSE"; + } + else if (prop == propNAME) + { + return this->GetName().c_str(); + } + else if(prop == propSOURCES) + { + if (this->Internal->SourceEntries.empty()) + { + return 0; + } + + cmOStringStream ss; + const char* sep = ""; + typedef cmTargetInternals::TargetPropertyEntry + TargetPropertyEntry; + for(std::vector::const_iterator + i = this->Internal->SourceEntries.begin(); + i != this->Internal->SourceEntries.end(); ++i) + { + std::string entry = (*i)->ge->GetInput(); + + std::vector files; + cmSystemTools::ExpandListArgument(entry, files); + for (std::vector::const_iterator + li = files.begin(); li != files.end(); ++li) { - std::string objLibName = li->substr(17, li->size()-18); + if(cmHasLiteralPrefix(*li, "$size() - 1] == '>') + { + std::string objLibName = li->substr(17, li->size()-18); - if (cmGeneratorExpression::Find(objLibName) != std::string::npos) - { - ss << sep; - sep = ";"; - ss << *li; - continue; - } + if (cmGeneratorExpression::Find(objLibName) != std::string::npos) + { + ss << sep; + sep = ";"; + ss << *li; + continue; + } - bool addContent = false; - bool noMessage = true; - cmOStringStream e; - cmake::MessageType messageType = cmake::AUTHOR_WARNING; - switch(context->GetPolicyStatus(cmPolicies::CMP0051)) - { - case cmPolicies::WARN: - e << (this->Makefile->GetPolicies() - ->GetPolicyWarning(cmPolicies::CMP0051)) << "\n"; - noMessage = false; - case cmPolicies::OLD: - break; - case cmPolicies::REQUIRED_ALWAYS: - case cmPolicies::REQUIRED_IF_USED: - case cmPolicies::NEW: - addContent = true; + bool addContent = false; + bool noMessage = true; + cmOStringStream e; + cmake::MessageType messageType = cmake::AUTHOR_WARNING; + switch(context->GetPolicyStatus(cmPolicies::CMP0051)) + { + case cmPolicies::WARN: + e << (this->Makefile->GetPolicies() + ->GetPolicyWarning(cmPolicies::CMP0051)) << "\n"; + noMessage = false; + case cmPolicies::OLD: + break; + case cmPolicies::REQUIRED_ALWAYS: + case cmPolicies::REQUIRED_IF_USED: + case cmPolicies::NEW: + addContent = true; + } + if (!noMessage) + { + e << "Target \"" << this->Name << "\" contains " + "$ generator expression in its sources list. " + "This content was not previously part of the SOURCES property " + "when that property was read at configure time. Code reading " + "that property needs to be adapted to ignore the generator " + "expression using the string(GENEX_STRIP) command."; + context->IssueMessage(messageType, e.str()); + } + if (addContent) + { + ss << sep; + sep = ";"; + ss << *li; + } } - if (!noMessage) - { - e << "Target \"" << this->Name << "\" contains $ " - "generator expression in its sources list. This content was not " - "previously part of the SOURCES property when that property was " - "read at configure time. Code reading that property needs to be " - "adapted to ignore the generator expression using the " - "string(GENEX_STRIP) command."; - context->IssueMessage(messageType, e.str()); - } - if (addContent) + else if (cmGeneratorExpression::Find(*li) == std::string::npos) { ss << sep; sep = ";"; ss << *li; } - } - else if (cmGeneratorExpression::Find(*li) == std::string::npos) - { - ss << sep; - sep = ";"; - ss << *li; - } - else - { - cmSourceFile *sf = this->Makefile->GetOrCreateSource(*li); - // Construct what is known about this source file location. - cmSourceFileLocation const& location = sf->GetLocation(); - std::string sname = location.GetDirectory(); - if(!sname.empty()) + else { - sname += "/"; - } - sname += location.GetName(); + cmSourceFile *sf = this->Makefile->GetOrCreateSource(*li); + // Construct what is known about this source file location. + cmSourceFileLocation const& location = sf->GetLocation(); + std::string sname = location.GetDirectory(); + if(!sname.empty()) + { + sname += "/"; + } + sname += location.GetName(); - ss << sep; - sep = ";"; - // Append this list entry. - ss << sname; + ss << sep; + sep = ";"; + // Append this list entry. + ss << sname; + } } } + this->Properties.SetProperty("SOURCES", ss.str().c_str(), + cmProperty::TARGET); } - this->Properties.SetProperty("SOURCES", ss.str().c_str(), - cmProperty::TARGET); } - // the type property returns what type the target is - if (prop == "TYPE") - { - return cmTarget::GetTargetTypeName(this->GetType()); - } bool chain = false; const char *retVal = this->Properties.GetPropertyValue(prop, cmProperty::TARGET, chain); @@ -3338,7 +3338,7 @@ class cmTargetCollectLinkLanguages public: cmTargetCollectLinkLanguages(cmTarget const* target, const std::string& config, - std::set& languages, + UNORDERED_SET& languages, cmTarget const* head): Config(config), Languages(languages), HeadTarget(head), Makefile(target->GetMakefile()), Target(target) @@ -3408,7 +3408,7 @@ public: } private: std::string Config; - std::set& Languages; + UNORDERED_SET& Languages; cmTarget const* HeadTarget; cmMakefile* Makefile; const cmTarget* Target; @@ -3445,7 +3445,7 @@ class cmTargetSelectLinker cmTarget const* Target; cmMakefile* Makefile; cmGlobalGenerator* GG; - std::set Preferred; + UNORDERED_SET Preferred; public: cmTargetSelectLinker(cmTarget const* target): Preference(0), Target(target) { @@ -3477,7 +3477,7 @@ public: e << "Target " << this->Target->GetName() << " contains multiple languages with the highest linker preference" << " (" << this->Preference << "):\n"; - for(std::set::const_iterator + for(UNORDERED_SET::const_iterator li = this->Preferred.begin(); li != this->Preferred.end(); ++li) { e << " " << *li << "\n"; @@ -3496,7 +3496,7 @@ void cmTarget::ComputeLinkClosure(const std::string& config, LinkClosure& lc) const { // Get languages built in this target. - std::set languages; + UNORDERED_SET languages; LinkImplementation const* impl = this->GetLinkImplementation(config); for(std::vector::const_iterator li = impl->Languages.begin(); li != impl->Languages.end(); ++li) @@ -3514,7 +3514,7 @@ void cmTarget::ComputeLinkClosure(const std::string& config, } // Store the transitive closure of languages. - for(std::set::const_iterator li = languages.begin(); + for(UNORDERED_SET::const_iterator li = languages.begin(); li != languages.end(); ++li) { lc.Languages.push_back(*li); @@ -3542,7 +3542,7 @@ void cmTarget::ComputeLinkClosure(const std::string& config, } // Now consider languages that propagate from linked targets. - for(std::set::const_iterator sit = languages.begin(); + for(UNORDERED_SET::const_iterator sit = languages.begin(); sit != languages.end(); ++sit) { std::string propagates = "CMAKE_"+*sit+"_LINKER_PREFERENCE_PROPAGATES"; @@ -4836,12 +4836,13 @@ bool cmTarget::IsNullImpliedByLinkLibraries(const std::string &p) const //---------------------------------------------------------------------------- template -PropertyType getTypedProperty(cmTarget const* tgt, const char *prop, +PropertyType getTypedProperty(cmTarget const* tgt, const std::string& prop, PropertyType *); //---------------------------------------------------------------------------- template<> -bool getTypedProperty(cmTarget const* tgt, const char *prop, bool *) +bool getTypedProperty(cmTarget const* tgt, const std::string& prop, + bool *) { return tgt->GetPropertyAsBool(prop); } @@ -4849,7 +4850,7 @@ bool getTypedProperty(cmTarget const* tgt, const char *prop, bool *) //---------------------------------------------------------------------------- template<> const char *getTypedProperty(cmTarget const* tgt, - const char *prop, + const std::string& prop, const char **) { return tgt->GetProperty(prop); @@ -5088,7 +5089,7 @@ PropertyType checkInterfacePropertyCompatibility(cmTarget const* tgt, CompatibleType t, PropertyType *) { - PropertyType propContent = getTypedProperty(tgt, p.c_str(), + PropertyType propContent = getTypedProperty(tgt, p, 0); const bool explicitlySet = tgt->GetProperties() .find(p) @@ -5124,6 +5125,7 @@ PropertyType checkInterfacePropertyCompatibility(cmTarget const* tgt, report += "\" property not set.\n"; } + std::string interfaceProperty = "INTERFACE_" + p; for(std::vector::const_iterator li = deps.begin(); li != deps.end(); ++li) @@ -5137,11 +5139,11 @@ PropertyType checkInterfacePropertyCompatibility(cmTarget const* tgt, cmTarget const* theTarget = *li; const bool ifaceIsSet = theTarget->GetProperties() - .find("INTERFACE_" + p) + .find(interfaceProperty) != theTarget->GetProperties().end(); PropertyType ifacePropContent = getTypedProperty(theTarget, - ("INTERFACE_" + p).c_str(), 0); + interfaceProperty, 0); std::string reportEntry; if (ifaceIsSet) @@ -6169,7 +6171,7 @@ cmTargetInternals::ComputeLinkInterfaceLibraries( // Compare the link implementation fallback link interface to the // preferred new link interface property and warn if different. std::vector ifaceLibs; - std::string newProp = "INTERFACE_LINK_LIBRARIES"; + static const std::string newProp = "INTERFACE_LINK_LIBRARIES"; if(const char* newExplicitLibraries = thisTarget->GetProperty(newProp)) { thisTarget->ExpandLinkItems(newProp, newExplicitLibraries, config, @@ -6237,7 +6239,7 @@ void cmTargetInternals::ComputeLinkInterface(cmTarget const* thisTarget, { // Shared libraries may have runtime implementation dependencies // on other shared libraries that are not in the interface. - std::set emitted; + UNORDERED_SET emitted; for(std::vector::const_iterator li = iface.Libraries.begin(); li != iface.Libraries.end(); ++li) { @@ -6755,9 +6757,13 @@ void cmTarget::CheckPropertyCompatibility(cmComputeLinkInformation *info, const cmComputeLinkInformation::ItemVector &deps = info->GetItems(); std::set emittedBools; + static std::string strBool = "COMPATIBLE_INTERFACE_BOOL"; std::set emittedStrings; + static std::string strString = "COMPATIBLE_INTERFACE_STRING"; std::set emittedMinNumbers; + static std::string strNumMin = "COMPATIBLE_INTERFACE_NUMBER_MIN"; std::set emittedMaxNumbers; + static std::string strNumMax = "COMPATIBLE_INTERFACE_NUMBER_MAX"; for(cmComputeLinkInformation::ItemVector::const_iterator li = deps.begin(); @@ -6769,14 +6775,14 @@ void cmTarget::CheckPropertyCompatibility(cmComputeLinkInformation *info, } checkPropertyConsistency(this, li->Target, - std::string("COMPATIBLE_INTERFACE_BOOL"), + strBool, emittedBools, config, BoolType, 0); if (cmSystemTools::GetErrorOccuredFlag()) { return; } checkPropertyConsistency(this, li->Target, - std::string("COMPATIBLE_INTERFACE_STRING"), + strString, emittedStrings, config, StringType, 0); if (cmSystemTools::GetErrorOccuredFlag()) @@ -6784,7 +6790,7 @@ void cmTarget::CheckPropertyCompatibility(cmComputeLinkInformation *info, return; } checkPropertyConsistency(this, li->Target, - std::string("COMPATIBLE_INTERFACE_NUMBER_MIN"), + strNumMin, emittedMinNumbers, config, NumberMinType, 0); if (cmSystemTools::GetErrorOccuredFlag()) @@ -6792,7 +6798,7 @@ void cmTarget::CheckPropertyCompatibility(cmComputeLinkInformation *info, return; } checkPropertyConsistency(this, li->Target, - std::string("COMPATIBLE_INTERFACE_NUMBER_MAX"), + strNumMax, emittedMaxNumbers, config, NumberMaxType, 0); if (cmSystemTools::GetErrorOccuredFlag()) @@ -6808,26 +6814,27 @@ void cmTarget::CheckPropertyCompatibility(cmComputeLinkInformation *info, if (!prop.empty()) { + // Use a std::set to keep the error message sorted. std::set props; std::set::const_iterator i = emittedBools.find(prop); if (i != emittedBools.end()) { - props.insert("COMPATIBLE_INTERFACE_BOOL"); + props.insert(strBool); } i = emittedStrings.find(prop); if (i != emittedStrings.end()) { - props.insert("COMPATIBLE_INTERFACE_STRING"); + props.insert(strString); } i = emittedMinNumbers.find(prop); if (i != emittedMinNumbers.end()) { - props.insert("COMPATIBLE_INTERFACE_NUMBER_MIN"); + props.insert(strNumMin); } i = emittedMaxNumbers.find(prop); if (i != emittedMaxNumbers.end()) { - props.insert("COMPATIBLE_INTERFACE_NUMBER_MAX"); + props.insert(strNumMax); } std::string propsString = *props.begin(); diff --git a/Source/cmTarget.h b/Source/cmTarget.h index 486315e09..b4c8a0fec 100644 --- a/Source/cmTarget.h +++ b/Source/cmTarget.h @@ -18,6 +18,9 @@ #include "cmListFileCache.h" #include +#if defined(CMAKE_BUILD_WITH_CMAKE) +#include +#endif #define CM_FOR_EACH_TARGET_POLICY(F) \ F(CMP0003) \ @@ -844,7 +847,11 @@ private: mutable bool LinkImplementationLanguageIsContextDependent; }; +#ifdef CMAKE_BUILD_WITH_CMAKE +typedef cmsys::hash_map cmTargets; +#else typedef std::map cmTargets; +#endif class cmTargetSet: public std::set {}; class cmTargetManifest: public std::map {};