summaryrefslogtreecommitdiffstats
path: root/Source/cmTarget.cxx
diff options
context:
space:
mode:
authorBrad King <brad.king@kitware.com>2014-07-18 15:00:29 (GMT)
committerCMake Topic Stage <kwrobot@kitware.com>2014-07-18 15:00:29 (GMT)
commit36a8184d40e7055e9af564b5ad86cd84b7934994 (patch)
treec7184670633d239c5e48244c0657b388463ce48c /Source/cmTarget.cxx
parente27b2c3fa542a400a14176a7753d0daac36c1ed4 (diff)
parenta9c9b66c272d1d63918c1a5040c63d6cb169be91 (diff)
downloadCMake-36a8184d40e7055e9af564b5ad86cd84b7934994.zip
CMake-36a8184d40e7055e9af564b5ad86cd84b7934994.tar.gz
CMake-36a8184d40e7055e9af564b5ad86cd84b7934994.tar.bz2
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
Diffstat (limited to 'Source/cmTarget.cxx')
-rw-r--r--Source/cmTarget.cxx667
1 files changed, 337 insertions, 330 deletions
diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index 29029eb..07f08de 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -25,6 +25,12 @@
#include <stdlib.h> // required for atof
#include <assert.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)
{
@@ -190,10 +196,11 @@ public:
public:
TargetPropertyEntry(cmsys::auto_ptr<cmCompiledGeneratorExpression> cge,
cmLinkImplItem const& item = NoLinkImplItem)
- : ge(cge), LinkImplItem(item)
+ : ge(cge), Cached(false), LinkImplItem(item)
{}
const cmsys::auto_ptr<cmCompiledGeneratorExpression> ge;
std::vector<std::string> CachedEntries;
+ bool Cached;
cmLinkImplItem const& LinkImplItem;
};
std::vector<TargetPropertyEntry*> IncludeDirectoriesEntries;
@@ -228,7 +235,7 @@ public:
cmLinkImplItem cmTargetInternals::TargetPropertyEntry::NoLinkImplItem;
//----------------------------------------------------------------------------
-void deleteAndClear(
+static void deleteAndClear(
std::vector<cmTargetInternals::TargetPropertyEntry*> &entries)
{
for (std::vector<cmTargetInternals::TargetPropertyEntry*>::const_iterator
@@ -242,7 +249,7 @@ void deleteAndClear(
}
//----------------------------------------------------------------------------
-void deleteAndClear(
+static void deleteAndClear(
std::map<std::string,
std::vector<cmTargetInternals::TargetPropertyEntry*> > &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<std::string>::iterator ci = configNames.begin();
- ci != configNames.end(); ++ci)
- {
- std::string configUpper = cmSystemTools::UpperCase(*ci);
- for(const char** p = configProps; *p; ++p)
- {
- if (this->TargetTypeValue == INTERFACE_LIBRARY
- && strcmp(*p, "MAP_IMPORTED_CONFIG_") != 0)
+ if (this->GetType() != UTILITY)
+ {
+ 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<std::string>::iterator ci = configNames.begin();
+ ci != configNames.end(); ++ci)
+ {
+ 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<cmTargetInternals::TargetPropertyEntry*> &entries,
std::vector<std::string> &srcs,
- std::set<std::string> &uniqueSrcs,
+ UNORDERED_SET<std::string> &uniqueSrcs,
cmGeneratorExpressionDAGChecker *dagChecker,
std::string const& config, bool debugSources)
{
@@ -788,7 +801,7 @@ void cmTarget::GetSourceFiles(std::vector<std::string> &files,
cmGeneratorExpressionDAGChecker dagChecker(this->GetName(),
"SOURCES", 0, 0);
- std::set<std::string> uniqueSrcs;
+ UNORDERED_SET<std::string> 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<std::string> emitted;
+ UNORDERED_SET<std::string> emitted;
for(std::vector<cmListFileBacktrace>::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<std::string> 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<cmCompiledGeneratorExpression> 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<cmCompiledGeneratorExpression> 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<cmCompiledGeneratorExpression> 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<cmCompiledGeneratorExpression> 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<cmCompiledGeneratorExpression> 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<cmCompiledGeneratorExpression> 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<cmTargetInternals::TargetPropertyEntry*> &entries,
std::vector<std::string> &includes,
- std::set<std::string> &uniqueIncludes,
+ UNORDERED_SET<std::string> &uniqueIncludes,
cmGeneratorExpressionDAGChecker *dagChecker,
const std::string& config, bool debugIncludes)
{
@@ -2179,7 +2181,7 @@ std::vector<std::string>
cmTarget::GetIncludeDirectories(const std::string& config) const
{
std::vector<std::string> includes;
- std::set<std::string> uniqueIncludes;
+ UNORDERED_SET<std::string> 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<cmTargetInternals::TargetPropertyEntry*> &entries,
std::vector<std::string> &options,
- std::set<std::string> &uniqueOptions,
+ UNORDERED_SET<std::string> &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<cmTargetInternals::TargetPropertyEntry*>::const_iterator
it = entries.begin(), end = entries.end(); it != end; ++it)
{
- bool cacheOptions = false;
- std::vector<std::string> entryOptions = (*it)->CachedEntries;
- if(entryOptions.empty())
+ std::vector<std::string>& entriesRef = (*it)->CachedEntries;
+ std::vector<std::string> localEntries;
+ std::vector<std::string>* 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<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)
{
@@ -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<cmTargetInternals::TargetPropertyEntry*> &entries,
std::vector<std::string> &options,
- std::set<std::string> &uniqueOptions,
+ UNORDERED_SET<std::string> &uniqueOptions,
cmGeneratorExpressionDAGChecker *dagChecker,
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,
const std::string& config) const
{
- std::set<std::string> uniqueOptions;
+ UNORDERED_SET<std::string> uniqueOptions;
cmGeneratorExpressionDAGChecker dagChecker(this->GetName(),
"COMPILE_OPTIONS", 0, 0);
@@ -2428,7 +2434,7 @@ void cmTarget::GetCompileOptions(std::vector<std::string> &result,
static void processCompileDefinitions(cmTarget const* tgt,
const std::vector<cmTargetInternals::TargetPropertyEntry*> &entries,
std::vector<std::string> &options,
- std::set<std::string> &uniqueOptions,
+ UNORDERED_SET<std::string> &uniqueOptions,
cmGeneratorExpressionDAGChecker *dagChecker,
const std::string& config, bool debugOptions)
{
@@ -2441,7 +2447,7 @@ static void processCompileDefinitions(cmTarget const* tgt,
void cmTarget::GetCompileDefinitions(std::vector<std::string> &list,
const std::string& config) const
{
- std::set<std::string> uniqueOptions;
+ UNORDERED_SET<std::string> uniqueOptions;
cmGeneratorExpressionDAGChecker dagChecker(this->GetName(),
"COMPILE_DEFINITIONS", 0, 0);
@@ -2539,7 +2545,7 @@ void cmTarget::GetCompileDefinitions(std::vector<std::string> &list,
static void processCompileFeatures(cmTarget const* tgt,
const std::vector<cmTargetInternals::TargetPropertyEntry*> &entries,
std::vector<std::string> &options,
- std::set<std::string> &uniqueOptions,
+ UNORDERED_SET<std::string> &uniqueOptions,
cmGeneratorExpressionDAGChecker *dagChecker,
const std::string& config, bool debugOptions)
{
@@ -2551,7 +2557,7 @@ static void processCompileFeatures(cmTarget const* tgt,
void cmTarget::GetCompileFeatures(std::vector<std::string> &result,
const std::string& config) const
{
- std::set<std::string> uniqueFeatures;
+ UNORDERED_SET<std::string> uniqueFeatures;
cmGeneratorExpressionDAGChecker dagChecker(this->GetName(),
"COMPILE_FEATURES",
@@ -3014,6 +3020,22 @@ bool cmTarget::HandleLocationPropertyPolicy(cmMakefile* context) const
}
//----------------------------------------------------------------------------
+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
{
return this->GetProperty(prop, this->Makefile);
@@ -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_<CONFIG>".
- 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 "<CONFIG>_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")
- {
- if (this->Internal->IncludeDirectoriesEntries.empty())
- {
- return 0;
- }
+ 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())
+ {
+ 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))
+ {
+ if(prop == propLINK_LIBRARIES)
+ {
+ if (this->Internal->LinkImplementationPropertyEntries.empty())
+ {
+ return 0;
+ }
- 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 = ";";
+ static std::string output;
+ output = "";
+ std::string sep;
+ for (std::vector<cmValueWithOrigin>::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();
}
- return output.c_str();
- }
- if(prop == "COMPILE_OPTIONS")
- {
- if (this->Internal->CompileOptionsEntries.empty())
+ // the type property returns what type the target is
+ else if (prop == propTYPE)
{
- return 0;
+ return cmTarget::GetTargetTypeName(this->GetType());
}
-
- 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)
+ else if(prop == propINCLUDE_DIRECTORIES)
{
- output += sep;
- output += (*it)->ge->GetInput();
- sep = ";";
+ if (this->Internal->IncludeDirectoriesEntries.empty())
+ {
+ return 0;
+ }
+
+ static std::string output;
+ MakePropertyList(output, this->Internal->IncludeDirectoriesEntries);
+ return output.c_str();
}
- return output.c_str();
- }
- if(prop == "COMPILE_FEATURES")
- {
- if (this->Internal->CompileFeaturesEntries.empty())
+ else if(prop == propCOMPILE_FEATURES)
{
- return 0;
- }
+ 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 = ";";
+ static std::string output;
+ MakePropertyList(output, this->Internal->CompileFeaturesEntries);
+ return output.c_str();
}
- return output.c_str();
- }
- if(prop == "COMPILE_DEFINITIONS")
- {
- if (this->Internal->CompileDefinitionsEntries.empty())
+ else if(prop == propCOMPILE_OPTIONS)
{
- return 0;
- }
+ 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->CompileDefinitionsEntries.begin(),
- end = this->Internal->CompileDefinitionsEntries.end();
- it != end; ++it)
- {
- output += sep;
- output += (*it)->ge->GetInput();
- sep = ";";
+ static std::string output;
+ MakePropertyList(output, this->Internal->CompileOptionsEntries);
+ return output.c_str();
}
- return output.c_str();
- }
- if(prop == "LINK_LIBRARIES")
- {
- if (this->Internal->LinkImplementationPropertyEntries.empty())
+ else if(prop == propCOMPILE_DEFINITIONS)
{
- return 0;
- }
+ if (this->Internal->CompileDefinitionsEntries.empty())
+ {
+ return 0;
+ }
- static std::string output;
- output = "";
- std::string sep;
- for (std::vector<cmValueWithOrigin>::const_iterator
- it = this->Internal->LinkImplementationPropertyEntries.begin(),
- end = this->Internal->LinkImplementationPropertyEntries.end();
- it != end; ++it)
+ static std::string output;
+ MakePropertyList(output, this->Internal->CompileDefinitionsEntries);
+ return output.c_str();
+ }
+ else if (prop == propIMPORTED)
{
- output += sep;
- output += it->Value;
- sep = ";";
+ return this->IsImported()?"TRUE":"FALSE";
}
- return output.c_str();
- }
-
- if (prop == "IMPORTED")
- {
- return this->IsImported()?"TRUE":"FALSE";
- }
-
- if(prop == "SOURCES")
- {
- if (this->Internal->SourceEntries.empty())
+ else if (prop == propNAME)
{
- return 0;
+ return this->GetName().c_str();
}
-
- cmOStringStream ss;
- const char* sep = "";
- typedef cmTargetInternals::TargetPropertyEntry
- TargetPropertyEntry;
- for(std::vector<TargetPropertyEntry*>::const_iterator
- i = this->Internal->SourceEntries.begin();
- i != this->Internal->SourceEntries.end(); ++i)
+ else if(prop == propSOURCES)
{
- std::string entry = (*i)->ge->GetInput();
+ if (this->Internal->SourceEntries.empty())
+ {
+ return 0;
+ }
- std::vector<std::string> files;
- cmSystemTools::ExpandListArgument(entry, files);
- for (std::vector<std::string>::const_iterator
- li = files.begin(); li != files.end(); ++li)
+ cmOStringStream ss;
+ const char* sep = "";
+ typedef cmTargetInternals::TargetPropertyEntry
+ TargetPropertyEntry;
+ for(std::vector<TargetPropertyEntry*>::const_iterator
+ i = this->Internal->SourceEntries.begin();
+ i != this->Internal->SourceEntries.end(); ++i)
{
- if(cmHasLiteralPrefix(*li, "$<TARGET_OBJECTS:") &&
- (*li)[li->size() - 1] == '>')
- {
- std::string objLibName = li->substr(17, li->size()-18);
+ std::string entry = (*i)->ge->GetInput();
- if (cmGeneratorExpression::Find(objLibName) != std::string::npos)
+ std::vector<std::string> files;
+ cmSystemTools::ExpandListArgument(entry, files);
+ for (std::vector<std::string>::const_iterator
+ li = files.begin(); li != files.end(); ++li)
+ {
+ if(cmHasLiteralPrefix(*li, "$<TARGET_OBJECTS:") &&
+ (*li)[li->size() - 1] == '>')
{
- ss << sep;
- sep = ";";
- ss << *li;
- continue;
- }
+ std::string objLibName = li->substr(17, li->size()-18);
- 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 $<TARGET_OBJECTS> "
- "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 (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;
+ }
+ if (!noMessage)
+ {
+ e << "Target \"" << this->Name << "\" contains "
+ "$<TARGET_OBJECTS> 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 (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<std::string>& languages,
+ UNORDERED_SET<std::string>& 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<std::string>& Languages;
+ UNORDERED_SET<std::string>& Languages;
cmTarget const* HeadTarget;
cmMakefile* Makefile;
const cmTarget* Target;
@@ -3445,7 +3445,7 @@ class cmTargetSelectLinker
cmTarget const* Target;
cmMakefile* Makefile;
cmGlobalGenerator* GG;
- std::set<std::string> Preferred;
+ UNORDERED_SET<std::string> 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<std::string>::const_iterator
+ for(UNORDERED_SET<std::string>::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<std::string> languages;
+ UNORDERED_SET<std::string> languages;
LinkImplementation const* impl = this->GetLinkImplementation(config);
for(std::vector<std::string>::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<std::string>::const_iterator li = languages.begin();
+ for(UNORDERED_SET<std::string>::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<std::string>::const_iterator sit = languages.begin();
+ for(UNORDERED_SET<std::string>::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<typename PropertyType>
-PropertyType getTypedProperty(cmTarget const* tgt, const char *prop,
+PropertyType getTypedProperty(cmTarget const* tgt, const std::string& prop,
PropertyType *);
//----------------------------------------------------------------------------
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);
}
@@ -4849,7 +4850,7 @@ bool getTypedProperty<bool>(cmTarget const* tgt, const char *prop, bool *)
//----------------------------------------------------------------------------
template<>
const char *getTypedProperty<const char *>(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<PropertyType>(tgt, p.c_str(),
+ PropertyType propContent = getTypedProperty<PropertyType>(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<cmTarget const*>::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<PropertyType>(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<cmLinkItem> 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<std::string> emitted;
+ UNORDERED_SET<std::string> emitted;
for(std::vector<cmLinkItem>::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<std::string> emittedBools;
+ static std::string strBool = "COMPATIBLE_INTERFACE_BOOL";
std::set<std::string> emittedStrings;
+ static std::string strString = "COMPATIBLE_INTERFACE_STRING";
std::set<std::string> emittedMinNumbers;
+ static std::string strNumMin = "COMPATIBLE_INTERFACE_NUMBER_MIN";
std::set<std::string> 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<bool>(this, li->Target,
- std::string("COMPATIBLE_INTERFACE_BOOL"),
+ strBool,
emittedBools, config, BoolType, 0);
if (cmSystemTools::GetErrorOccuredFlag())
{
return;
}
checkPropertyConsistency<const char *>(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<const char *>(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<const char *>(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<std::string> props;
std::set<std::string>::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();