浏览代码

Add target property debugging for COMPILE_DEFINITIONS

Use constructs similar to those for COMPILE_OPTIONS. This is a little
different because there is a command to remove_definitions(), so
we can't populate the equivalent target property until generate-time
in cmGlobalGenerator.
Stephen Kelly 12 年之前
父节点
当前提交
d7dd01083a
共有 5 个文件被更改,包括 228 次插入66 次删除
  1. 10 3
      Source/cmGlobalGenerator.cxx
  2. 41 0
      Source/cmMakefile.cxx
  3. 5 0
      Source/cmMakefile.h
  4. 169 63
      Source/cmTarget.cxx
  5. 3 0
      Source/cmTarget.h

+ 10 - 3
Source/cmGlobalGenerator.cxx

@@ -1121,8 +1121,9 @@ void cmGlobalGenerator::CreateGeneratorTargets()
     cmGeneratorTargetsType generatorTargets;
 
     cmMakefile *mf = this->LocalGenerators[i]->GetMakefile();
-    const char *noconfig_compile_definitions =
-                                      mf->GetProperty("COMPILE_DEFINITIONS");
+
+    const std::vector<cmValueWithOrigin> noconfig_compile_definitions =
+                                mf->GetCompileDefinitionsEntries();
 
     std::vector<std::string> configs;
     mf->GetConfigurations(configs);
@@ -1134,7 +1135,13 @@ void cmGlobalGenerator::CreateGeneratorTargets()
       cmTarget* t = &ti->second;
 
       {
-      t->AppendProperty("COMPILE_DEFINITIONS", noconfig_compile_definitions);
+      for (std::vector<cmValueWithOrigin>::const_iterator it
+                                      = noconfig_compile_definitions.begin();
+          it != noconfig_compile_definitions.end(); ++it)
+        {
+        t->InsertCompileDefinition(*it);
+        }
+
       for(std::vector<std::string>::const_iterator ci = configs.begin();
           ci != configs.end(); ++ci)
         {

+ 41 - 0
Source/cmMakefile.cxx

@@ -1505,6 +1505,12 @@ void cmMakefile::InitializeFromParent()
                                      parentOptions.begin(),
                                      parentOptions.end());
 
+  const std::vector<cmValueWithOrigin> parentDefines =
+                                      parent->GetCompileDefinitionsEntries();
+  this->CompileDefinitionsEntries.insert(this->CompileDefinitionsEntries.end(),
+                                     parentDefines.begin(),
+                                     parentDefines.end());
+
   this->SystemIncludeDirectories = parent->SystemIncludeDirectories;
 
   // define flags
@@ -3493,6 +3499,19 @@ void cmMakefile::SetProperty(const char* prop, const char* value)
     this->CompileOptionsEntries.push_back(cmValueWithOrigin(value, lfbt));
     return;
     }
+  if (propname == "COMPILE_DEFINITIONS")
+    {
+    this->CompileDefinitionsEntries.clear();
+    if (!value)
+      {
+      return;
+      }
+    cmListFileBacktrace lfbt;
+    this->GetBacktrace(lfbt);
+    cmValueWithOrigin entry(value, lfbt);
+    this->CompileDefinitionsEntries.push_back(entry);
+    return;
+    }
 
   if ( propname == "INCLUDE_REGULAR_EXPRESSION" )
     {
@@ -3540,6 +3559,14 @@ void cmMakefile::AppendProperty(const char* prop, const char* value,
                                         cmValueWithOrigin(value, lfbt));
     return;
     }
+  if (propname == "COMPILE_DEFINITIONS")
+    {
+    cmListFileBacktrace lfbt;
+    this->GetBacktrace(lfbt);
+    this->CompileDefinitionsEntries.push_back(
+                                        cmValueWithOrigin(value, lfbt));
+    return;
+    }
   if ( propname == "LINK_DIRECTORIES" )
     {
     std::vector<std::string> varArgsExpanded;
@@ -3679,6 +3706,20 @@ const char *cmMakefile::GetProperty(const char* prop,
       }
     return output.c_str();
     }
