Merge topic 'dev/target-fastpaths'

a9c9b66c cmTarget: use a hash_map for cmTargets typedef
bcb6dbc1 cmTarget: help the optimizer a bit
679f3dee cmTarget: use hash_set for sets of strings
23d6520d cmTarget: Allow caching of empty genex expansions
cd54f1db cmTarget: Only copy GenEx expansions when necessary
b75fc0e1 cmTarget: Don't set properties on custom targets
66076915 cmTarget: Use static strings for special property names
cebefa71 cmTarget: Sort special property checks
97ce676e cmTarget: Fast path for regular properties
4cfa918a cmTarget: Factor out common code
85242b7d cmTarget: Use else/if trees rather than an if tree
This commit is contained in:
Brad King 2014-07-18 11:00:29 -04:00 committed by CMake Topic Stage
commit 36a8184d40
2 changed files with 358 additions and 344 deletions

View File

@ -25,6 +25,12 @@
#include <stdlib.h> // required for atof #include <stdlib.h> // required for atof
#include <assert.h> #include <assert.h>
#include <errno.h> #include <errno.h>
#if defined(CMAKE_BUILD_WITH_CMAKE)
#include <cmsys/hash_set.hxx>
#define UNORDERED_SET cmsys::hash_set
#else
#define UNORDERED_SET std::set
#endif
const char* cmTarget::GetTargetTypeName(TargetType targetType) const char* cmTarget::GetTargetTypeName(TargetType targetType)
{ {
@ -190,10 +196,11 @@ public:
public: public:
TargetPropertyEntry(cmsys::auto_ptr<cmCompiledGeneratorExpression> cge, TargetPropertyEntry(cmsys::auto_ptr<cmCompiledGeneratorExpression> cge,
cmLinkImplItem const& item = NoLinkImplItem) cmLinkImplItem const& item = NoLinkImplItem)
: ge(cge), LinkImplItem(item) : ge(cge), Cached(false), LinkImplItem(item)
{} {}
const cmsys::auto_ptr<cmCompiledGeneratorExpression> ge; const cmsys::auto_ptr<cmCompiledGeneratorExpression> ge;
std::vector<std::string> CachedEntries; std::vector<std::string> CachedEntries;
bool Cached;
cmLinkImplItem const& LinkImplItem; cmLinkImplItem const& LinkImplItem;
}; };
std::vector<TargetPropertyEntry*> IncludeDirectoriesEntries; std::vector<TargetPropertyEntry*> IncludeDirectoriesEntries;
@ -228,7 +235,7 @@ public:
cmLinkImplItem cmTargetInternals::TargetPropertyEntry::NoLinkImplItem; cmLinkImplItem cmTargetInternals::TargetPropertyEntry::NoLinkImplItem;
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
void deleteAndClear( static void deleteAndClear(
std::vector<cmTargetInternals::TargetPropertyEntry*> &entries) std::vector<cmTargetInternals::TargetPropertyEntry*> &entries)
{ {
for (std::vector<cmTargetInternals::TargetPropertyEntry*>::const_iterator for (std::vector<cmTargetInternals::TargetPropertyEntry*>::const_iterator
@ -242,7 +249,7 @@ void deleteAndClear(
} }
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
void deleteAndClear( static void deleteAndClear(
std::map<std::string, std::map<std::string,
std::vector<cmTargetInternals::TargetPropertyEntry*> > &entries) std::vector<cmTargetInternals::TargetPropertyEntry*> > &entries)
{ {
@ -339,7 +346,7 @@ void cmTarget::SetMakefile(cmMakefile* mf)
this->IsApple = this->Makefile->IsOn("APPLE"); this->IsApple = this->Makefile->IsOn("APPLE");
// Setup default property values. // 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_NAME_DIR", 0);
this->SetPropertyDefault("INSTALL_RPATH", ""); this->SetPropertyDefault("INSTALL_RPATH", "");
@ -380,6 +387,8 @@ void cmTarget::SetMakefile(cmMakefile* mf)
mf->GetConfigurations(configNames); mf->GetConfigurations(configNames);
// Setup per-configuration property default values. // Setup per-configuration property default values.
if (this->GetType() != UTILITY)
{
const char* configProps[] = { const char* configProps[] = {
"ARCHIVE_OUTPUT_DIRECTORY_", "ARCHIVE_OUTPUT_DIRECTORY_",
"LIBRARY_OUTPUT_DIRECTORY_", "LIBRARY_OUTPUT_DIRECTORY_",
@ -417,6 +426,7 @@ void cmTarget::SetMakefile(cmMakefile* mf)
this->SetPropertyDefault(property, 0); this->SetPropertyDefault(property, 0);
} }
} }
}
// Save the backtrace of target construction. // Save the backtrace of target construction.
this->Internal->Backtrace = this->Makefile->GetBacktrace(); this->Internal->Backtrace = this->Makefile->GetBacktrace();
@ -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("C_VISIBILITY_PRESET", 0);
this->SetPropertyDefault("CXX_VISIBILITY_PRESET", 0); this->SetPropertyDefault("CXX_VISIBILITY_PRESET", 0);
@ -465,7 +475,7 @@ void cmTarget::SetMakefile(cmMakefile* mf)
{ {
this->SetProperty("POSITION_INDEPENDENT_CODE", "True"); 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); this->SetPropertyDefault("POSITION_INDEPENDENT_CODE", 0);
} }
@ -487,9 +497,12 @@ void cmTarget::SetMakefile(cmMakefile* mf)
this->PolicyStatusCMP0022 = cmPolicies::NEW; this->PolicyStatusCMP0022 = cmPolicies::NEW;
} }
if (this->GetType() != INTERFACE_LIBRARY && this->GetType() != UTILITY)
{
this->SetPropertyDefault("JOB_POOL_COMPILE", 0); this->SetPropertyDefault("JOB_POOL_COMPILE", 0);
this->SetPropertyDefault("JOB_POOL_LINK", 0); this->SetPropertyDefault("JOB_POOL_LINK", 0);
} }
}
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
void cmTarget::AddUtility(const std::string& u, cmMakefile *makefile) void cmTarget::AddUtility(const std::string& u, cmMakefile *makefile)
@ -646,7 +659,7 @@ bool cmTarget::IsBundleOnApple() const
static bool processSources(cmTarget const* tgt, static bool processSources(cmTarget const* tgt,
const std::vector<cmTargetInternals::TargetPropertyEntry*> &entries, const std::vector<cmTargetInternals::TargetPropertyEntry*> &entries,
std::vector<std::string> &srcs, std::vector<std::string> &srcs,
std::set<std::string> &uniqueSrcs, UNORDERED_SET<std::string> &uniqueSrcs,
cmGeneratorExpressionDAGChecker *dagChecker, cmGeneratorExpressionDAGChecker *dagChecker,
std::string const& config, bool debugSources) std::string const& config, bool debugSources)
{ {
@ -788,7 +801,7 @@ void cmTarget::GetSourceFiles(std::vector<std::string> &files,
cmGeneratorExpressionDAGChecker dagChecker(this->GetName(), cmGeneratorExpressionDAGChecker dagChecker(this->GetName(),
"SOURCES", 0, 0); "SOURCES", 0, 0);
std::set<std::string> uniqueSrcs; UNORDERED_SET<std::string> uniqueSrcs;
bool contextDependentDirectSources = processSources(this, bool contextDependentDirectSources = processSources(this,
this->Internal->SourceEntries, this->Internal->SourceEntries,
files, files,
@ -1302,7 +1315,7 @@ void cmTarget::GetTllSignatureTraces(cmOStringStream &s,
= (sig == cmTarget::KeywordTLLSignature ? "keyword" = (sig == cmTarget::KeywordTLLSignature ? "keyword"
: "plain"); : "plain");
s << "The uses of the " << sigString << " signature are here:\n"; s << "The uses of the " << sigString << " signature are here:\n";
std::set<std::string> emitted; UNORDERED_SET<std::string> emitted;
for(std::vector<cmListFileBacktrace>::iterator it = sigs.begin(); for(std::vector<cmListFileBacktrace>::iterator it = sigs.begin();
it != sigs.end(); ++it) it != sigs.end(); ++it)
{ {
@ -1721,22 +1734,20 @@ static bool whiteListedInterfaceProperty(const std::string& prop)
{ {
return true; return true;
} }
static const char* builtIns[] = { static UNORDERED_SET<std::string> builtIns;
// ###: This must remain sorted. It is processed with a binary search. if (builtIns.empty())
"COMPATIBLE_INTERFACE_BOOL", {
"COMPATIBLE_INTERFACE_NUMBER_MAX", builtIns.insert("COMPATIBLE_INTERFACE_BOOL");
"COMPATIBLE_INTERFACE_NUMBER_MIN", builtIns.insert("COMPATIBLE_INTERFACE_NUMBER_MAX");
"COMPATIBLE_INTERFACE_STRING", builtIns.insert("COMPATIBLE_INTERFACE_NUMBER_MIN");
"EXPORT_NAME", builtIns.insert("COMPATIBLE_INTERFACE_STRING");
"IMPORTED", builtIns.insert("EXPORT_NAME");
"NAME", builtIns.insert("IMPORTED");
"TYPE" builtIns.insert("NAME");
}; builtIns.insert("TYPE");
}
if (std::binary_search(cmArrayBegin(builtIns), if (builtIns.count(prop))
cmArrayEnd(builtIns),
prop.c_str(),
cmStrCmp(prop)))
{ {
return true; return true;
} }
@ -1761,15 +1772,14 @@ void cmTarget::SetProperty(const std::string& prop, const char* value)
this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str()); this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
return; return;
} }
else if (prop == "NAME")
if (prop == "NAME")
{ {
cmOStringStream e; cmOStringStream e;
e << "NAME property is read-only\n"; e << "NAME property is read-only\n";
this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str()); this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
return; return;
} }
if(prop == "INCLUDE_DIRECTORIES") else if(prop == "INCLUDE_DIRECTORIES")
{ {
cmListFileBacktrace lfbt = this->Makefile->GetBacktrace(); cmListFileBacktrace lfbt = this->Makefile->GetBacktrace();
cmGeneratorExpression ge(&lfbt); cmGeneratorExpression ge(&lfbt);
@ -1777,9 +1787,8 @@ void cmTarget::SetProperty(const std::string& prop, const char* value)
cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(value); cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(value);
this->Internal->IncludeDirectoriesEntries.push_back( this->Internal->IncludeDirectoriesEntries.push_back(
new cmTargetInternals::TargetPropertyEntry(cge)); new cmTargetInternals::TargetPropertyEntry(cge));
return;
} }
if(prop == "COMPILE_OPTIONS") else if(prop == "COMPILE_OPTIONS")
{ {
cmListFileBacktrace lfbt = this->Makefile->GetBacktrace(); cmListFileBacktrace lfbt = this->Makefile->GetBacktrace();
cmGeneratorExpression ge(&lfbt); cmGeneratorExpression ge(&lfbt);
@ -1787,9 +1796,8 @@ void cmTarget::SetProperty(const std::string& prop, const char* value)
cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(value); cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(value);
this->Internal->CompileOptionsEntries.push_back( this->Internal->CompileOptionsEntries.push_back(
new cmTargetInternals::TargetPropertyEntry(cge)); new cmTargetInternals::TargetPropertyEntry(cge));
return;
} }
if(prop == "COMPILE_FEATURES") else if(prop == "COMPILE_FEATURES")
{ {
cmListFileBacktrace lfbt = this->Makefile->GetBacktrace(); cmListFileBacktrace lfbt = this->Makefile->GetBacktrace();
cmGeneratorExpression ge(&lfbt); cmGeneratorExpression ge(&lfbt);
@ -1797,9 +1805,8 @@ void cmTarget::SetProperty(const std::string& prop, const char* value)
cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(value); cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(value);
this->Internal->CompileFeaturesEntries.push_back( this->Internal->CompileFeaturesEntries.push_back(
new cmTargetInternals::TargetPropertyEntry(cge)); new cmTargetInternals::TargetPropertyEntry(cge));
return;
} }
if(prop == "COMPILE_DEFINITIONS") else if(prop == "COMPILE_DEFINITIONS")
{ {
cmListFileBacktrace lfbt = this->Makefile->GetBacktrace(); cmListFileBacktrace lfbt = this->Makefile->GetBacktrace();
cmGeneratorExpression ge(&lfbt); cmGeneratorExpression ge(&lfbt);
@ -1807,25 +1814,22 @@ void cmTarget::SetProperty(const std::string& prop, const char* value)
cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(value); cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(value);
this->Internal->CompileDefinitionsEntries.push_back( this->Internal->CompileDefinitionsEntries.push_back(
new cmTargetInternals::TargetPropertyEntry(cge)); new cmTargetInternals::TargetPropertyEntry(cge));
return;
} }
if(prop == "EXPORT_NAME" && this->IsImported()) else if(prop == "EXPORT_NAME" && this->IsImported())
{ {
cmOStringStream e; cmOStringStream e;
e << "EXPORT_NAME property can't be set on imported targets (\"" e << "EXPORT_NAME property can't be set on imported targets (\""
<< this->Name << "\")\n"; << this->Name << "\")\n";
this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str()); this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
return;
} }
if (prop == "LINK_LIBRARIES") else if (prop == "LINK_LIBRARIES")
{ {
this->Internal->LinkImplementationPropertyEntries.clear(); this->Internal->LinkImplementationPropertyEntries.clear();
cmListFileBacktrace lfbt = this->Makefile->GetBacktrace(); cmListFileBacktrace lfbt = this->Makefile->GetBacktrace();
cmValueWithOrigin entry(value, lfbt); cmValueWithOrigin entry(value, lfbt);
this->Internal->LinkImplementationPropertyEntries.push_back(entry); this->Internal->LinkImplementationPropertyEntries.push_back(entry);
return;
} }
if (prop == "SOURCES") else if (prop == "SOURCES")
{ {
if(this->IsImported()) if(this->IsImported())
{ {
@ -1842,11 +1846,13 @@ void cmTarget::SetProperty(const std::string& prop, const char* value)
cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(value); cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(value);
this->Internal->SourceEntries.push_back( this->Internal->SourceEntries.push_back(
new cmTargetInternals::TargetPropertyEntry(cge)); new cmTargetInternals::TargetPropertyEntry(cge));
return;
} }
else
{
this->Properties.SetProperty(prop, value, cmProperty::TARGET); this->Properties.SetProperty(prop, value, cmProperty::TARGET);
this->MaybeInvalidatePropertyCache(prop); this->MaybeInvalidatePropertyCache(prop);
} }
}
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
void cmTarget::AppendProperty(const std::string& prop, const char* value, void cmTarget::AppendProperty(const std::string& prop, const char* value,
@ -1861,61 +1867,55 @@ void cmTarget::AppendProperty(const std::string& prop, const char* value,
this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str()); this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
return; return;
} }
if (prop == "NAME") else if (prop == "NAME")
{ {
cmOStringStream e; cmOStringStream e;
e << "NAME property is read-only\n"; e << "NAME property is read-only\n";
this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str()); this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
return; return;
} }
if(prop == "INCLUDE_DIRECTORIES") else if(prop == "INCLUDE_DIRECTORIES")
{ {
cmListFileBacktrace lfbt = this->Makefile->GetBacktrace(); cmListFileBacktrace lfbt = this->Makefile->GetBacktrace();
cmGeneratorExpression ge(&lfbt); cmGeneratorExpression ge(&lfbt);
this->Internal->IncludeDirectoriesEntries.push_back( this->Internal->IncludeDirectoriesEntries.push_back(
new cmTargetInternals::TargetPropertyEntry(ge.Parse(value))); new cmTargetInternals::TargetPropertyEntry(ge.Parse(value)));
return;
} }
if(prop == "COMPILE_OPTIONS") else if(prop == "COMPILE_OPTIONS")
{ {
cmListFileBacktrace lfbt = this->Makefile->GetBacktrace(); cmListFileBacktrace lfbt = this->Makefile->GetBacktrace();
cmGeneratorExpression ge(&lfbt); cmGeneratorExpression ge(&lfbt);
this->Internal->CompileOptionsEntries.push_back( this->Internal->CompileOptionsEntries.push_back(
new cmTargetInternals::TargetPropertyEntry(ge.Parse(value))); new cmTargetInternals::TargetPropertyEntry(ge.Parse(value)));
return;
} }
if(prop == "COMPILE_FEATURES") else if(prop == "COMPILE_FEATURES")
{ {
cmListFileBacktrace lfbt = this->Makefile->GetBacktrace(); cmListFileBacktrace lfbt = this->Makefile->GetBacktrace();
cmGeneratorExpression ge(&lfbt); cmGeneratorExpression ge(&lfbt);
this->Internal->CompileFeaturesEntries.push_back( this->Internal->CompileFeaturesEntries.push_back(
new cmTargetInternals::TargetPropertyEntry(ge.Parse(value))); new cmTargetInternals::TargetPropertyEntry(ge.Parse(value)));
return;
} }
if(prop == "COMPILE_DEFINITIONS") else if(prop == "COMPILE_DEFINITIONS")
{ {
cmListFileBacktrace lfbt = this->Makefile->GetBacktrace(); cmListFileBacktrace lfbt = this->Makefile->GetBacktrace();
cmGeneratorExpression ge(&lfbt); cmGeneratorExpression ge(&lfbt);
this->Internal->CompileDefinitionsEntries.push_back( this->Internal->CompileDefinitionsEntries.push_back(
new cmTargetInternals::TargetPropertyEntry(ge.Parse(value))); new cmTargetInternals::TargetPropertyEntry(ge.Parse(value)));
return;
} }
if(prop == "EXPORT_NAME" && this->IsImported()) else if(prop == "EXPORT_NAME" && this->IsImported())
{ {
cmOStringStream e; cmOStringStream e;
e << "EXPORT_NAME property can't be set on imported targets (\"" e << "EXPORT_NAME property can't be set on imported targets (\""
<< this->Name << "\")\n"; << this->Name << "\")\n";
this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str()); this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
return;
} }
if (prop == "LINK_LIBRARIES") else if (prop == "LINK_LIBRARIES")
{ {
cmListFileBacktrace lfbt = this->Makefile->GetBacktrace(); cmListFileBacktrace lfbt = this->Makefile->GetBacktrace();
cmValueWithOrigin entry(value, lfbt); cmValueWithOrigin entry(value, lfbt);
this->Internal->LinkImplementationPropertyEntries.push_back(entry); this->Internal->LinkImplementationPropertyEntries.push_back(entry);
return;
} }
if (prop == "SOURCES") else if (prop == "SOURCES")
{ {
if(this->IsImported()) if(this->IsImported())
{ {
@ -1931,11 +1931,13 @@ void cmTarget::AppendProperty(const std::string& prop, const char* value,
cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(value); cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(value);
this->Internal->SourceEntries.push_back( this->Internal->SourceEntries.push_back(
new cmTargetInternals::TargetPropertyEntry(cge)); new cmTargetInternals::TargetPropertyEntry(cge));
return;
} }
else
{
this->Properties.AppendProperty(prop, value, cmProperty::TARGET, asString); this->Properties.AppendProperty(prop, value, cmProperty::TARGET, asString);
this->MaybeInvalidatePropertyCache(prop); this->MaybeInvalidatePropertyCache(prop);
} }
}
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
std::string cmTarget::GetExportName() const std::string cmTarget::GetExportName() const
@ -2030,7 +2032,7 @@ void cmTarget::InsertCompileDefinition(const cmValueWithOrigin &entry)
static void processIncludeDirectories(cmTarget const* tgt, static void processIncludeDirectories(cmTarget const* tgt,
const std::vector<cmTargetInternals::TargetPropertyEntry*> &entries, const std::vector<cmTargetInternals::TargetPropertyEntry*> &entries,
std::vector<std::string> &includes, std::vector<std::string> &includes,
std::set<std::string> &uniqueIncludes, UNORDERED_SET<std::string> &uniqueIncludes,
cmGeneratorExpressionDAGChecker *dagChecker, cmGeneratorExpressionDAGChecker *dagChecker,
const std::string& config, bool debugIncludes) const std::string& config, bool debugIncludes)
{ {
@ -2179,7 +2181,7 @@ std::vector<std::string>
cmTarget::GetIncludeDirectories(const std::string& config) const cmTarget::GetIncludeDirectories(const std::string& config) const
{ {
std::vector<std::string> includes; std::vector<std::string> includes;
std::set<std::string> uniqueIncludes; UNORDERED_SET<std::string> uniqueIncludes;
cmGeneratorExpressionDAGChecker dagChecker(this->GetName(), cmGeneratorExpressionDAGChecker dagChecker(this->GetName(),
"INCLUDE_DIRECTORIES", 0, 0); "INCLUDE_DIRECTORIES", 0, 0);
@ -2271,7 +2273,7 @@ cmTarget::GetIncludeDirectories(const std::string& config) const
static void processCompileOptionsInternal(cmTarget const* tgt, static void processCompileOptionsInternal(cmTarget const* tgt,
const std::vector<cmTargetInternals::TargetPropertyEntry*> &entries, const std::vector<cmTargetInternals::TargetPropertyEntry*> &entries,
std::vector<std::string> &options, std::vector<std::string> &options,
std::set<std::string> &uniqueOptions, UNORDERED_SET<std::string> &uniqueOptions,
cmGeneratorExpressionDAGChecker *dagChecker, cmGeneratorExpressionDAGChecker *dagChecker,
const std::string& config, bool debugOptions, const char *logName) const std::string& config, bool debugOptions, const char *logName)
{ {
@ -2280,27 +2282,35 @@ static void processCompileOptionsInternal(cmTarget const* tgt,
for (std::vector<cmTargetInternals::TargetPropertyEntry*>::const_iterator for (std::vector<cmTargetInternals::TargetPropertyEntry*>::const_iterator
it = entries.begin(), end = entries.end(); it != end; ++it) it = entries.begin(), end = entries.end(); it != end; ++it)
{ {
bool cacheOptions = false; std::vector<std::string>& entriesRef = (*it)->CachedEntries;
std::vector<std::string> entryOptions = (*it)->CachedEntries; std::vector<std::string> localEntries;
if(entryOptions.empty()) std::vector<std::string>* entryOptions = &entriesRef;
if(!(*it)->Cached)
{ {
cmSystemTools::ExpandListArgument((*it)->ge->Evaluate(mf, cmSystemTools::ExpandListArgument((*it)->ge->Evaluate(mf,
config, config,
false, false,
tgt, tgt,
dagChecker), dagChecker),
entryOptions); localEntries);
if (mf->IsGeneratingBuildSystem() if (mf->IsGeneratingBuildSystem()
&& !(*it)->ge->GetHadContextSensitiveCondition()) && !(*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; std::string usedOptions;
for(std::vector<std::string>::iterator for(std::vector<std::string>::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) if(uniqueOptions.insert(opt).second)
{ {
@ -2311,10 +2321,6 @@ static void processCompileOptionsInternal(cmTarget const* tgt,
} }
} }
} }
if (cacheOptions)
{
(*it)->CachedEntries = entryOptions;
}
if (!usedOptions.empty()) if (!usedOptions.empty())
{ {
mf->GetCMakeInstance()->IssueMessage(cmake::LOG, mf->GetCMakeInstance()->IssueMessage(cmake::LOG,
@ -2330,7 +2336,7 @@ static void processCompileOptionsInternal(cmTarget const* tgt,
static void processCompileOptions(cmTarget const* tgt, static void processCompileOptions(cmTarget const* tgt,
const std::vector<cmTargetInternals::TargetPropertyEntry*> &entries, const std::vector<cmTargetInternals::TargetPropertyEntry*> &entries,
std::vector<std::string> &options, std::vector<std::string> &options,
std::set<std::string> &uniqueOptions, UNORDERED_SET<std::string> &uniqueOptions,
cmGeneratorExpressionDAGChecker *dagChecker, cmGeneratorExpressionDAGChecker *dagChecker,
const std::string& config, bool debugOptions) const std::string& config, bool debugOptions)
{ {
@ -2367,7 +2373,7 @@ void cmTarget::GetAutoUicOptions(std::vector<std::string> &result,
void cmTarget::GetCompileOptions(std::vector<std::string> &result, void cmTarget::GetCompileOptions(std::vector<std::string> &result,
const std::string& config) const const std::string& config) const
{ {
std::set<std::string> uniqueOptions; UNORDERED_SET<std::string> uniqueOptions;
cmGeneratorExpressionDAGChecker dagChecker(this->GetName(), cmGeneratorExpressionDAGChecker dagChecker(this->GetName(),
"COMPILE_OPTIONS", 0, 0); "COMPILE_OPTIONS", 0, 0);
@ -2428,7 +2434,7 @@ void cmTarget::GetCompileOptions(std::vector<std::string> &result,
static void processCompileDefinitions(cmTarget const* tgt, static void processCompileDefinitions(cmTarget const* tgt,
const std::vector<cmTargetInternals::TargetPropertyEntry*> &entries, const std::vector<cmTargetInternals::TargetPropertyEntry*> &entries,
std::vector<std::string> &options, std::vector<std::string> &options,
std::set<std::string> &uniqueOptions, UNORDERED_SET<std::string> &uniqueOptions,
cmGeneratorExpressionDAGChecker *dagChecker, cmGeneratorExpressionDAGChecker *dagChecker,
const std::string& config, bool debugOptions) const std::string& config, bool debugOptions)
{ {
@ -2441,7 +2447,7 @@ static void processCompileDefinitions(cmTarget const* tgt,
void cmTarget::GetCompileDefinitions(std::vector<std::string> &list, void cmTarget::GetCompileDefinitions(std::vector<std::string> &list,
const std::string& config) const const std::string& config) const
{ {
std::set<std::string> uniqueOptions; UNORDERED_SET<std::string> uniqueOptions;
cmGeneratorExpressionDAGChecker dagChecker(this->GetName(), cmGeneratorExpressionDAGChecker dagChecker(this->GetName(),
"COMPILE_DEFINITIONS", 0, 0); "COMPILE_DEFINITIONS", 0, 0);
@ -2539,7 +2545,7 @@ void cmTarget::GetCompileDefinitions(std::vector<std::string> &list,
static void processCompileFeatures(cmTarget const* tgt, static void processCompileFeatures(cmTarget const* tgt,
const std::vector<cmTargetInternals::TargetPropertyEntry*> &entries, const std::vector<cmTargetInternals::TargetPropertyEntry*> &entries,
std::vector<std::string> &options, std::vector<std::string> &options,
std::set<std::string> &uniqueOptions, UNORDERED_SET<std::string> &uniqueOptions,
cmGeneratorExpressionDAGChecker *dagChecker, cmGeneratorExpressionDAGChecker *dagChecker,
const std::string& config, bool debugOptions) const std::string& config, bool debugOptions)
{ {
@ -2551,7 +2557,7 @@ static void processCompileFeatures(cmTarget const* tgt,
void cmTarget::GetCompileFeatures(std::vector<std::string> &result, void cmTarget::GetCompileFeatures(std::vector<std::string> &result,
const std::string& config) const const std::string& config) const
{ {
std::set<std::string> uniqueFeatures; UNORDERED_SET<std::string> uniqueFeatures;
cmGeneratorExpressionDAGChecker dagChecker(this->GetName(), cmGeneratorExpressionDAGChecker dagChecker(this->GetName(),
"COMPILE_FEATURES", "COMPILE_FEATURES",
@ -3013,6 +3019,22 @@ bool cmTarget::HandleLocationPropertyPolicy(cmMakefile* context) const
return messageType != cmake::FATAL_ERROR; return messageType != cmake::FATAL_ERROR;
} }
//----------------------------------------------------------------------------
static void MakePropertyList(std::string& output,
std::vector<cmTargetInternals::TargetPropertyEntry*> const& values)
{
output = "";
std::string sep;
for (std::vector<cmTargetInternals::TargetPropertyEntry*>::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 const char *cmTarget::GetProperty(const std::string& prop) const
{ {
@ -3033,11 +3055,6 @@ const char *cmTarget::GetProperty(const std::string& prop,
return 0; return 0;
} }
if (prop == "NAME")
{
return this->GetName().c_str();
}
// Watch for special "computed" properties that are dependent on // Watch for special "computed" properties that are dependent on
// other properties or variables. Always recompute them. // other properties or variables. Always recompute them.
if(this->GetType() == cmTarget::EXECUTABLE || 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::MODULE_LIBRARY ||
this->GetType() == cmTarget::UNKNOWN_LIBRARY) this->GetType() == cmTarget::UNKNOWN_LIBRARY)
{ {
if(prop == "LOCATION") static const std::string propLOCATION = "LOCATION";
if(prop == propLOCATION)
{ {
if (!this->HandleLocationPropertyPolicy(context)) 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 // cannot take into account the per-configuration name of the
// target because the configuration type may not be known at // target because the configuration type may not be known at
// CMake time. // CMake time.
this->Properties.SetProperty("LOCATION", this->GetLocationForBuild(), this->Properties.SetProperty(propLOCATION, this->GetLocationForBuild(),
cmProperty::TARGET); cmProperty::TARGET);
} }
// Support "LOCATION_<CONFIG>". // Support "LOCATION_<CONFIG>".
if(cmHasLiteralPrefix(prop, "LOCATION_")) else if(cmHasLiteralPrefix(prop, "LOCATION_"))
{ {
if (!this->HandleLocationPropertyPolicy(context)) if (!this->HandleLocationPropertyPolicy(context))
{ {
@ -3079,7 +3097,7 @@ const char *cmTarget::GetProperty(const std::string& prop,
cmProperty::TARGET); cmProperty::TARGET);
} }
// Support "<CONFIG>_LOCATION". // Support "<CONFIG>_LOCATION".
if(cmHasLiteralSuffix(prop, "_LOCATION")) else if(cmHasLiteralSuffix(prop, "_LOCATION"))
{ {
std::string configName(prop.c_str(), prop.size() - 9); std::string configName(prop.c_str(), prop.size() - 9);
if(configName != "IMPORTED") if(configName != "IMPORTED")
@ -3094,99 +3112,34 @@ const char *cmTarget::GetProperty(const std::string& prop,
} }
} }
} }
if(prop == "INCLUDE_DIRECTORIES") static UNORDERED_SET<std::string> 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()) 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(specialProps.count(prop))
{ {
return 0; if(prop == propLINK_LIBRARIES)
}
static std::string output;
output = "";
std::string sep;
typedef cmTargetInternals::TargetPropertyEntry
TargetPropertyEntry;
for (std::vector<TargetPropertyEntry*>::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();
}
if(prop == "COMPILE_OPTIONS")
{
if (this->Internal->CompileOptionsEntries.empty())
{
return 0;
}
static std::string output;
output = "";
std::string sep;
typedef cmTargetInternals::TargetPropertyEntry
TargetPropertyEntry;
for (std::vector<TargetPropertyEntry*>::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<TargetPropertyEntry*>::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<TargetPropertyEntry*>::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()) if (this->Internal->LinkImplementationPropertyEntries.empty())
{ {
@ -3207,13 +3160,64 @@ const char *cmTarget::GetProperty(const std::string& prop,
} }
return output.c_str(); 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;
}
if (prop == "IMPORTED") 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"; return this->IsImported()?"TRUE":"FALSE";
} }
else if (prop == propNAME)
if(prop == "SOURCES") {
return this->GetName().c_str();
}
else if(prop == propSOURCES)
{ {
if (this->Internal->SourceEntries.empty()) if (this->Internal->SourceEntries.empty())
{ {
@ -3267,12 +3271,12 @@ const char *cmTarget::GetProperty(const std::string& prop,
} }
if (!noMessage) if (!noMessage)
{ {
e << "Target \"" << this->Name << "\" contains $<TARGET_OBJECTS> " e << "Target \"" << this->Name << "\" contains "
"generator expression in its sources list. This content was not " "$<TARGET_OBJECTS> generator expression in its sources list. "
"previously part of the SOURCES property when that property was " "This content was not previously part of the SOURCES property "
"read at configure time. Code reading that property needs to be " "when that property was read at configure time. Code reading "
"adapted to ignore the generator expression using the " "that property needs to be adapted to ignore the generator "
"string(GENEX_STRIP) command."; "expression using the string(GENEX_STRIP) command.";
context->IssueMessage(messageType, e.str()); context->IssueMessage(messageType, e.str());
} }
if (addContent) if (addContent)
@ -3310,12 +3314,8 @@ const char *cmTarget::GetProperty(const std::string& prop,
this->Properties.SetProperty("SOURCES", ss.str().c_str(), this->Properties.SetProperty("SOURCES", ss.str().c_str(),
cmProperty::TARGET); cmProperty::TARGET);
} }
// the type property returns what type the target is
if (prop == "TYPE")
{
return cmTarget::GetTargetTypeName(this->GetType());
} }
bool chain = false; bool chain = false;
const char *retVal = const char *retVal =
this->Properties.GetPropertyValue(prop, cmProperty::TARGET, chain); this->Properties.GetPropertyValue(prop, cmProperty::TARGET, chain);
@ -3338,7 +3338,7 @@ class cmTargetCollectLinkLanguages
public: public:
cmTargetCollectLinkLanguages(cmTarget const* target, cmTargetCollectLinkLanguages(cmTarget const* target,
const std::string& config, const std::string& config,
std::set<std::string>& languages, UNORDERED_SET<std::string>& languages,
cmTarget const* head): cmTarget const* head):
Config(config), Languages(languages), HeadTarget(head), Config(config), Languages(languages), HeadTarget(head),
Makefile(target->GetMakefile()), Target(target) Makefile(target->GetMakefile()), Target(target)
@ -3408,7 +3408,7 @@ public:
} }
private: private:
std::string Config; std::string Config;
std::set<std::string>& Languages; UNORDERED_SET<std::string>& Languages;
cmTarget const* HeadTarget; cmTarget const* HeadTarget;
cmMakefile* Makefile; cmMakefile* Makefile;
const cmTarget* Target; const cmTarget* Target;
@ -3445,7 +3445,7 @@ class cmTargetSelectLinker
cmTarget const* Target; cmTarget const* Target;
cmMakefile* Makefile; cmMakefile* Makefile;
cmGlobalGenerator* GG; cmGlobalGenerator* GG;
std::set<std::string> Preferred; UNORDERED_SET<std::string> Preferred;
public: public:
cmTargetSelectLinker(cmTarget const* target): Preference(0), Target(target) cmTargetSelectLinker(cmTarget const* target): Preference(0), Target(target)
{ {
@ -3477,7 +3477,7 @@ public:
e << "Target " << this->Target->GetName() e << "Target " << this->Target->GetName()
<< " contains multiple languages with the highest linker preference" << " contains multiple languages with the highest linker preference"
<< " (" << this->Preference << "):\n"; << " (" << this->Preference << "):\n";
for(std::set<std::string>::const_iterator for(UNORDERED_SET<std::string>::const_iterator
li = this->Preferred.begin(); li != this->Preferred.end(); ++li) li = this->Preferred.begin(); li != this->Preferred.end(); ++li)
{ {
e << " " << *li << "\n"; e << " " << *li << "\n";
@ -3496,7 +3496,7 @@ void cmTarget::ComputeLinkClosure(const std::string& config,
LinkClosure& lc) const LinkClosure& lc) const
{ {
// Get languages built in this target. // Get languages built in this target.
std::set<std::string> languages; UNORDERED_SET<std::string> languages;
LinkImplementation const* impl = this->GetLinkImplementation(config); LinkImplementation const* impl = this->GetLinkImplementation(config);
for(std::vector<std::string>::const_iterator li = impl->Languages.begin(); for(std::vector<std::string>::const_iterator li = impl->Languages.begin();
li != impl->Languages.end(); ++li) li != impl->Languages.end(); ++li)
@ -3514,7 +3514,7 @@ void cmTarget::ComputeLinkClosure(const std::string& config,
} }
// Store the transitive closure of languages. // Store the transitive closure of languages.
for(std::set<std::string>::const_iterator li = languages.begin(); for(UNORDERED_SET<std::string>::const_iterator li = languages.begin();
li != languages.end(); ++li) li != languages.end(); ++li)
{ {
lc.Languages.push_back(*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. // Now consider languages that propagate from linked targets.
for(std::set<std::string>::const_iterator sit = languages.begin(); for(UNORDERED_SET<std::string>::const_iterator sit = languages.begin();
sit != languages.end(); ++sit) sit != languages.end(); ++sit)
{ {
std::string propagates = "CMAKE_"+*sit+"_LINKER_PREFERENCE_PROPAGATES"; std::string propagates = "CMAKE_"+*sit+"_LINKER_PREFERENCE_PROPAGATES";
@ -4836,12 +4836,13 @@ bool cmTarget::IsNullImpliedByLinkLibraries(const std::string &p) const
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
template<typename PropertyType> template<typename PropertyType>
PropertyType getTypedProperty(cmTarget const* tgt, const char *prop, PropertyType getTypedProperty(cmTarget const* tgt, const std::string& prop,
PropertyType *); PropertyType *);
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
template<> template<>
bool getTypedProperty<bool>(cmTarget const* tgt, const char *prop, bool *) bool getTypedProperty<bool>(cmTarget const* tgt, const std::string& prop,
bool *)
{ {
return tgt->GetPropertyAsBool(prop); return tgt->GetPropertyAsBool(prop);
} }
@ -4849,7 +4850,7 @@ bool getTypedProperty<bool>(cmTarget const* tgt, const char *prop, bool *)
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
template<> template<>
const char *getTypedProperty<const char *>(cmTarget const* tgt, const char *getTypedProperty<const char *>(cmTarget const* tgt,
const char *prop, const std::string& prop,
const char **) const char **)
{ {
return tgt->GetProperty(prop); return tgt->GetProperty(prop);
@ -5088,7 +5089,7 @@ PropertyType checkInterfacePropertyCompatibility(cmTarget const* tgt,
CompatibleType t, CompatibleType t,
PropertyType *) PropertyType *)
{ {
PropertyType propContent = getTypedProperty<PropertyType>(tgt, p.c_str(), PropertyType propContent = getTypedProperty<PropertyType>(tgt, p,
0); 0);
const bool explicitlySet = tgt->GetProperties() const bool explicitlySet = tgt->GetProperties()
.find(p) .find(p)
@ -5124,6 +5125,7 @@ PropertyType checkInterfacePropertyCompatibility(cmTarget const* tgt,
report += "\" property not set.\n"; report += "\" property not set.\n";
} }
std::string interfaceProperty = "INTERFACE_" + p;
for(std::vector<cmTarget const*>::const_iterator li = for(std::vector<cmTarget const*>::const_iterator li =
deps.begin(); deps.begin();
li != deps.end(); ++li) li != deps.end(); ++li)
@ -5137,11 +5139,11 @@ PropertyType checkInterfacePropertyCompatibility(cmTarget const* tgt,
cmTarget const* theTarget = *li; cmTarget const* theTarget = *li;
const bool ifaceIsSet = theTarget->GetProperties() const bool ifaceIsSet = theTarget->GetProperties()
.find("INTERFACE_" + p) .find(interfaceProperty)
!= theTarget->GetProperties().end(); != theTarget->GetProperties().end();
PropertyType ifacePropContent = PropertyType ifacePropContent =
getTypedProperty<PropertyType>(theTarget, getTypedProperty<PropertyType>(theTarget,
("INTERFACE_" + p).c_str(), 0); interfaceProperty, 0);
std::string reportEntry; std::string reportEntry;
if (ifaceIsSet) if (ifaceIsSet)
@ -6169,7 +6171,7 @@ cmTargetInternals::ComputeLinkInterfaceLibraries(
// Compare the link implementation fallback link interface to the // Compare the link implementation fallback link interface to the
// preferred new link interface property and warn if different. // preferred new link interface property and warn if different.
std::vector<cmLinkItem> ifaceLibs; std::vector<cmLinkItem> ifaceLibs;
std::string newProp = "INTERFACE_LINK_LIBRARIES"; static const std::string newProp = "INTERFACE_LINK_LIBRARIES";
if(const char* newExplicitLibraries = thisTarget->GetProperty(newProp)) if(const char* newExplicitLibraries = thisTarget->GetProperty(newProp))
{ {
thisTarget->ExpandLinkItems(newProp, newExplicitLibraries, config, thisTarget->ExpandLinkItems(newProp, newExplicitLibraries, config,
@ -6237,7 +6239,7 @@ void cmTargetInternals::ComputeLinkInterface(cmTarget const* thisTarget,
{ {
// Shared libraries may have runtime implementation dependencies // Shared libraries may have runtime implementation dependencies
// on other shared libraries that are not in the interface. // on other shared libraries that are not in the interface.
std::set<std::string> emitted; UNORDERED_SET<std::string> emitted;
for(std::vector<cmLinkItem>::const_iterator for(std::vector<cmLinkItem>::const_iterator
li = iface.Libraries.begin(); li != iface.Libraries.end(); ++li) li = iface.Libraries.begin(); li != iface.Libraries.end(); ++li)
{ {
@ -6755,9 +6757,13 @@ void cmTarget::CheckPropertyCompatibility(cmComputeLinkInformation *info,
const cmComputeLinkInformation::ItemVector &deps = info->GetItems(); const cmComputeLinkInformation::ItemVector &deps = info->GetItems();
std::set<std::string> emittedBools; std::set<std::string> emittedBools;
static std::string strBool = "COMPATIBLE_INTERFACE_BOOL";
std::set<std::string> emittedStrings; std::set<std::string> emittedStrings;
static std::string strString = "COMPATIBLE_INTERFACE_STRING";
std::set<std::string> emittedMinNumbers; std::set<std::string> emittedMinNumbers;
static std::string strNumMin = "COMPATIBLE_INTERFACE_NUMBER_MIN";
std::set<std::string> emittedMaxNumbers; std::set<std::string> emittedMaxNumbers;
static std::string strNumMax = "COMPATIBLE_INTERFACE_NUMBER_MAX";
for(cmComputeLinkInformation::ItemVector::const_iterator li = for(cmComputeLinkInformation::ItemVector::const_iterator li =
deps.begin(); deps.begin();
@ -6769,14 +6775,14 @@ void cmTarget::CheckPropertyCompatibility(cmComputeLinkInformation *info,
} }
checkPropertyConsistency<bool>(this, li->Target, checkPropertyConsistency<bool>(this, li->Target,
std::string("COMPATIBLE_INTERFACE_BOOL"), strBool,
emittedBools, config, BoolType, 0); emittedBools, config, BoolType, 0);
if (cmSystemTools::GetErrorOccuredFlag()) if (cmSystemTools::GetErrorOccuredFlag())
{ {
return; return;
} }
checkPropertyConsistency<const char *>(this, li->Target, checkPropertyConsistency<const char *>(this, li->Target,
std::string("COMPATIBLE_INTERFACE_STRING"), strString,
emittedStrings, config, emittedStrings, config,
StringType, 0); StringType, 0);
if (cmSystemTools::GetErrorOccuredFlag()) if (cmSystemTools::GetErrorOccuredFlag())
@ -6784,7 +6790,7 @@ void cmTarget::CheckPropertyCompatibility(cmComputeLinkInformation *info,
return; return;
} }
checkPropertyConsistency<const char *>(this, li->Target, checkPropertyConsistency<const char *>(this, li->Target,
std::string("COMPATIBLE_INTERFACE_NUMBER_MIN"), strNumMin,
emittedMinNumbers, config, emittedMinNumbers, config,
NumberMinType, 0); NumberMinType, 0);
if (cmSystemTools::GetErrorOccuredFlag()) if (cmSystemTools::GetErrorOccuredFlag())
@ -6792,7 +6798,7 @@ void cmTarget::CheckPropertyCompatibility(cmComputeLinkInformation *info,
return; return;
} }
checkPropertyConsistency<const char *>(this, li->Target, checkPropertyConsistency<const char *>(this, li->Target,
std::string("COMPATIBLE_INTERFACE_NUMBER_MAX"), strNumMax,
emittedMaxNumbers, config, emittedMaxNumbers, config,
NumberMaxType, 0); NumberMaxType, 0);
if (cmSystemTools::GetErrorOccuredFlag()) if (cmSystemTools::GetErrorOccuredFlag())
@ -6808,26 +6814,27 @@ void cmTarget::CheckPropertyCompatibility(cmComputeLinkInformation *info,
if (!prop.empty()) if (!prop.empty())
{ {
// Use a std::set to keep the error message sorted.
std::set<std::string> props; std::set<std::string> props;
std::set<std::string>::const_iterator i = emittedBools.find(prop); std::set<std::string>::const_iterator i = emittedBools.find(prop);
if (i != emittedBools.end()) if (i != emittedBools.end())
{ {
props.insert("COMPATIBLE_INTERFACE_BOOL"); props.insert(strBool);
} }
i = emittedStrings.find(prop); i = emittedStrings.find(prop);
if (i != emittedStrings.end()) if (i != emittedStrings.end())
{ {
props.insert("COMPATIBLE_INTERFACE_STRING"); props.insert(strString);
} }
i = emittedMinNumbers.find(prop); i = emittedMinNumbers.find(prop);
if (i != emittedMinNumbers.end()) if (i != emittedMinNumbers.end())
{ {
props.insert("COMPATIBLE_INTERFACE_NUMBER_MIN"); props.insert(strNumMin);
} }
i = emittedMaxNumbers.find(prop); i = emittedMaxNumbers.find(prop);
if (i != emittedMaxNumbers.end()) if (i != emittedMaxNumbers.end())
{ {
props.insert("COMPATIBLE_INTERFACE_NUMBER_MAX"); props.insert(strNumMax);
} }
std::string propsString = *props.begin(); std::string propsString = *props.begin();

View File

@ -18,6 +18,9 @@
#include "cmListFileCache.h" #include "cmListFileCache.h"
#include <cmsys/auto_ptr.hxx> #include <cmsys/auto_ptr.hxx>
#if defined(CMAKE_BUILD_WITH_CMAKE)
#include <cmsys/hash_map.hxx>
#endif
#define CM_FOR_EACH_TARGET_POLICY(F) \ #define CM_FOR_EACH_TARGET_POLICY(F) \
F(CMP0003) \ F(CMP0003) \
@ -844,7 +847,11 @@ private:
mutable bool LinkImplementationLanguageIsContextDependent; mutable bool LinkImplementationLanguageIsContextDependent;
}; };
#ifdef CMAKE_BUILD_WITH_CMAKE
typedef cmsys::hash_map<std::string,cmTarget> cmTargets;
#else
typedef std::map<std::string,cmTarget> cmTargets; typedef std::map<std::string,cmTarget> cmTargets;
#endif
class cmTargetSet: public std::set<std::string> {}; class cmTargetSet: public std::set<std::string> {};
class cmTargetManifest: public std::map<std::string, cmTargetSet> {}; class cmTargetManifest: public std::map<std::string, cmTargetSet> {};