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 | |
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.
-rw-r--r-- | Source/cmGeneratorExpressionEvaluator.cxx | 69 | ||||
-rw-r--r-- | Source/cmTarget.cxx | 197 | ||||
-rw-r--r-- | Source/cmTarget.h | 1 | ||||
-rw-r--r-- | Source/cmTargetLinkLibrariesCommand.cxx | 8 |
4 files changed, 218 insertions, 57 deletions
diff --git a/Source/cmGeneratorExpressionEvaluator.cxx b/Source/cmGeneratorExpressionEvaluator.cxx index 98e0ada..6c1c12a 100644 --- a/Source/cmGeneratorExpressionEvaluator.cxx +++ b/Source/cmGeneratorExpressionEvaluator.cxx @@ -451,15 +451,68 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode } const char *prop = target->GetProperty(propertyName.c_str()); - if (!prop) + + std::string linkedTargetsContent; + + if (dagCheckerParent) { - if (target->IsImported()) + if (dagCheckerParent->EvaluatingLinkLibraries()) { - return std::string(); + if(!prop) + { + return std::string(); + } } - if (dagCheckerParent && dagCheckerParent->EvaluatingLinkLibraries()) + else { - return std::string(); + assert(dagCheckerParent->EvaluatingIncludeDirectories() + || dagCheckerParent->EvaluatingCompileDefinitions()); + + if (propertyName == "INTERFACE_INCLUDE_DIRECTORIES" + || propertyName == "INTERFACE_COMPILE_DEFINITIONS") + { + const cmTarget::LinkInterface *iface = target->GetLinkInterface( + context->Config, + context->HeadTarget); + if(iface) + { + cmGeneratorExpression ge(context->Backtrace); + + std::string sep; + std::string depString; + for (std::vector<std::string>::const_iterator + it = iface->Libraries.begin(); + it != iface->Libraries.end(); ++it) + { + if (context->Makefile->FindTargetToUse(it->c_str())) + { + depString += + sep + "$<TARGET_PROPERTY:" + *it + "," + propertyName + ">"; + sep = ";"; + } + } + cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = + ge.Parse(depString); + linkedTargetsContent = cge->Evaluate(context->Makefile, + context->Config, + context->Quiet, + context->HeadTarget, + target, + &dagChecker); + if (cge->GetHadContextSensitiveCondition()) + { + context->HadContextSensitiveCondition = true; + } + } + } + } + } + + if (!prop) + { + if (target->IsImported()) + { + return linkedTargetsContent; } if (target->IsLinkInterfaceDependentBoolProperty(propertyName, context->Config)) @@ -480,7 +533,7 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode return propContent ? propContent : ""; } - return std::string(); + return linkedTargetsContent; } for (size_t i = 0; @@ -503,6 +556,10 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode { context->HadContextSensitiveCondition = true; } + if (!linkedTargetsContent.empty()) + { + result += (result.empty() ? "" : ";") + linkedTargetsContent; + } return result; } } 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; } //---------------------------------------------------------------------------- diff --git a/Source/cmTarget.h b/Source/cmTarget.h index 028a55e..e659baf 100644 --- a/Source/cmTarget.h +++ b/Source/cmTarget.h @@ -495,6 +495,7 @@ public: std::vector<std::string> GetIncludeDirectories(const char *config); void InsertInclude(const cmValueWithOrigin &entry, bool before = false); + void AppendTllInclude(const cmValueWithOrigin &entry); void AppendBuildInterfaceIncludes(); diff --git a/Source/cmTargetLinkLibrariesCommand.cxx b/Source/cmTargetLinkLibrariesCommand.cxx index 9dd0e5b..22ea920 100644 --- a/Source/cmTargetLinkLibrariesCommand.cxx +++ b/Source/cmTargetLinkLibrariesCommand.cxx @@ -291,6 +291,14 @@ cmTargetLinkLibrariesCommand::HandleLibrary(const char* lib, // Handle normal case first. if(this->CurrentProcessingState != ProcessingLinkInterface) { + { + cmListFileBacktrace lfbt; + this->Makefile->GetBacktrace(lfbt); + cmValueWithOrigin entry(this->Target->GetDebugGeneratorExpressions(lib, + llt), + lfbt); + this->Target->AppendTllInclude(entry); + } this->Makefile ->AddLinkLibraryForTarget(this->Target->GetName(), lib, llt); if (this->CurrentProcessingState != ProcessingPublicInterface) |