+  else if (!strcmp("COMPILE_DEFINITIONS",prop))
+    {
+    std::string sep;
+    for (std::vector<cmValueWithOrigin>::const_iterator
+        it = this->CompileDefinitionsEntries.begin(),
+        end = this->CompileDefinitionsEntries.end();
+        it != end; ++it)
+      {
+      output += sep;
+      output += it->Value;
+      sep = ";";
+      }
+    return output.c_str();
+    }
 
   bool chain = false;
   const char *retVal =

+ 5 - 0
Source/cmMakefile.h

@@ -871,6 +871,10 @@ public:
   {
     return this->CompileOptionsEntries;
   }
+  std::vector<cmValueWithOrigin> GetCompileDefinitionsEntries() const
+  {
+    return this->CompileDefinitionsEntries;
+  }
 
   bool IsGeneratingBuildSystem(){ return this->GeneratingBuildSystem; }
   void SetGeneratingBuildSystem(){ this->GeneratingBuildSystem = true; }
@@ -925,6 +929,7 @@ protected:
 
   std::vector<cmValueWithOrigin> IncludeDirectoriesEntries;
   std::vector<cmValueWithOrigin> CompileOptionsEntries;
+  std::vector<cmValueWithOrigin> CompileDefinitionsEntries;
 
   // Track the value of the computed DEFINITIONS property.
   void AddDefineFlag(const char*, std::string&);

+ 169 - 63
Source/cmTarget.cxx

@@ -141,13 +141,15 @@ public:
   };
   std::vector<TargetPropertyEntry*> IncludeDirectoriesEntries;
   std::vector<TargetPropertyEntry*> CompileOptionsEntries;
+  std::vector<TargetPropertyEntry*> CompileDefinitionsEntries;
   std::vector<cmValueWithOrigin> LinkInterfacePropertyEntries;
 
   std::map<std::string, std::vector<TargetPropertyEntry*> >
                                 CachedLinkInterfaceIncludeDirectoriesEntries;
   std::map<std::string, std::vector<TargetPropertyEntry*> >
                                 CachedLinkInterfaceCompileOptionsEntries;
-  std::map<std::string, std::string> CachedLinkInterfaceCompileDefinitions;
+  std::map<std::string, std::vector<TargetPropertyEntry*> >
+                                CachedLinkInterfaceCompileDefinitionsEntries;
 
   std::map<std::string, bool> CacheLinkInterfaceIncludeDirectoriesDone;
   std::map<std::string, bool> CacheLinkInterfaceCompileDefinitionsDone;
@@ -186,6 +188,7 @@ cmTargetInternals::~cmTargetInternals()
 {
   deleteAndClear(this->CachedLinkInterfaceIncludeDirectoriesEntries);
   deleteAndClear(this->CachedLinkInterfaceCompileOptionsEntries);
+  deleteAndClear(this->CachedLinkInterfaceCompileDefinitionsEntries);
 }
 
 //----------------------------------------------------------------------------
@@ -205,6 +208,7 @@ cmTarget::cmTarget()
   this->BuildInterfaceIncludesAppended = false;
   this->DebugIncludesDone = false;
   this->DebugCompileOptionsDone = false;
+  this->DebugCompileDefinitionsDone = false;
 }
 
 //----------------------------------------------------------------------------
@@ -2845,6 +2849,17 @@ void cmTarget::SetProperty(const char* prop, const char* value)
                           new cmTargetInternals::TargetPropertyEntry(cge));
     return;
     }
+  if(strcmp(prop,"COMPILE_DEFINITIONS") == 0)
+    {
+    cmListFileBacktrace lfbt;
+    this->Makefile->GetBacktrace(lfbt);
+    cmGeneratorExpression ge(lfbt);
+    deleteAndClear(this->Internal->CompileDefinitionsEntries);
+    cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(value);
+    this->Internal->CompileDefinitionsEntries.push_back(
+                          new cmTargetInternals::TargetPropertyEntry(cge));
+    return;
+    }
   if(strcmp(prop,"EXPORT_NAME") == 0 && this->IsImported())
     {
     cmOStringStream e;
@@ -2896,6 +2911,15 @@ void cmTarget::AppendProperty(const char* prop, const char* value,
               new cmTargetInternals::TargetPropertyEntry(ge.Parse(value)));
     return;
     }
