فهرست منبع

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.
Stephen Kelly 12 سال پیش
والد
کامیت
a1c4905f72
4فایلهای تغییر یافته به همراه218 افزوده شده و 57 حذف شده
  1. 63 6
      Source/cmGeneratorExpressionEvaluator.cxx
  2. 146 51
      Source/cmTarget.cxx
  3. 1 0
      Source/cmTarget.h
  4. 8 0
      Source/cmTargetLinkLibrariesCommand.cxx

+ 63 - 6
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;
         }
       }

+ 146 - 51
Source/cmTarget.cxx

@@ -137,6 +137,7 @@ public:
     std::vector<std::string> CachedIncludes;
   };
   std::vector<IncludeDirectoriesEntry*> IncludeDirectoriesEntries;
+  std::vector<cmValueWithOrigin> LinkInterfaceIncludeDirectoriesEntries;
 };
 
 //----------------------------------------------------------------------------
@@ -2742,6 +2743,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;
 }
 
 //----------------------------------------------------------------------------

+ 1 - 0
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();
 

+ 8 - 0
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)