From d95651e15abbe6dcb771b776dfc69a1412dd0400 Mon Sep 17 00:00:00 2001 From: Stephen Kelly Date: Thu, 6 Jun 2013 18:17:10 +0200 Subject: [PATCH 1/4] Overload cmLocalGenerator::AppendDefines to add a list. --- Source/cmLocalGenerator.cxx | 6 ++++++ Source/cmLocalGenerator.h | 3 +++ 2 files changed, 9 insertions(+) diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx index 00846d5f8..70d7d16f4 100644 --- a/Source/cmLocalGenerator.cxx +++ b/Source/cmLocalGenerator.cxx @@ -2301,7 +2301,13 @@ void cmLocalGenerator::AppendDefines(std::set& defines, // Expand the list of definitions. std::vector defines_vec; cmSystemTools::ExpandListArgument(defines_list, defines_vec); + this->AppendDefines(defines, defines_vec); +} +//---------------------------------------------------------------------------- +void cmLocalGenerator::AppendDefines(std::set& defines, + const std::vector &defines_vec) +{ for(std::vector::const_iterator di = defines_vec.begin(); di != defines_vec.end(); ++di) { diff --git a/Source/cmLocalGenerator.h b/Source/cmLocalGenerator.h index f35ef8e2b..f5cd7fdd4 100644 --- a/Source/cmLocalGenerator.h +++ b/Source/cmLocalGenerator.h @@ -166,6 +166,9 @@ public: { this->AppendDefines(defines, defines_list.c_str()); } + void AppendDefines(std::set& defines, + const std::vector &defines_vec); + /** * Join a set of defines into a definesString with a space separator. */ From afc9243c325c37ac7364af12a10adffd7dd81d25 Mon Sep 17 00:00:00 2001 From: Stephen Kelly Date: Wed, 10 Jul 2013 15:22:59 +0200 Subject: [PATCH 2/4] Add an overload of cmIDEOptions::AddDefines taking a vector of strings. --- Source/cmIDEOptions.cxx | 5 +++++ Source/cmIDEOptions.h | 1 + 2 files changed, 6 insertions(+) diff --git a/Source/cmIDEOptions.cxx b/Source/cmIDEOptions.cxx index 76a60cfcd..34a9c7c78 100644 --- a/Source/cmIDEOptions.cxx +++ b/Source/cmIDEOptions.cxx @@ -165,6 +165,11 @@ void cmIDEOptions::AddDefines(const char* defines) cmSystemTools::ExpandListArgument(defines, this->Defines); } } +//---------------------------------------------------------------------------- +void cmIDEOptions::AddDefines(const std::vector &defines) +{ + this->Defines.insert(this->Defines.end(), defines.begin(), defines.end()); +} //---------------------------------------------------------------------------- void cmIDEOptions::AddFlag(const char* flag, const char* value) diff --git a/Source/cmIDEOptions.h b/Source/cmIDEOptions.h index e556bdeca..e78af3ee4 100644 --- a/Source/cmIDEOptions.h +++ b/Source/cmIDEOptions.h @@ -27,6 +27,7 @@ public: // Store definitions and flags. void AddDefine(const std::string& define); void AddDefines(const char* defines); + void AddDefines(const std::vector &defines); void AddFlag(const char* flag, const char* value); void RemoveFlag(const char* flag); const char* GetFlag(const char* flag); From 184121538c2576b2113c0e256ecb0cd9ac354134 Mon Sep 17 00:00:00 2001 From: Stephen Kelly Date: Thu, 6 Jun 2013 18:13:35 +0200 Subject: [PATCH 3/4] Refactor cmTarget::GetCompileDefinitions to use an out-vector, not a string. Refactor to create AddCompileDefinitions. --- Source/cmExtraCodeBlocksGenerator.cxx | 18 +++++++----------- Source/cmExtraSublimeTextGenerator.cxx | 2 +- Source/cmGlobalXCodeGenerator.cxx | 5 +++-- Source/cmLocalGenerator.cxx | 11 +++++++++++ Source/cmLocalGenerator.h | 2 ++ Source/cmLocalUnixMakefileGenerator3.cxx | 4 ++-- Source/cmLocalVisualStudio6Generator.cxx | 20 +++++--------------- Source/cmLocalVisualStudio7Generator.cxx | 4 +++- Source/cmMakefileTargetGenerator.cxx | 5 ++--- Source/cmNinjaTargetGenerator.cxx | 5 ++--- Source/cmQtAutomoc.cxx | 10 ++++++---- Source/cmTarget.cxx | 8 +++++--- Source/cmTarget.h | 3 ++- Source/cmVisualStudio10TargetGenerator.cxx | 5 +++-- 14 files changed, 54 insertions(+), 48 deletions(-) diff --git a/Source/cmExtraCodeBlocksGenerator.cxx b/Source/cmExtraCodeBlocksGenerator.cxx index f6f4ceff3..dfbb1c0ad 100644 --- a/Source/cmExtraCodeBlocksGenerator.cxx +++ b/Source/cmExtraCodeBlocksGenerator.cxx @@ -621,19 +621,15 @@ void cmExtraCodeBlocksGenerator::AppendTarget(cmGeneratedFileStream& fout, ->GetGeneratorTarget(target); // the compilerdefines for this target - std::string cdefs = target->GetCompileDefinitions(buildType); + std::vector cdefs; + target->GetCompileDefinitions(cdefs, buildType); - if(!cdefs.empty()) + // Expand the list. + for(std::vector::const_iterator di = cdefs.begin(); + di != cdefs.end(); ++di) { - // Expand the list. - std::vector defs; - cmSystemTools::ExpandListArgument(cdefs.c_str(), defs); - for(std::vector::const_iterator di = defs.begin(); - di != defs.end(); ++di) - { - cmXMLSafe safedef(di->c_str()); - fout <<" \n"; - } + cmXMLSafe safedef(di->c_str()); + fout <<" \n"; } // the include directories for this target diff --git a/Source/cmExtraSublimeTextGenerator.cxx b/Source/cmExtraSublimeTextGenerator.cxx index 012013c38..d92543298 100644 --- a/Source/cmExtraSublimeTextGenerator.cxx +++ b/Source/cmExtraSublimeTextGenerator.cxx @@ -463,7 +463,7 @@ ComputeDefines(cmSourceFile *source, cmLocalGenerator* lg, cmTarget *target, } // Add preprocessor definitions for this target and configuration. - lg->AppendDefines(defines, target->GetCompileDefinitions(config)); + lg->AddCompileDefinitions(defines, target, config); lg->AppendDefines(defines, source->GetProperty("COMPILE_DEFINITIONS")); { std::string defPropName = "COMPILE_DEFINITIONS_"; diff --git a/Source/cmGlobalXCodeGenerator.cxx b/Source/cmGlobalXCodeGenerator.cxx index 9cfbe42a0..63de1a51d 100644 --- a/Source/cmGlobalXCodeGenerator.cxx +++ b/Source/cmGlobalXCodeGenerator.cxx @@ -1741,8 +1741,9 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmTarget& target, this->AppendDefines(ppDefs, exportMacro); } cmGeneratorTarget *gtgt = this->GetGeneratorTarget(&target); - this->AppendDefines(ppDefs, - target.GetCompileDefinitions(configName).c_str()); + std::vector targetDefines; + target.GetCompileDefinitions(targetDefines, configName); + this->AppendDefines(ppDefs, targetDefines); buildSettings->AddAttribute ("GCC_PREPROCESSOR_DEFINITIONS", ppDefs.CreateList()); diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx index 70d7d16f4..624005410 100644 --- a/Source/cmLocalGenerator.cxx +++ b/Source/cmLocalGenerator.cxx @@ -1338,6 +1338,17 @@ std::string cmLocalGenerator::GetIncludeFlags( return flags; } +//---------------------------------------------------------------------------- +void cmLocalGenerator::AddCompileDefinitions(std::set& defines, + cmTarget* target, + const char* config) +{ + std::vector targetDefines; + target->GetCompileDefinitions(targetDefines, + config); + this->AppendDefines(defines, targetDefines); +} + //---------------------------------------------------------------------------- void cmLocalGenerator::AddCompileOptions( std::string& flags, cmTarget* target, diff --git a/Source/cmLocalGenerator.h b/Source/cmLocalGenerator.h index f5cd7fdd4..5c644d198 100644 --- a/Source/cmLocalGenerator.h +++ b/Source/cmLocalGenerator.h @@ -223,6 +223,8 @@ public: bool stripImplicitInclDirs = true); void AddCompileOptions(std::string& flags, cmTarget* target, const char* lang, const char* config); + void AddCompileDefinitions(std::set& defines, cmTarget* target, + const char* config); /** Compute the language used to compile the given source file. */ const char* GetSourceFileLanguage(const cmSourceFile& source); diff --git a/Source/cmLocalUnixMakefileGenerator3.cxx b/Source/cmLocalUnixMakefileGenerator3.cxx index 78a70f83e..1d1acfdff 100644 --- a/Source/cmLocalUnixMakefileGenerator3.cxx +++ b/Source/cmLocalUnixMakefileGenerator3.cxx @@ -1962,8 +1962,8 @@ void cmLocalUnixMakefileGenerator3 // Build a list of preprocessor definitions for the target. std::set defines; - this->AppendDefines(defines, target.GetCompileDefinitions( - this->ConfigurationName.c_str())); + this->AddCompileDefinitions(defines, &target, + this->ConfigurationName.c_str()); if(!defines.empty()) { cmakefileStream diff --git a/Source/cmLocalVisualStudio6Generator.cxx b/Source/cmLocalVisualStudio6Generator.cxx index 0b61e1db5..df6e1f1e9 100644 --- a/Source/cmLocalVisualStudio6Generator.cxx +++ b/Source/cmLocalVisualStudio6Generator.cxx @@ -1701,21 +1701,11 @@ void cmLocalVisualStudio6Generator std::set minsizeDefinesSet; std::set debugrelDefinesSet; - this->AppendDefines( - definesSet, - target.GetCompileDefinitions(0)); - this->AppendDefines( - debugDefinesSet, - target.GetCompileDefinitions("DEBUG")); - this->AppendDefines( - releaseDefinesSet, - target.GetCompileDefinitions("RELEASE")); - this->AppendDefines( - minsizeDefinesSet, - target.GetCompileDefinitions("MINSIZEREL")); - this->AppendDefines( - debugrelDefinesSet, - target.GetCompileDefinitions("RELWITHDEBINFO")); + this->AddCompileDefinitions(definesSet, &target, 0); + this->AddCompileDefinitions(debugDefinesSet, &target, "DEBUG"); + this->AddCompileDefinitions(releaseDefinesSet, &target, "RELEASE"); + this->AddCompileDefinitions(minsizeDefinesSet, &target, "MINSIZEREL"); + this->AddCompileDefinitions(debugrelDefinesSet, &target, "RELWITHDEBINFO"); std::string defines = " "; std::string debugDefines = " "; diff --git a/Source/cmLocalVisualStudio7Generator.cxx b/Source/cmLocalVisualStudio7Generator.cxx index 1d2f7095a..9ecd53db4 100644 --- a/Source/cmLocalVisualStudio7Generator.cxx +++ b/Source/cmLocalVisualStudio7Generator.cxx @@ -746,7 +746,9 @@ void cmLocalVisualStudio7Generator::WriteConfiguration(std::ostream& fout, targetOptions.ParseFinish(); cmGeneratorTarget* gt = this->GlobalGenerator->GetGeneratorTarget(&target); - targetOptions.AddDefines(target.GetCompileDefinitions(configName).c_str()); + std::vector targetDefines; + target.GetCompileDefinitions(targetDefines, configName); + targetOptions.AddDefines(targetDefines); targetOptions.SetVerboseMakefile( this->Makefile->IsOn("CMAKE_VERBOSE_MAKEFILE")); diff --git a/Source/cmMakefileTargetGenerator.cxx b/Source/cmMakefileTargetGenerator.cxx index 1492dfabe..b19d37d56 100644 --- a/Source/cmMakefileTargetGenerator.cxx +++ b/Source/cmMakefileTargetGenerator.cxx @@ -309,9 +309,8 @@ std::string cmMakefileTargetGenerator::GetDefines(const std::string &l) } // Add preprocessor definitions for this target and configuration. - this->LocalGenerator->AppendDefines - (defines, this->Target->GetCompileDefinitions( - this->LocalGenerator->ConfigurationName.c_str())); + this->LocalGenerator->AddCompileDefinitions(defines, this->Target, + this->LocalGenerator->ConfigurationName.c_str()); std::string definesString; this->LocalGenerator->JoinDefines(defines, definesString, lang); diff --git a/Source/cmNinjaTargetGenerator.cxx b/Source/cmNinjaTargetGenerator.cxx index 65173ca26..88ab72752 100644 --- a/Source/cmNinjaTargetGenerator.cxx +++ b/Source/cmNinjaTargetGenerator.cxx @@ -201,9 +201,8 @@ ComputeDefines(cmSourceFile *source, const std::string& language) } // Add preprocessor definitions for this target and configuration. - this->LocalGenerator->AppendDefines - (defines, - this->Target->GetCompileDefinitions(this->GetConfigName())); + this->LocalGenerator->AddCompileDefinitions(defines, this->Target, + this->GetConfigName()); this->LocalGenerator->AppendDefines (defines, source->GetProperty("COMPILE_DEFINITIONS")); diff --git a/Source/cmQtAutomoc.cxx b/Source/cmQtAutomoc.cxx index 34b3c7e4a..93e39abeb 100644 --- a/Source/cmQtAutomoc.cxx +++ b/Source/cmQtAutomoc.cxx @@ -175,15 +175,17 @@ static void GetCompileDefinitionsAndDirectories(cmTarget *target, incs += *incDirIt; } - defs = target->GetCompileDefinitions(config); + std::set defines; + localGen->AddCompileDefinitions(defines, target, config); - const char *tmp = makefile->GetProperty("COMPILE_DEFINITIONS"); sep = ""; - if (tmp) + for(std::set::const_iterator defIt = defines.begin(); + defIt != defines.end(); + ++defIt) { defs += sep; sep = ";"; - defs += tmp; + defs += *defIt; } } diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx index a90fa74cb..02dcf815c 100644 --- a/Source/cmTarget.cxx +++ b/Source/cmTarget.cxx @@ -3384,7 +3384,8 @@ void cmTarget::GetCompileOptions(std::vector &result, } //---------------------------------------------------------------------------- -std::string cmTarget::GetCompileDefinitions(const char *config) +void cmTarget::GetCompileDefinitions(std::vector &list, + const char *config) { const char *configProp = 0; if (config) @@ -3419,7 +3420,8 @@ std::string cmTarget::GetCompileDefinitions(const char *config) if (libs.empty()) { - return result; + cmSystemTools::ExpandListArgument(result, list); + return; } std::string sep; @@ -3467,7 +3469,7 @@ std::string cmTarget::GetCompileDefinitions(const char *config) = true; } - return result; + cmSystemTools::ExpandListArgument(result, list); } //---------------------------------------------------------------------------- diff --git a/Source/cmTarget.h b/Source/cmTarget.h index 3bc0ab2e2..ab3dff21c 100644 --- a/Source/cmTarget.h +++ b/Source/cmTarget.h @@ -442,7 +442,8 @@ public: If no macro should be defined null is returned. */ const char* GetExportMacro(); - std::string GetCompileDefinitions(const char *config); + void GetCompileDefinitions(std::vector &result, + const char *config); // Compute the set of languages compiled by the target. This is // computed every time it is called because the languages can change diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx index 50f195e5a..d59de116c 100644 --- a/Source/cmVisualStudio10TargetGenerator.cxx +++ b/Source/cmVisualStudio10TargetGenerator.cxx @@ -1337,8 +1337,9 @@ bool cmVisualStudio10TargetGenerator::ComputeClOptions( clOptions.AddFlag("AssemblerListingLocation", asmLocation.c_str()); clOptions.Parse(flags.c_str()); clOptions.Parse(defineFlags.c_str()); - clOptions.AddDefines(this->Target->GetCompileDefinitions( - configName.c_str()).c_str()); + std::vector targetDefines; + this->Target->GetCompileDefinitions(targetDefines, configName.c_str()); + clOptions.AddDefines(targetDefines); clOptions.SetVerboseMakefile( this->Makefile->IsOn("CMAKE_VERBOSE_MAKEFILE")); From d7dd01083a99055d689c80fe28bbc79a11bf3da1 Mon Sep 17 00:00:00 2001 From: Stephen Kelly Date: Wed, 12 Jun 2013 10:12:51 +0200 Subject: [PATCH 4/4] Add target property debugging for COMPILE_DEFINITIONS Use constructs similar to those for COMPILE_OPTIONS. This is a little different because there is a command to remove_definitions(), so we can't populate the equivalent target property until generate-time in cmGlobalGenerator. --- Source/cmGlobalGenerator.cxx | 13 +- Source/cmMakefile.cxx | 41 ++++++ Source/cmMakefile.h | 5 + Source/cmTarget.cxx | 236 +++++++++++++++++++++++++---------- Source/cmTarget.h | 3 + 5 files changed, 230 insertions(+), 68 deletions(-) diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx index ad74767f7..00226055d 100644 --- a/Source/cmGlobalGenerator.cxx +++ b/Source/cmGlobalGenerator.cxx @@ -1121,8 +1121,9 @@ void cmGlobalGenerator::CreateGeneratorTargets() cmGeneratorTargetsType generatorTargets; cmMakefile *mf = this->LocalGenerators[i]->GetMakefile(); - const char *noconfig_compile_definitions = - mf->GetProperty("COMPILE_DEFINITIONS"); + + const std::vector noconfig_compile_definitions = + mf->GetCompileDefinitionsEntries(); std::vector configs; mf->GetConfigurations(configs); @@ -1134,7 +1135,13 @@ void cmGlobalGenerator::CreateGeneratorTargets() cmTarget* t = &ti->second; { - t->AppendProperty("COMPILE_DEFINITIONS", noconfig_compile_definitions); + for (std::vector::const_iterator it + = noconfig_compile_definitions.begin(); + it != noconfig_compile_definitions.end(); ++it) + { + t->InsertCompileDefinition(*it); + } + for(std::vector::const_iterator ci = configs.begin(); ci != configs.end(); ++ci) { diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx index f3a66bab8..d94c93d28 100644 --- a/Source/cmMakefile.cxx +++ b/Source/cmMakefile.cxx @@ -1505,6 +1505,12 @@ void cmMakefile::InitializeFromParent() parentOptions.begin(), parentOptions.end()); + const std::vector parentDefines = + parent->GetCompileDefinitionsEntries(); + this->CompileDefinitionsEntries.insert(this->CompileDefinitionsEntries.end(), + parentDefines.begin(), + parentDefines.end()); + this->SystemIncludeDirectories = parent->SystemIncludeDirectories; // define flags @@ -3493,6 +3499,19 @@ void cmMakefile::SetProperty(const char* prop, const char* value) this->CompileOptionsEntries.push_back(cmValueWithOrigin(value, lfbt)); return; } + if (propname == "COMPILE_DEFINITIONS") + { + this->CompileDefinitionsEntries.clear(); + if (!value) + { + return; + } + cmListFileBacktrace lfbt; + this->GetBacktrace(lfbt); + cmValueWithOrigin entry(value, lfbt); + this->CompileDefinitionsEntries.push_back(entry); + return; + } if ( propname == "INCLUDE_REGULAR_EXPRESSION" ) { @@ -3540,6 +3559,14 @@ void cmMakefile::AppendProperty(const char* prop, const char* value, cmValueWithOrigin(value, lfbt)); return; } + if (propname == "COMPILE_DEFINITIONS") + { + cmListFileBacktrace lfbt; + this->GetBacktrace(lfbt); + this->CompileDefinitionsEntries.push_back( + cmValueWithOrigin(value, lfbt)); + return; + } if ( propname == "LINK_DIRECTORIES" ) { std::vector varArgsExpanded; @@ -3679,6 +3706,20 @@ const char *cmMakefile::GetProperty(const char* prop, } return output.c_str(); } + else if (!strcmp("COMPILE_DEFINITIONS",prop)) + { + std::string sep; + for (std::vector::const_iterator + it = this->CompileDefinitionsEntries.begin(), + end = this->CompileDefinitionsEntries.end(); + it != end; ++it) + { + output += sep; + output += it->Value; + sep = ";"; + } + return output.c_str(); + } bool chain = false; const char *retVal = diff --git a/Source/cmMakefile.h b/Source/cmMakefile.h index 42971559e..1b1077310 100644 --- a/Source/cmMakefile.h +++ b/Source/cmMakefile.h @@ -871,6 +871,10 @@ public: { return this->CompileOptionsEntries; } + std::vector GetCompileDefinitionsEntries() const + { + return this->CompileDefinitionsEntries; + } bool IsGeneratingBuildSystem(){ return this->GeneratingBuildSystem; } void SetGeneratingBuildSystem(){ this->GeneratingBuildSystem = true; } @@ -925,6 +929,7 @@ protected: std::vector IncludeDirectoriesEntries; std::vector CompileOptionsEntries; + std::vector CompileDefinitionsEntries; // Track the value of the computed DEFINITIONS property. void AddDefineFlag(const char*, std::string&); diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx index 02dcf815c..a56eb9eed 100644 --- a/Source/cmTarget.cxx +++ b/Source/cmTarget.cxx @@ -141,13 +141,15 @@ public: }; std::vector IncludeDirectoriesEntries; std::vector CompileOptionsEntries; + std::vector CompileDefinitionsEntries; std::vector LinkInterfacePropertyEntries; std::map > CachedLinkInterfaceIncludeDirectoriesEntries; std::map > CachedLinkInterfaceCompileOptionsEntries; - std::map CachedLinkInterfaceCompileDefinitions; + std::map > + CachedLinkInterfaceCompileDefinitionsEntries; std::map CacheLinkInterfaceIncludeDirectoriesDone; std::map CacheLinkInterfaceCompileDefinitionsDone; @@ -186,6 +188,7 @@ cmTargetInternals::~cmTargetInternals() { deleteAndClear(this->CachedLinkInterfaceIncludeDirectoriesEntries); deleteAndClear(this->CachedLinkInterfaceCompileOptionsEntries); + deleteAndClear(this->CachedLinkInterfaceCompileDefinitionsEntries); } //---------------------------------------------------------------------------- @@ -205,6 +208,7 @@ cmTarget::cmTarget() this->BuildInterfaceIncludesAppended = false; this->DebugIncludesDone = false; this->DebugCompileOptionsDone = false; + this->DebugCompileDefinitionsDone = false; } //---------------------------------------------------------------------------- @@ -2845,6 +2849,17 @@ void cmTarget::SetProperty(const char* prop, const char* value) new cmTargetInternals::TargetPropertyEntry(cge)); return; } + if(strcmp(prop,"COMPILE_DEFINITIONS") == 0) + { + cmListFileBacktrace lfbt; + this->Makefile->GetBacktrace(lfbt); + cmGeneratorExpression ge(lfbt); + deleteAndClear(this->Internal->CompileDefinitionsEntries); + cmsys::auto_ptr cge = ge.Parse(value); + this->Internal->CompileDefinitionsEntries.push_back( + new cmTargetInternals::TargetPropertyEntry(cge)); + return; + } if(strcmp(prop,"EXPORT_NAME") == 0 && this->IsImported()) { cmOStringStream e; @@ -2896,6 +2911,15 @@ void cmTarget::AppendProperty(const char* prop, const char* value, new cmTargetInternals::TargetPropertyEntry(ge.Parse(value))); return; } + if(strcmp(prop,"COMPILE_DEFINITIONS") == 0) + { + cmListFileBacktrace lfbt; + this->Makefile->GetBacktrace(lfbt); + cmGeneratorExpression ge(lfbt); + this->Internal->CompileDefinitionsEntries.push_back( + new cmTargetInternals::TargetPropertyEntry(ge.Parse(value))); + return; + } if(strcmp(prop,"EXPORT_NAME") == 0 && this->IsImported()) { cmOStringStream e; @@ -2999,6 +3023,20 @@ void cmTarget::InsertCompileOption(const cmValueWithOrigin &entry, new cmTargetInternals::TargetPropertyEntry(ge.Parse(entry.Value))); } +//---------------------------------------------------------------------------- +void cmTarget::InsertCompileDefinition(const cmValueWithOrigin &entry, + bool before) +{ + cmGeneratorExpression ge(entry.Backtrace); + + std::vector::iterator position + = before ? this->Internal->CompileDefinitionsEntries.begin() + : this->Internal->CompileDefinitionsEntries.end(); + + this->Internal->CompileDefinitionsEntries.insert(position, + new cmTargetInternals::TargetPropertyEntry(ge.Parse(entry.Value))); +} + //---------------------------------------------------------------------------- static void processIncludeDirectories(cmTarget *tgt, const std::vector &entries, @@ -3231,12 +3269,12 @@ std::vector cmTarget::GetIncludeDirectories(const char *config) } //---------------------------------------------------------------------------- -static void processCompileOptions(cmTarget *tgt, +static void processCompileOptionsInternal(cmTarget *tgt, const std::vector &entries, std::vector &options, std::set &uniqueOptions, cmGeneratorExpressionDAGChecker *dagChecker, - const char *config, bool debugOptions) + const char *config, bool debugOptions, const char *logName) { cmMakefile *mf = tgt->GetMakefile(); @@ -3281,13 +3319,26 @@ static void processCompileOptions(cmTarget *tgt, if (!usedOptions.empty()) { mf->GetCMakeInstance()->IssueMessage(cmake::LOG, - std::string("Used compile options for target ") + std::string("Used compile ") + logName + + std::string(" for target ") + tgt->GetName() + ":\n" + usedOptions, (*it)->ge->GetBacktrace()); } } } +//---------------------------------------------------------------------------- +static void processCompileOptions(cmTarget *tgt, + const std::vector &entries, + std::vector &options, + std::set &uniqueOptions, + cmGeneratorExpressionDAGChecker *dagChecker, + const char *config, bool debugOptions) +{ + processCompileOptionsInternal(tgt, entries, options, uniqueOptions, + dagChecker, config, debugOptions, "options"); +} + //---------------------------------------------------------------------------- void cmTarget::GetCompileOptions(std::vector &result, const char *config) @@ -3383,93 +3434,129 @@ void cmTarget::GetCompileOptions(std::vector &result, } } +//---------------------------------------------------------------------------- +static void processCompileDefinitions(cmTarget *tgt, + const std::vector &entries, + std::vector &options, + std::set &uniqueOptions, + cmGeneratorExpressionDAGChecker *dagChecker, + const char *config, bool debugOptions) +{ + processCompileOptionsInternal(tgt, entries, options, uniqueOptions, + dagChecker, config, debugOptions, + "definitions"); +} + //---------------------------------------------------------------------------- void cmTarget::GetCompileDefinitions(std::vector &list, const char *config) { - const char *configProp = 0; - if (config) - { - std::string configPropName; - configPropName = "COMPILE_DEFINITIONS_" + cmSystemTools::UpperCase(config); - configProp = this->GetProperty(configPropName.c_str()); - } - - const char *noconfigProp = this->GetProperty("COMPILE_DEFINITIONS"); + std::set uniqueOptions; cmListFileBacktrace lfbt; + cmGeneratorExpressionDAGChecker dagChecker(lfbt, - this->GetName(), - "COMPILE_DEFINITIONS", 0, 0); + this->GetName(), + "COMPILE_DEFINITIONS", 0, 0); - std::string defsString = (noconfigProp ? noconfigProp : ""); - if (configProp && noconfigProp) + std::vector debugProperties; + const char *debugProp = + this->Makefile->GetDefinition("CMAKE_DEBUG_TARGET_PROPERTIES"); + if (debugProp) { - defsString += ";"; - } - defsString += (configProp ? configProp : ""); - - cmGeneratorExpression ge(lfbt); - std::string result = ge.Parse(defsString.c_str())->Evaluate(this->Makefile, - config, - false, - this, - &dagChecker); - - std::vector libs; - this->GetDirectLinkLibraries(config, libs, this); - - if (libs.empty()) - { - cmSystemTools::ExpandListArgument(result, list); - return; + cmSystemTools::ExpandListArgument(debugProp, debugProperties); } - std::string sep; - std::string depString; - for (std::vector::const_iterator it = libs.begin(); - it != libs.end(); ++it) + bool debugDefines = !this->DebugCompileDefinitionsDone + && std::find(debugProperties.begin(), + debugProperties.end(), + "COMPILE_DEFINITIONS") + != debugProperties.end(); + + if (this->Makefile->IsGeneratingBuildSystem()) { - if ((cmGeneratorExpression::IsValidTargetName(it->c_str()) - || cmGeneratorExpression::Find(it->c_str()) != std::string::npos) - && this->Makefile->FindTargetToUse(it->c_str())) - { - depString += sep + "$"; - sep = ";"; - } + this->DebugCompileDefinitionsDone = true; } + processCompileDefinitions(this, + this->Internal->CompileDefinitionsEntries, + list, + uniqueOptions, + &dagChecker, + config, + debugDefines); + std::string configString = config ? config : ""; if (!this->Internal->CacheLinkInterfaceCompileDefinitionsDone[configString]) { - cmGeneratorExpression ge2(lfbt); - cmsys::auto_ptr cge2 = - ge2.Parse(depString); - this->Internal->CachedLinkInterfaceCompileDefinitions[configString] = - cge2->Evaluate(this->Makefile, - config, - false, - this, - &dagChecker); - } - if (!this->Internal->CachedLinkInterfaceCompileDefinitions[configString] - .empty()) - { - result += (result.empty() ? "" : ";") - + this->Internal->CachedLinkInterfaceCompileDefinitions[configString]; + for (std::vector::const_iterator + it = this->Internal->LinkInterfacePropertyEntries.begin(), + end = this->Internal->LinkInterfacePropertyEntries.end(); + it != end; ++it) + { + { + cmGeneratorExpression ge(lfbt); + cmsys::auto_ptr cge = + ge.Parse(it->Value); + std::string targetResult = cge->Evaluate(this->Makefile, config, + false, this, 0, 0); + if (!this->Makefile->FindTargetToUse(targetResult.c_str())) + { + continue; + } + } + std::string defsGenex = "$Value + ",INTERFACE_COMPILE_DEFINITIONS>"; + if (cmGeneratorExpression::Find(it->Value) != std::string::npos) + { + // Because it->Value is a generator expression, ensure that it + // evaluates to the non-empty string before being used in the + // TARGET_PROPERTY expression. + defsGenex = "$<$Value + ">:" + defsGenex + ">"; + } + cmGeneratorExpression ge(it->Backtrace); + cmsys::auto_ptr cge = ge.Parse( + defsGenex); + + this->Internal + ->CachedLinkInterfaceCompileDefinitionsEntries[configString].push_back( + new cmTargetInternals::TargetPropertyEntry(cge, + it->Value)); + } + if (config) + { + std::string configPropName = "COMPILE_DEFINITIONS_" + + cmSystemTools::UpperCase(config); + const char *configProp = this->GetProperty(configPropName.c_str()); + std::string defsString = (configProp ? configProp : ""); + + cmGeneratorExpression ge(lfbt); + cmsys::auto_ptr cge = + ge.Parse(defsString); + this->Internal + ->CachedLinkInterfaceCompileDefinitionsEntries[configString].push_back( + new cmTargetInternals::TargetPropertyEntry(cge)); + } + } + processCompileDefinitions(this, + this->Internal->CachedLinkInterfaceCompileDefinitionsEntries[configString], + list, + uniqueOptions, + &dagChecker, + config, + debugDefines); + if (!this->Makefile->IsGeneratingBuildSystem()) { - this->Internal->CachedLinkInterfaceCompileDefinitions[configString] = ""; + deleteAndClear(this->Internal + ->CachedLinkInterfaceCompileDefinitionsEntries); } else { this->Internal->CacheLinkInterfaceCompileDefinitionsDone[configString] = true; } - - cmSystemTools::ExpandListArgument(result, list); } //---------------------------------------------------------------------------- @@ -3841,6 +3928,24 @@ const char *cmTarget::GetProperty(const char* prop, } return output.c_str(); } + if(strcmp(prop,"COMPILE_DEFINITIONS") == 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 (strcmp(prop,"IMPORTED") == 0) { @@ -6566,6 +6671,7 @@ cmTargetInternalPointer::~cmTargetInternalPointer() { deleteAndClear(this->Pointer->IncludeDirectoriesEntries); deleteAndClear(this->Pointer->CompileOptionsEntries); + deleteAndClear(this->Pointer->CompileDefinitionsEntries); delete this->Pointer; } diff --git a/Source/cmTarget.h b/Source/cmTarget.h index ab3dff21c..adaae47c5 100644 --- a/Source/cmTarget.h +++ b/Source/cmTarget.h @@ -514,6 +514,8 @@ public: bool before = false); void InsertCompileOption(const cmValueWithOrigin &entry, bool before = false); + void InsertCompileDefinition(const cmValueWithOrigin &entry, + bool before = false); void AppendBuildInterfaceIncludes(); @@ -650,6 +652,7 @@ private: bool IsImportedTarget; bool DebugIncludesDone; bool DebugCompileOptionsDone; + bool DebugCompileDefinitionsDone; mutable std::set LinkImplicitNullProperties; bool BuildInterfaceIncludesAppended;