+  if(strcmp(prop,"COMPILE_DEFINITIONS") == 0)
+    {
+    cmListFileBacktrace lfbt;
+    this->Makefile->GetBacktrace(lfbt);
+    cmGeneratorExpression ge(lfbt);
+    this->Internal->CompileDefinitionsEntries.push_back(
+              new cmTargetInternals::TargetPropertyEntry(ge.Parse(value)));
+    return;
+    }
   if(strcmp(prop,"EXPORT_NAME") == 0 && this->IsImported())
     {
     cmOStringStream e;
@@ -2999,6 +3023,20 @@ void cmTarget::InsertCompileOption(const cmValueWithOrigin &entry,
       new cmTargetInternals::TargetPropertyEntry(ge.Parse(entry.Value)));
 }
 
+//----------------------------------------------------------------------------
+void cmTarget::InsertCompileDefinition(const cmValueWithOrigin &entry,
+                     bool before)
+{
+  cmGeneratorExpression ge(entry.Backtrace);
+
+  std::vector<cmTargetInternals::TargetPropertyEntry*>::iterator position
+                = before ? this->Internal->CompileDefinitionsEntries.begin()
+                         : this->Internal->CompileDefinitionsEntries.end();
+
+  this->Internal->CompileDefinitionsEntries.insert(position,
+      new cmTargetInternals::TargetPropertyEntry(ge.Parse(entry.Value)));
+}
+
 //----------------------------------------------------------------------------
 static void processIncludeDirectories(cmTarget *tgt,
       const std::vector<cmTargetInternals::TargetPropertyEntry*> &entries,
@@ -3231,12 +3269,12 @@ std::vector<std::string> cmTarget::GetIncludeDirectories(const char *config)
 }
 
 //----------------------------------------------------------------------------
-static void processCompileOptions(cmTarget *tgt,
+static void processCompileOptionsInternal(cmTarget *tgt,
       const std::vector<cmTargetInternals::TargetPropertyEntry*> &entries,
       std::vector<std::string> &options,
       std::set<std::string> &uniqueOptions,
       cmGeneratorExpressionDAGChecker *dagChecker,
-      const char *config, bool debugOptions)
+      const char *config, bool debugOptions, const char *logName)
 {
   cmMakefile *mf = tgt->GetMakefile();
 
@@ -3281,13 +3319,26 @@ static void processCompileOptions(cmTarget *tgt,
     if (!usedOptions.empty())
       {
       mf->GetCMakeInstance()->IssueMessage(cmake::LOG,
-                            std::string("Used compile options for target ")
+                            std::string("Used compile ") + logName
+                            + std::string(" for target ")
                             + tgt->GetName() + ":\n"
                             + usedOptions, (*it)->ge->GetBacktrace());
       }
     }
 }
 
+//----------------------------------------------------------------------------
+static void processCompileOptions(cmTarget *tgt,
+      const std::vector<cmTargetInternals::TargetPropertyEntry*> &entries,
+      std::vector<std::string> &options,
+      std::set<std::string> &uniqueOptions,
+      cmGeneratorExpressionDAGChecker *dagChecker,
+      const char *config, bool debugOptions)
+{
+  processCompileOptionsInternal(tgt, entries, options, uniqueOptions,
+                                dagChecker, config, debugOptions, "options");
+}
+
 //----------------------------------------------------------------------------
 void cmTarget::GetCompileOptions(std::vector<std::string> &result,
                                  const char *config)
@@ -3383,93 +3434,129 @@ void cmTarget::GetCompileOptions(std::vector<std::string> &result,
     }
 }
 
+//----------------------------------------------------------------------------
+static void processCompileDefinitions(cmTarget *tgt,
+      const std::vector<cmTargetInternals::TargetPropertyEntry*> &entries,
+      std::vector<std::string> &options,
+      std::set<std::string> &uniqueOptions,
+      cmGeneratorExpressionDAGChecker *dagChecker,
+      const char *config, bool debugOptions)
+{
+  processCompileOptionsInternal(tgt, entries, options, uniqueOptions,
+                                dagChecker, config, debugOptions,
+                                "definitions");
+}
+
 //----------------------------------------------------------------------------
 void cmTarget::GetCompileDefinitions(std::vector<std::string> &list,
                                             const char *config)
 {
-  const char *configProp = 0;
-  if (config)
-    {
-    std::string configPropName;
-    configPropName = "COMPILE_DEFINITIONS_" + cmSystemTools::UpperCase(config);
-    configProp = this->GetProperty(configPropName.c_str());
-    }
-
-  const char *noconfigProp = this->GetProperty("COMPILE_DEFINITIONS");
+  std::set<std::string> uniqueOptions;
   cmListFileBacktrace lfbt;
+
   cmGeneratorExpressionDAGChecker dagChecker(lfbt,
-                                            this->GetName(),
-                                            "COMPILE_DEFINITIONS", 0, 0);
+                                              this->GetName(),
+                                              "COMPILE_DEFINITIONS", 0, 0);
 
