diff options
author | Brad King <brad.king@kitware.com> | 2013-06-03 13:57:44 (GMT) |
---|---|---|
committer | CMake Topic Stage <kwrobot@kitware.com> | 2013-06-03 13:57:44 (GMT) |
commit | e57b6a25211ea28b7b01aadfc3aaf1de79455bdb (patch) | |
tree | 3957355de7d91f18e663fc1ed13185bf31f35125 /Source/cmTarget.cxx | |
parent | bcc29c56a599baa3e2d8bd1d56e3727911a1c7d7 (diff) | |
parent | 24466f22c0c0e3235f0a21bd2a298c39df50e2f3 (diff) | |
download | CMake-e57b6a25211ea28b7b01aadfc3aaf1de79455bdb.zip CMake-e57b6a25211ea28b7b01aadfc3aaf1de79455bdb.tar.gz CMake-e57b6a25211ea28b7b01aadfc3aaf1de79455bdb.tar.bz2 |
Merge topic 'target-COMPILE_OPTIONS'
24466f2 Add target_compile_options command.
80ca9c4 Add COMPILE_OPTIONS target property.
7cb2308 cmTarget: Rename LinkInterfaceIncludeDirectoriesEntries
47f80d9 cmTarget: Rename struct to be more re-usable.
1319a14 Add <LANG>_COMPILER_ID generator expressions.
3549676 Add cmLocalGenerator::GetCompileOptions.
f3ad863 VS6: Rename some variables to correspond to config values.
Diffstat (limited to 'Source/cmTarget.cxx')
-rw-r--r-- | Source/cmTarget.cxx | 292 |
1 files changed, 265 insertions, 27 deletions
diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx index 5628971..f1d0ac3 100644 --- a/Source/cmTarget.cxx +++ b/Source/cmTarget.cxx @@ -130,31 +130,35 @@ public: typedef std::map<cmSourceFile*, SourceEntry> SourceEntriesType; SourceEntriesType SourceEntries; - struct IncludeDirectoriesEntry { - IncludeDirectoriesEntry(cmsys::auto_ptr<cmCompiledGeneratorExpression> cge, + struct TargetPropertyEntry { + TargetPropertyEntry(cmsys::auto_ptr<cmCompiledGeneratorExpression> cge, const std::string &targetName = std::string()) : ge(cge), TargetName(targetName) {} const cmsys::auto_ptr<cmCompiledGeneratorExpression> ge; - std::vector<std::string> CachedIncludes; + std::vector<std::string> CachedEntries; const std::string TargetName; }; - std::vector<IncludeDirectoriesEntry*> IncludeDirectoriesEntries; - std::vector<cmValueWithOrigin> LinkInterfaceIncludeDirectoriesEntries; + std::vector<TargetPropertyEntry*> IncludeDirectoriesEntries; + std::vector<TargetPropertyEntry*> CompileOptionsEntries; + std::vector<cmValueWithOrigin> LinkInterfacePropertyEntries; - std::map<std::string, std::vector<IncludeDirectoriesEntry*> > + std::map<std::string, std::vector<TargetPropertyEntry*> > CachedLinkInterfaceIncludeDirectoriesEntries; + std::map<std::string, std::vector<TargetPropertyEntry*> > + CachedLinkInterfaceCompileOptionsEntries; std::map<std::string, std::string> CachedLinkInterfaceCompileDefinitions; std::map<std::string, bool> CacheLinkInterfaceIncludeDirectoriesDone; std::map<std::string, bool> CacheLinkInterfaceCompileDefinitionsDone; + std::map<std::string, bool> CacheLinkInterfaceCompileOptionsDone; }; //---------------------------------------------------------------------------- void deleteAndClear( - std::vector<cmTargetInternals::IncludeDirectoriesEntry*> &entries) + std::vector<cmTargetInternals::TargetPropertyEntry*> &entries) { - for (std::vector<cmTargetInternals::IncludeDirectoriesEntry*>::const_iterator + for (std::vector<cmTargetInternals::TargetPropertyEntry*>::const_iterator it = entries.begin(), end = entries.end(); it != end; ++it) @@ -167,10 +171,10 @@ void deleteAndClear( //---------------------------------------------------------------------------- void deleteAndClear( std::map<std::string, - std::vector<cmTargetInternals::IncludeDirectoriesEntry*> > &entries) + std::vector<cmTargetInternals::TargetPropertyEntry*> > &entries) { for (std::map<std::string, - std::vector<cmTargetInternals::IncludeDirectoriesEntry*> >::iterator + std::vector<cmTargetInternals::TargetPropertyEntry*> >::iterator it = entries.begin(), end = entries.end(); it != end; ++it) { deleteAndClear(it->second); @@ -181,6 +185,7 @@ void deleteAndClear( cmTargetInternals::~cmTargetInternals() { deleteAndClear(this->CachedLinkInterfaceIncludeDirectoriesEntries); + deleteAndClear(this->CachedLinkInterfaceCompileOptionsEntries); } //---------------------------------------------------------------------------- @@ -199,6 +204,7 @@ cmTarget::cmTarget() this->IsImportedTarget = false; this->BuildInterfaceIncludesAppended = false; this->DebugIncludesDone = false; + this->DebugCompileOptionsDone = false; } //---------------------------------------------------------------------------- @@ -287,6 +293,32 @@ void cmTarget::DefineProperties(cmake *cm) "This is the configuration-specific version of COMPILE_DEFINITIONS."); cm->DefineProperty + ("COMPILE_OPTIONS", cmProperty::TARGET, + "List of options to pass to the compiler.", + "This property specifies the list of options specified " + "so far for this property. " + "This property exists on targets only. " + "\n" + "The target property values are used by the generators to set " + "the options for the compiler.\n" + "Contents of COMPILE_OPTIONS may use \"generator expressions\" with " + "the syntax \"$<...>\". " + CM_DOCUMENT_COMMAND_GENERATOR_EXPRESSIONS + CM_DOCUMENT_LANGUAGE_GENERATOR_EXPRESSIONS); + + cm->DefineProperty + ("INTERFACE_COMPILE_OPTIONS", cmProperty::TARGET, + "List of interface options to pass to the compiler.", + "Targets may populate this property to publish the compile options " + "required to compile against the headers for the target. Consuming " + "targets can add entries to their own COMPILE_OPTIONS property such " + "as $<TARGET_PROPERTY:foo,INTERFACE_COMPILE_OPTIONS> to use the " + "compile options specified in the interface of 'foo'." + "\n" + CM_DOCUMENT_COMMAND_GENERATOR_EXPRESSIONS + CM_DOCUMENT_LANGUAGE_GENERATOR_EXPRESSIONS); + + cm->DefineProperty ("DEFINE_SYMBOL", cmProperty::TARGET, "Define a symbol when compiling this target's sources.", "DEFINE_SYMBOL sets the name of the preprocessor symbol defined when " @@ -2751,7 +2783,18 @@ void cmTarget::SetProperty(const char* prop, const char* value) deleteAndClear(this->Internal->IncludeDirectoriesEntries); cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(value); this->Internal->IncludeDirectoriesEntries.push_back( - new cmTargetInternals::IncludeDirectoriesEntry(cge)); + new cmTargetInternals::TargetPropertyEntry(cge)); + return; + } + if(strcmp(prop,"COMPILE_OPTIONS") == 0) + { + cmListFileBacktrace lfbt; + this->Makefile->GetBacktrace(lfbt); + cmGeneratorExpression ge(lfbt); + deleteAndClear(this->Internal->CompileOptionsEntries); + cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(value); + this->Internal->CompileOptionsEntries.push_back( + new cmTargetInternals::TargetPropertyEntry(cge)); return; } if(strcmp(prop,"EXPORT_NAME") == 0 && this->IsImported()) @@ -2764,14 +2807,14 @@ void cmTarget::SetProperty(const char* prop, const char* value) } if (strcmp(prop, "LINK_LIBRARIES") == 0) { - this->Internal->LinkInterfaceIncludeDirectoriesEntries.clear(); + this->Internal->LinkInterfacePropertyEntries.clear(); if (cmGeneratorExpression::IsValidTargetName(value) || cmGeneratorExpression::Find(value) != std::string::npos) { cmListFileBacktrace lfbt; this->Makefile->GetBacktrace(lfbt); cmValueWithOrigin entry(value, lfbt); - this->Internal->LinkInterfaceIncludeDirectoriesEntries.push_back(entry); + this->Internal->LinkInterfacePropertyEntries.push_back(entry); } // Fall through } @@ -2793,7 +2836,16 @@ void cmTarget::AppendProperty(const char* prop, const char* value, this->Makefile->GetBacktrace(lfbt); cmGeneratorExpression ge(lfbt); this->Internal->IncludeDirectoriesEntries.push_back( - new cmTargetInternals::IncludeDirectoriesEntry(ge.Parse(value))); + new cmTargetInternals::TargetPropertyEntry(ge.Parse(value))); + return; + } + if(strcmp(prop,"COMPILE_OPTIONS") == 0) + { + cmListFileBacktrace lfbt; + this->Makefile->GetBacktrace(lfbt); + cmGeneratorExpression ge(lfbt); + this->Internal->CompileOptionsEntries.push_back( + new cmTargetInternals::TargetPropertyEntry(ge.Parse(value))); return; } if(strcmp(prop,"EXPORT_NAME") == 0 && this->IsImported()) @@ -2812,7 +2864,7 @@ void cmTarget::AppendProperty(const char* prop, const char* value, cmListFileBacktrace lfbt; this->Makefile->GetBacktrace(lfbt); cmValueWithOrigin entry(value, lfbt); - this->Internal->LinkInterfaceIncludeDirectoriesEntries.push_back(entry); + this->Internal->LinkInterfacePropertyEntries.push_back(entry); } // Fall through } @@ -2877,17 +2929,31 @@ void cmTarget::InsertInclude(const cmValueWithOrigin &entry, { cmGeneratorExpression ge(entry.Backtrace); - std::vector<cmTargetInternals::IncludeDirectoriesEntry*>::iterator position + std::vector<cmTargetInternals::TargetPropertyEntry*>::iterator position = before ? this->Internal->IncludeDirectoriesEntries.begin() : this->Internal->IncludeDirectoriesEntries.end(); this->Internal->IncludeDirectoriesEntries.insert(position, - new cmTargetInternals::IncludeDirectoriesEntry(ge.Parse(entry.Value))); + new cmTargetInternals::TargetPropertyEntry(ge.Parse(entry.Value))); +} + +//---------------------------------------------------------------------------- +void cmTarget::InsertCompileOption(const cmValueWithOrigin &entry, + bool before) +{ + cmGeneratorExpression ge(entry.Backtrace); + + std::vector<cmTargetInternals::TargetPropertyEntry*>::iterator position + = before ? this->Internal->CompileOptionsEntries.begin() + : this->Internal->CompileOptionsEntries.end(); + + this->Internal->CompileOptionsEntries.insert(position, + new cmTargetInternals::TargetPropertyEntry(ge.Parse(entry.Value))); } //---------------------------------------------------------------------------- static void processIncludeDirectories(cmTarget *tgt, - const std::vector<cmTargetInternals::IncludeDirectoriesEntry*> &entries, + const std::vector<cmTargetInternals::TargetPropertyEntry*> &entries, std::vector<std::string> &includes, std::set<std::string> &uniqueIncludes, cmGeneratorExpressionDAGChecker *dagChecker, @@ -2895,12 +2961,12 @@ static void processIncludeDirectories(cmTarget *tgt, { cmMakefile *mf = tgt->GetMakefile(); - for (std::vector<cmTargetInternals::IncludeDirectoriesEntry*>::const_iterator + for (std::vector<cmTargetInternals::TargetPropertyEntry*>::const_iterator it = entries.begin(), end = entries.end(); it != end; ++it) { bool testIsOff = true; bool cacheIncludes = false; - std::vector<std::string> entryIncludes = (*it)->CachedIncludes; + std::vector<std::string> entryIncludes = (*it)->CachedEntries; if(!entryIncludes.empty()) { testIsOff = false; @@ -3003,7 +3069,7 @@ static void processIncludeDirectories(cmTarget *tgt, } if (cacheIncludes) { - (*it)->CachedIncludes = entryIncludes; + (*it)->CachedEntries = entryIncludes; } if (!usedIncludes.empty()) { @@ -3059,8 +3125,8 @@ std::vector<std::string> cmTarget::GetIncludeDirectories(const char *config) if (!this->Internal->CacheLinkInterfaceIncludeDirectoriesDone[configString]) { for (std::vector<cmValueWithOrigin>::const_iterator - it = this->Internal->LinkInterfaceIncludeDirectoriesEntries.begin(), - end = this->Internal->LinkInterfaceIncludeDirectoriesEntries.end(); + it = this->Internal->LinkInterfacePropertyEntries.begin(), + end = this->Internal->LinkInterfacePropertyEntries.end(); it != end; ++it) { { @@ -3089,7 +3155,7 @@ std::vector<std::string> cmTarget::GetIncludeDirectories(const char *config) this->Internal ->CachedLinkInterfaceIncludeDirectoriesEntries[configString].push_back( - new cmTargetInternals::IncludeDirectoriesEntry(cge, + new cmTargetInternals::TargetPropertyEntry(cge, it->Value)); } } @@ -3117,6 +3183,159 @@ std::vector<std::string> cmTarget::GetIncludeDirectories(const char *config) } //---------------------------------------------------------------------------- +static void processCompileOptions(cmTarget *tgt, + const std::vector<cmTargetInternals::TargetPropertyEntry*> &entries, + std::vector<std::string> &options, + std::set<std::string> &uniqueOptions, + cmGeneratorExpressionDAGChecker *dagChecker, + const char *config, bool debugOptions) +{ + cmMakefile *mf = tgt->GetMakefile(); + + 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()) + { + cmSystemTools::ExpandListArgument((*it)->ge->Evaluate(mf, + config, + false, + tgt, + dagChecker), + entryOptions); + if (mf->IsGeneratingBuildSystem() + && !(*it)->ge->GetHadContextSensitiveCondition()) + { + cacheOptions = true; + } + } + std::string usedOptions; + for(std::vector<std::string>::iterator + li = entryOptions.begin(); li != entryOptions.end(); ++li) + { + std::string opt = *li; + + if(uniqueOptions.insert(opt).second) + { + options.push_back(opt); + if (debugOptions) + { + usedOptions += " * " + opt + "\n"; + } + } + } + if (cacheOptions) + { + (*it)->CachedEntries = entryOptions; + } + if (!usedOptions.empty()) + { + mf->GetCMakeInstance()->IssueMessage(cmake::LOG, + std::string("Used compile options for target ") + + tgt->GetName() + ":\n" + + usedOptions, (*it)->ge->GetBacktrace()); + } + } +} + +//---------------------------------------------------------------------------- +void cmTarget::GetCompileOptions(std::vector<std::string> &result, + const char *config) +{ + std::set<std::string> uniqueOptions; + cmListFileBacktrace lfbt; + + cmGeneratorExpressionDAGChecker dagChecker(lfbt, + this->GetName(), + "COMPILE_OPTIONS", 0, 0); + + std::vector<std::string> debugProperties; + const char *debugProp = + this->Makefile->GetDefinition("CMAKE_DEBUG_TARGET_PROPERTIES"); + if (debugProp) + { + cmSystemTools::ExpandListArgument(debugProp, debugProperties); + } + + bool debugOptions = !this->DebugCompileOptionsDone + && std::find(debugProperties.begin(), + debugProperties.end(), + "COMPILE_OPTIONS") + != debugProperties.end(); + + if (this->Makefile->IsGeneratingBuildSystem()) + { + this->DebugCompileOptionsDone = true; + } + + processCompileOptions(this, + this->Internal->CompileOptionsEntries, + result, + uniqueOptions, + &dagChecker, + config, + debugOptions); + + std::string configString = config ? config : ""; + if (!this->Internal->CacheLinkInterfaceCompileOptionsDone[configString]) + { + for (std::vector<cmValueWithOrigin>::const_iterator + it = this->Internal->LinkInterfacePropertyEntries.begin(), + end = this->Internal->LinkInterfacePropertyEntries.end(); + it != end; ++it) + { + { + cmGeneratorExpression ge(lfbt); + cmsys::auto_ptr<cmCompiledGeneratorExpression> 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 optionGenex = "$<TARGET_PROPERTY:" + + it->Value + ",INTERFACE_COMPILE_OPTIONS>"; + 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. + optionGenex = "$<$<BOOL:" + it->Value + ">:" + optionGenex + ">"; + } + cmGeneratorExpression ge(it->Backtrace); + cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = ge.Parse( + optionGenex); + + this->Internal + ->CachedLinkInterfaceCompileOptionsEntries[configString].push_back( + new cmTargetInternals::TargetPropertyEntry(cge, + it->Value)); + } + } + + processCompileOptions(this, + this->Internal->CachedLinkInterfaceCompileOptionsEntries[configString], + result, + uniqueOptions, + &dagChecker, + config, + debugOptions); + + if (!this->Makefile->IsGeneratingBuildSystem()) + { + deleteAndClear(this->Internal->CachedLinkInterfaceCompileOptionsEntries); + } + else + { + this->Internal->CacheLinkInterfaceCompileOptionsDone[configString] = true; + } +} + +//---------------------------------------------------------------------------- std::string cmTarget::GetCompileDefinitions(const char *config) { const char *configProp = 0; @@ -3541,9 +3760,9 @@ const char *cmTarget::GetProperty(const char* prop, static std::string output; output = ""; std::string sep; - typedef cmTargetInternals::IncludeDirectoriesEntry - IncludeDirectoriesEntry; - for (std::vector<IncludeDirectoriesEntry*>::const_iterator + typedef cmTargetInternals::TargetPropertyEntry + TargetPropertyEntry; + for (std::vector<TargetPropertyEntry*>::const_iterator it = this->Internal->IncludeDirectoriesEntries.begin(), end = this->Internal->IncludeDirectoriesEntries.end(); it != end; ++it) @@ -3554,6 +3773,24 @@ const char *cmTarget::GetProperty(const char* prop, } return output.c_str(); } + if(strcmp(prop,"COMPILE_OPTIONS") == 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 (strcmp(prop,"IMPORTED") == 0) { @@ -6263,6 +6500,7 @@ cmTargetInternalPointer cmTargetInternalPointer::~cmTargetInternalPointer() { deleteAndClear(this->Pointer->IncludeDirectoriesEntries); + deleteAndClear(this->Pointer->CompileOptionsEntries); delete this->Pointer; } |