summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStephen Kelly <steveire@gmail.com>2013-02-12 10:29:09 (GMT)
committerStephen Kelly <steveire@gmail.com>2013-02-13 14:12:30 (GMT)
commita1c4905f723f9d99bd481580f9fe24fdaf81b174 (patch)
tree7e99ae5614cf070ae73a3607f8d1ce51e0c5ac79
parent5c9f5e313ff893a28f975749ad9a6b19481e8e62 (diff)
downloadCMake-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.cxx69
-rw-r--r--Source/cmTarget.cxx197
-rw-r--r--Source/cmTarget.h1
-rw-r--r--Source/cmTargetLinkLibrariesCommand.cxx8
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)