-  std::string defsString = (noconfigProp ? noconfigProp : "");
-  if (configProp && noconfigProp)
+  std::vector<std::string> debugProperties;
+  const char *debugProp =
+              this->Makefile->GetDefinition("CMAKE_DEBUG_TARGET_PROPERTIES");
+  if (debugProp)
     {
-    defsString += ";";
+    cmSystemTools::ExpandListArgument(debugProp, debugProperties);
     }
-  defsString += (configProp ? configProp : "");
-
-  cmGeneratorExpression ge(lfbt);
-  std::string result = ge.Parse(defsString.c_str())->Evaluate(this->Makefile,
-                                config,
-                                false,
-                                this,
-                                &dagChecker);
 
-  std::vector<std::string> libs;
-  this->GetDirectLinkLibraries(config, libs, this);
+  bool debugDefines = !this->DebugCompileDefinitionsDone
+                          && std::find(debugProperties.begin(),
+                                debugProperties.end(),
+                                "COMPILE_DEFINITIONS")
+                        != debugProperties.end();
 
-  if (libs.empty())
+  if (this->Makefile->IsGeneratingBuildSystem())
     {
-    cmSystemTools::ExpandListArgument(result, list);
-    return;
+    this->DebugCompileDefinitionsDone = true;
     }
 
-  std::string sep;
-  std::string depString;
-  for (std::vector<std::string>::const_iterator it = libs.begin();
-      it != libs.end(); ++it)
-    {
-    if ((cmGeneratorExpression::IsValidTargetName(it->c_str())
-          || cmGeneratorExpression::Find(it->c_str()) != std::string::npos)
-        && this->Makefile->FindTargetToUse(it->c_str()))
-      {
-      depString += sep + "$<TARGET_PROPERTY:"
-                + *it + ",INTERFACE_COMPILE_DEFINITIONS>";
-      sep = ";";
-      }
-    }
+  processCompileDefinitions(this,
+                            this->Internal->CompileDefinitionsEntries,
+                            list,
+                            uniqueOptions,
+                            &dagChecker,
+                            config,
+                            debugDefines);
 
   std::string configString = config ? config : "";
   if (!this->Internal->CacheLinkInterfaceCompileDefinitionsDone[configString])
     {
-    cmGeneratorExpression ge2(lfbt);
-    cmsys::auto_ptr<cmCompiledGeneratorExpression> cge2 =
-                                                        ge2.Parse(depString);
-    this->Internal->CachedLinkInterfaceCompileDefinitions[configString] =
-                                                cge2->Evaluate(this->Makefile,
-                                                               config,
-                                                               false,
-                                                               this,
-                                                               &dagChecker);
-    }
-  if (!this->Internal->CachedLinkInterfaceCompileDefinitions[configString]
-                                                                    .empty())
-    {
-    result += (result.empty() ? "" : ";")
-        + this->Internal->CachedLinkInterfaceCompileDefinitions[configString];
+    for (std::vector<cmValueWithOrigin>::const_iterator
+        it = this->Internal->LinkInterfacePropertyEntries.begin(),
+        end = this->Internal->LinkInterfacePropertyEntries.end();
+        it != end; ++it)
+      {
+      {
+      cmGeneratorExpression ge(lfbt);
+      cmsys::auto_ptr<cmCompiledGeneratorExpression> cge =
+                                                        ge.Parse(it->Value);
+      std::string targetResult = cge->Evaluate(this->Makefile, config,
+                                        false, this, 0, 0);
+      if (!this->Makefile->FindTargetToUse(targetResult.c_str()))
+        {
+        continue;
+        }
+      }
+      std::string defsGenex = "$<TARGET_PROPERTY:" +
+                              it->Value + ",INTERFACE_COMPILE_DEFINITIONS>";
+      if (cmGeneratorExpression::Find(it->Value) != std::string::npos)
+        {
+        // Because it->Value is a generator expression, ensure that it
+        // evaluates to the non-empty string before being used in the
+        // TARGET_PROPERTY expression.
+        defsGenex = "$<$<BOOL:" + it->Value + ">:" + defsGenex + ">";
+        }
+      cmGeneratorExpression ge(it->Backtrace);
+      cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(
+                                                                defsGenex);
+
+      this->Internal
+        ->CachedLinkInterfaceCompileDefinitionsEntries[configString].push_back(
+                        new cmTargetInternals::TargetPropertyEntry(cge,
+                                                              it->Value));
+      }
+    if (config)
+      {
+      std::string configPropName = "COMPILE_DEFINITIONS_"
+                                          + cmSystemTools::UpperCase(config);
+      const char *configProp = this->GetProperty(configPropName.c_str());
+      std::string defsString = (configProp ? configProp : "");
+
+      cmGeneratorExpression ge(lfbt);
+      cmsys::auto_ptr<cmCompiledGeneratorExpression> cge =
+                                                        ge.Parse(defsString);
+      this->Internal
+        ->CachedLinkInterfaceCompileDefinitionsEntries[configString].push_back(
+                        new cmTargetInternals::TargetPropertyEntry(cge));
+      }
+
     }
 
