diff options
author | Stephen Kelly <steveire@gmail.com> | 2014-01-01 14:49:05 (GMT) |
---|---|---|
committer | Stephen Kelly <steveire@gmail.com> | 2014-01-06 16:25:10 (GMT) |
commit | faedd2bea9c98fddd9e9f70deebdb53f8f369124 (patch) | |
tree | 9bd680db2dfc528aa600494acb4f865e5fe31e1e /Source/cmGeneratorTarget.cxx | |
parent | 9eb06d0dde52203d3f8ac91ea9a1c5396a09f8af (diff) | |
download | CMake-faedd2bea9c98fddd9e9f70deebdb53f8f369124.zip CMake-faedd2bea9c98fddd9e9f70deebdb53f8f369124.tar.gz CMake-faedd2bea9c98fddd9e9f70deebdb53f8f369124.tar.bz2 |
cmTarget: Fix system include annotation propagation.
Direct users of IMPORTED targets treat INTERFACE_INCLUDE_DIRECTORIES
as SYSTEM, after commit a63fcbcb (Always consider includes from IMPORTED
targets to be SYSTEM., 2013-08-29). It was intended that transitive
use of an IMPORTED target would have the same behavior, but that
did not work. The implementation processed only direct dependencies
in cmTarget::FinalizeSystemIncludeDirectories.
Implement transitive evaluation of dependencies by traversing the
link interface of each target in the link implementation.
Diffstat (limited to 'Source/cmGeneratorTarget.cxx')
-rw-r--r-- | Source/cmGeneratorTarget.cxx | 113 |
1 files changed, 99 insertions, 14 deletions
diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx index fdd4e6d..6894cfc 100644 --- a/Source/cmGeneratorTarget.cxx +++ b/Source/cmGeneratorTarget.cxx @@ -18,9 +18,12 @@ #include "cmSourceFile.h" #include "cmGeneratorExpression.h" #include "cmGeneratorExpressionDAGChecker.h" +#include "cmComputeLinkInformation.h" #include <queue> +#include "assert.h" + //---------------------------------------------------------------------------- cmGeneratorTarget::cmGeneratorTarget(cmTarget* t): Target(t) { @@ -59,10 +62,50 @@ cmGeneratorTarget::GetSourceDepends(cmSourceFile* sf) const return 0; } +static void handleSystemIncludesDep(cmMakefile *mf, const std::string &name, + const char *config, cmTarget *headTarget, + cmGeneratorExpressionDAGChecker *dagChecker, + std::vector<std::string>& result) +{ + cmTarget* depTgt = mf->FindTargetToUse(name.c_str()); + + if (!depTgt) + { + return; + } + + cmListFileBacktrace lfbt; + + if (const char* dirs = + depTgt->GetProperty("INTERFACE_SYSTEM_INCLUDE_DIRECTORIES")) + { + cmGeneratorExpression ge(lfbt); + cmSystemTools::ExpandListArgument(ge.Parse(dirs) + ->Evaluate(mf, + config, false, headTarget, + depTgt, dagChecker), result); + } + if (!depTgt->IsImported()) + { + return; + } + + if (const char* dirs = + depTgt->GetProperty("INTERFACE_INCLUDE_DIRECTORIES")) + { + cmGeneratorExpression ge(lfbt); + cmSystemTools::ExpandListArgument(ge.Parse(dirs) + ->Evaluate(mf, + config, false, headTarget, + depTgt, dagChecker), result); + } +} + //---------------------------------------------------------------------------- bool cmGeneratorTarget::IsSystemIncludeDirectory(const char *dir, const char *config) const { + assert(this->GetType() != cmTarget::INTERFACE_LIBRARY); std::string config_upper; if(config && *config) { @@ -75,39 +118,81 @@ bool cmGeneratorTarget::IsSystemIncludeDirectory(const char *dir, if (iter == this->SystemIncludesCache.end()) { + cmTarget::LinkImplementation const* impl + = this->Target->GetLinkImplementation(config, this->Target); + if(!impl) + { + return false; + } + + cmListFileBacktrace lfbt; + cmGeneratorExpressionDAGChecker dagChecker(lfbt, + this->GetName(), + "SYSTEM_INCLUDE_DIRECTORIES", 0, 0); + std::vector<std::string> result; for (std::set<cmStdString>::const_iterator it = this->Target->GetSystemIncludeDirectories().begin(); it != this->Target->GetSystemIncludeDirectories().end(); ++it) { - cmListFileBacktrace lfbt; cmGeneratorExpression ge(lfbt); + cmSystemTools::ExpandListArgument(ge.Parse(*it) + ->Evaluate(this->Makefile, + config, false, this->Target, + &dagChecker), result); + } + + std::set<cmStdString> uniqueDeps; + for(std::vector<std::string>::const_iterator li = impl->Libraries.begin(); + li != impl->Libraries.end(); ++li) + { + if (uniqueDeps.insert(*li).second) + { + cmTarget* tgt = this->Makefile->FindTargetToUse(li->c_str()); - cmGeneratorExpressionDAGChecker dagChecker(lfbt, - this->GetName(), - "INTERFACE_SYSTEM_INCLUDE_DIRECTORIES", 0, 0); + if (!tgt) + { + continue; + } - cmSystemTools::ExpandListArgument(ge.Parse(*it) - ->Evaluate(this->Makefile, - config, false, this->Target, - &dagChecker), result); + handleSystemIncludesDep(this->Makefile, *li, config, this->Target, + &dagChecker, result); + + std::vector<std::string> deps; + tgt->GetTransitivePropertyLinkLibraries(config, this->Target, deps); + + for(std::vector<std::string>::const_iterator di = deps.begin(); + di != deps.end(); ++di) + { + if (uniqueDeps.insert(*di).second) + { + handleSystemIncludesDep(this->Makefile, *di, config, this->Target, + &dagChecker, result); + } + } + } } + std::set<cmStdString> unique; for(std::vector<std::string>::iterator li = result.begin(); li != result.end(); ++li) { cmSystemTools::ConvertToUnixSlashes(*li); + unique.insert(*li); + } + result.clear(); + for(std::set<cmStdString>::iterator li = unique.begin(); + li != unique.end(); ++li) + { + result.push_back(*li); } IncludeCacheType::value_type entry(config_upper, result); iter = this->SystemIncludesCache.insert(entry).first; } - if (std::find(iter->second.begin(), - iter->second.end(), dir) != iter->second.end()) - { - return true; - } - return false; + std::string dirString = dir; + return std::binary_search(iter->second.begin(), iter->second.end(), + dirString); } //---------------------------------------------------------------------------- |