diff options
author | Stephen Kelly <steveire@gmail.com> | 2013-02-12 10:29:09 (GMT) |
---|---|---|
committer | Stephen Kelly <steveire@gmail.com> | 2013-02-13 14:12:30 (GMT) |
commit | a1c4905f723f9d99bd481580f9fe24fdaf81b174 (patch) | |
tree | 7e99ae5614cf070ae73a3607f8d1ce51e0c5ac79 /Source/cmTarget.cxx | |
parent | 5c9f5e313ff893a28f975749ad9a6b19481e8e62 (diff) | |
download | CMake-a1c4905f723f9d99bd481580f9fe24fdaf81b174.zip CMake-a1c4905f723f9d99bd481580f9fe24fdaf81b174.tar.gz CMake-a1c4905f723f9d99bd481580f9fe24fdaf81b174.tar.bz2 |
Use the link information as a source of compile definitions and includes.
After evaluating the INTERFACE_INCLUDE_DIRECTORIES, of a target in a
generator expression, also read the INTERFACE_INCLUDE_DIRECTORIES of
its link interface dependencies.
That means that code such as this will result in the 'user' target
using /bar/include and /foo/include:
add_library(foo ...)
target_include_directories(foo INTERFACE /foo/include)
add_library(bar ...)
target_include_directories(bar INTERFACE /bar/include)
target_link_libraries(bar LINK_PUBLIC foo)
add_executable(user ...)
target_include_directories(user PRIVATE
$<TARGET_PROPERTY:bar,INTERFACE_INCLUDE_DIRECTORIES>)
Also process the interface include directories from direct link
dependencies for in-build targets.
The situation is similar for the INTERFACE_COMPILE_DEFINITIONS. The
include directories related code is currently more complex because
we also need to store a backtrace at configure-time for the purpose
of debugging includes. The compile definitions related code will use
the same pattern in the future.
This is not a change in behavior, as existing code has the same effect,
but that existing code will be removed in follow-up commits.
Diffstat (limited to 'Source/cmTarget.cxx')
-rw-r--r-- | Source/cmTarget.cxx | 197 |
1 files changed, 146 insertions, 51 deletions
diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx index 6da6957..003f3d8 100644 --- a/Source/cmTarget.cxx +++ b/Source/cmTarget.cxx @@ -137,6 +137,7 @@ public: std::vector<std::string> CachedIncludes; }; std::vector<IncludeDirectoriesEntry*> IncludeDirectoriesEntries; + std::vector<cmValueWithOrigin> LinkInterfaceIncludeDirectoriesEntries; }; //---------------------------------------------------------------------------- @@ -2743,6 +2744,12 @@ void cmTarget::AppendBuildInterfaceIncludes() } //---------------------------------------------------------------------------- +void cmTarget::AppendTllInclude(const cmValueWithOrigin &entry) +{ + this->Internal->LinkInterfaceIncludeDirectoriesEntries.push_back(entry); +} + +//---------------------------------------------------------------------------- void cmTarget::InsertInclude(const cmValueWithOrigin &entry, bool before) { @@ -2757,43 +2764,18 @@ void cmTarget::InsertInclude(const cmValueWithOrigin &entry, } //---------------------------------------------------------------------------- -std::vector<std::string> cmTarget::GetIncludeDirectories(const char *config) +static void processIncludeDirectories(cmTarget *tgt, + const std::vector<cmTargetInternals::IncludeDirectoriesEntry*> &entries, + std::vector<std::string> &includes, + std::set<std::string> &uniqueIncludes, + cmGeneratorExpressionDAGChecker *dagChecker, + const char *config, bool debugIncludes) { - std::vector<std::string> includes; - std::set<std::string> uniqueIncludes; - cmListFileBacktrace lfbt; - - cmGeneratorExpressionDAGChecker dagChecker(lfbt, - this->GetName(), - "INCLUDE_DIRECTORIES", 0, 0); - - this->AppendBuildInterfaceIncludes(); - - std::vector<std::string> debugProperties; - const char *debugProp = - this->Makefile->GetDefinition("CMAKE_DEBUG_TARGET_PROPERTIES"); - if (debugProp) - { - cmSystemTools::ExpandListArgument(debugProp, debugProperties); - } - - bool debugIncludes = !this->DebugIncludesDone - && std::find(debugProperties.begin(), - debugProperties.end(), - "INCLUDE_DIRECTORIES") - != debugProperties.end(); - - if (this->Makefile->IsGeneratingBuildSystem()) - { - this->DebugIncludesDone = true; - } + cmMakefile *mf = tgt->GetMakefile(); for (std::vector<cmTargetInternals::IncludeDirectoriesEntry*>::const_iterator - it = this->Internal->IncludeDirectoriesEntries.begin(), - end = this->Internal->IncludeDirectoriesEntries.end(); - it != end; ++it) + it = entries.begin(), end = entries.end(); it != end; ++it) { - bool testIsOff = true; bool cacheIncludes = false; std::vector<std::string> entryIncludes = (*it)->CachedIncludes; @@ -2803,13 +2785,13 @@ std::vector<std::string> cmTarget::GetIncludeDirectories(const char *config) } else { - cmSystemTools::ExpandListArgument((*it)->ge->Evaluate(this->Makefile, + cmSystemTools::ExpandListArgument((*it)->ge->Evaluate(mf, config, false, - this, - &dagChecker), + tgt, + dagChecker), entryIncludes); - if (this->Makefile->IsGeneratingBuildSystem() + if (mf->IsGeneratingBuildSystem() && !(*it)->ge->GetHadContextSensitiveCondition()) { cacheIncludes = true; @@ -2840,11 +2822,90 @@ std::vector<std::string> cmTarget::GetIncludeDirectories(const char *config) } if (!usedIncludes.empty()) { - this->Makefile->GetCMakeInstance()->IssueMessage(cmake::LOG, - "Used includes for target " + this->Name + ":\n" + mf->GetCMakeInstance()->IssueMessage(cmake::LOG, + std::string("Used includes for target ") + + tgt->GetName() + ":\n" + usedIncludes, (*it)->ge->GetBacktrace()); } } +} + +//---------------------------------------------------------------------------- +std::vector<std::string> cmTarget::GetIncludeDirectories(const char *config) +{ + std::vector<std::string> includes; + std::set<std::string> uniqueIncludes; + cmListFileBacktrace lfbt; + + cmGeneratorExpressionDAGChecker dagChecker(lfbt, + this->GetName(), + "INCLUDE_DIRECTORIES", 0, 0); + + this->AppendBuildInterfaceIncludes(); + + std::vector<std::string> debugProperties; + const char *debugProp = + this->Makefile->GetDefinition("CMAKE_DEBUG_TARGET_PROPERTIES"); + if (debugProp) + { + cmSystemTools::ExpandListArgument(debugProp, debugProperties); + } + + bool debugIncludes = !this->DebugIncludesDone + && std::find(debugProperties.begin(), + debugProperties.end(), + "INCLUDE_DIRECTORIES") + != debugProperties.end(); + + if (this->Makefile->IsGeneratingBuildSystem()) + { + this->DebugIncludesDone = true; + } + + processIncludeDirectories(this, + this->Internal->IncludeDirectoriesEntries, + includes, + uniqueIncludes, + &dagChecker, + config, + debugIncludes); + + std::vector<cmTargetInternals::IncludeDirectoriesEntry*> + linkInterfaceIncludeDirectoriesEntries; + + for (std::vector<cmValueWithOrigin>::const_iterator + it = this->Internal->LinkInterfaceIncludeDirectoriesEntries.begin(), + end = this->Internal->LinkInterfaceIncludeDirectoriesEntries.end(); + it != end; ++it) + { + { + cmGeneratorExpression ge(lfbt); + cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(it->Value); + std::string result = cge->Evaluate(this->Makefile, config, + false, this, 0, 0); + if (!this->Makefile->FindTargetToUse(result.c_str())) + { + continue; + } + } + cmGeneratorExpression ge(it->Backtrace); + cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = ge.Parse( + "$<TARGET_PROPERTY:" + it->Value + ",INTERFACE_INCLUDE_DIRECTORIES>"); + + linkInterfaceIncludeDirectoriesEntries.push_back( + new cmTargetInternals::IncludeDirectoriesEntry(cge)); + } + + processIncludeDirectories(this, + linkInterfaceIncludeDirectoriesEntries, + includes, + uniqueIncludes, + &dagChecker, + config, + debugIncludes); + + deleteAndClear(linkInterfaceIncludeDirectoriesEntries); + return includes; } @@ -2858,23 +2919,57 @@ std::string cmTarget::GetCompileDefinitions(const char *config) } const char *prop = this->GetProperty(defPropName.c_str()); + cmListFileBacktrace lfbt; + cmGeneratorExpressionDAGChecker dagChecker(lfbt, + this->GetName(), + defPropName, 0, 0); - if (!prop) + std::string result; + if (prop) { - return ""; + cmGeneratorExpression ge(lfbt); + + result = ge.Parse(prop)->Evaluate(this->Makefile, + config, + false, + this, + &dagChecker); } - cmListFileBacktrace lfbt; - cmGeneratorExpression ge(lfbt); + std::vector<std::string> libs; + this->GetDirectLinkLibraries(config, libs, this); - cmGeneratorExpressionDAGChecker dagChecker(lfbt, - this->GetName(), - defPropName, 0, 0); - return ge.Parse(prop)->Evaluate(this->Makefile, - config, - false, - this, - &dagChecker); + if (libs.empty()) + { + return result; + } + + std::string sep; + std::string depString; + for (std::vector<std::string>::const_iterator it = libs.begin(); + it != libs.end(); ++it) + { + if (this->Makefile->FindTargetToUse(it->c_str())) + { + depString += sep + "$<TARGET_PROPERTY:" + + *it + ",INTERFACE_COMPILE_DEFINITIONS>"; + sep = ";"; + } + } + + cmGeneratorExpression ge2(lfbt); + cmsys::auto_ptr<cmCompiledGeneratorExpression> cge2 = ge2.Parse(depString); + std::string depResult = cge2->Evaluate(this->Makefile, + config, + false, + this, + &dagChecker); + if (!depResult.empty()) + { + result += (result.empty() ? "" : ";") + depResult; + } + + return result; } //---------------------------------------------------------------------------- |