+  processCompileDefinitions(this,
+    this->Internal->CachedLinkInterfaceCompileDefinitionsEntries[configString],
+                            list,
+                            uniqueOptions,
+                            &dagChecker,
+                            config,
+                            debugDefines);
+
   if (!this->Makefile->IsGeneratingBuildSystem())
     {
-    this->Internal->CachedLinkInterfaceCompileDefinitions[configString] = "";
+    deleteAndClear(this->Internal
+                              ->CachedLinkInterfaceCompileDefinitionsEntries);
     }
   else
     {
     this->Internal->CacheLinkInterfaceCompileDefinitionsDone[configString]
                                                                       = true;
     }
-
-  cmSystemTools::ExpandListArgument(result, list);
 }
 
 //----------------------------------------------------------------------------
@@ -3841,6 +3928,24 @@ const char *cmTarget::GetProperty(const char* prop,
       }
     return output.c_str();
     }
+  if(strcmp(prop,"COMPILE_DEFINITIONS") == 0)
+    {
+    static std::string output;
+    output = "";
+    std::string sep;
+    typedef cmTargetInternals::TargetPropertyEntry
+                                TargetPropertyEntry;
+    for (std::vector<TargetPropertyEntry*>::const_iterator
+        it = this->Internal->CompileDefinitionsEntries.begin(),
+        end = this->Internal->CompileDefinitionsEntries.end();
+        it != end; ++it)
+      {
+      output += sep;
+      output += (*it)->ge->GetInput();
+      sep = ";";
+      }
+    return output.c_str();
+    }
 
   if (strcmp(prop,"IMPORTED") == 0)
     {
@@ -6566,6 +6671,7 @@ cmTargetInternalPointer::~cmTargetInternalPointer()
 {
   deleteAndClear(this->Pointer->IncludeDirectoriesEntries);
   deleteAndClear(this->Pointer->CompileOptionsEntries);
+  deleteAndClear(this->Pointer->CompileDefinitionsEntries);
   delete this->Pointer;
 }
 

+ 3 - 0
Source/cmTarget.h

@@ -514,6 +514,8 @@ public:
                      bool before = false);
   void InsertCompileOption(const cmValueWithOrigin &entry,
                      bool before = false);
+  void InsertCompileDefinition(const cmValueWithOrigin &entry,
+                     bool before = false);
 
   void AppendBuildInterfaceIncludes();
 
@@ -650,6 +652,7 @@ private:
   bool IsImportedTarget;
   bool DebugIncludesDone;
   bool DebugCompileOptionsDone;
+  bool DebugCompileDefinitionsDone;
   mutable std::set<std::string> LinkImplicitNullProperties;
   bool BuildInterfaceIncludesAppended;