Explorar o código

Optionally pass include directories with response files

Create platform option CMAKE_<lang>_USE_RESPONSE_FILE_FOR_INCLUDES to
enable use of response files for passing the list of include directories
to compiler command lines.
Brad King %!s(int64=14) %!d(string=hai) anos
pai
achega
9a0b9bc8b7

+ 2 - 0
Source/cmDocumentVariables.cxx

@@ -1451,6 +1451,8 @@ void cmDocumentVariables::DefineVariables(cmake* cm)
                      cmProperty::VARIABLE,0,0);
   cm->DefineProperty("CMAKE_<LANG>_STANDARD_LIBRARIES_INIT",
                      cmProperty::VARIABLE,0,0);
+  cm->DefineProperty("CMAKE_<LANG>_USE_RESPONSE_FILE_FOR_INCLUDES",
+                     cmProperty::VARIABLE,0,0);
   cm->DefineProperty("CMAKE_<LANG>_USE_RESPONSE_FILE_FOR_OBJECTS",
                      cmProperty::VARIABLE,0,0);
   cm->DefineProperty("CMAKE_EXECUTABLE_SUFFIX_<LANG>",

+ 20 - 8
Source/cmLocalGenerator.cxx

@@ -1185,15 +1185,18 @@ cmLocalGenerator::ConvertToOutputForExisting(RelativeRoot remote,
 }
 
 //----------------------------------------------------------------------------
-const char* cmLocalGenerator::GetIncludeFlags(const char* lang)
+const char* cmLocalGenerator::GetIncludeFlags(const char* lang,
+                                              bool forResponseFile)
 {
   if(!lang)
     {
     return "";
     }
-  if(this->LanguageToIncludeFlags.count(lang))
+  std::string key = lang;
+  key += forResponseFile? "@" : "";
+  if(this->LanguageToIncludeFlags.count(key))
     {
-    return this->LanguageToIncludeFlags[lang].c_str();
+    return this->LanguageToIncludeFlags[key].c_str();
     }
 
   cmOStringStream includeFlags;
@@ -1251,10 +1254,10 @@ const char* cmLocalGenerator::GetIncludeFlags(const char* lang)
       frameworkDir = cmSystemTools::CollapseFullPath(frameworkDir.c_str());
       if(emitted.insert(frameworkDir).second)
         {
+        OutputFormat format = forResponseFile? RESPONSE : SHELL;
         includeFlags
           << "-F" << this->Convert(frameworkDir.c_str(),
-                                   cmLocalGenerator::START_OUTPUT,
-                                   cmLocalGenerator::SHELL, true)
+                                   START_OUTPUT, format, true)
           << " ";
         }
       continue;
@@ -1274,7 +1277,16 @@ const char* cmLocalGenerator::GetIncludeFlags(const char* lang)
         }
       flagUsed = true;
       }
-    std::string includePath = this->ConvertToOutputForExisting(i->c_str());
+    std::string includePath;
+    if(forResponseFile)
+      {
+      includePath = this->Convert(i->c_str(), START_OUTPUT,
+                                  RESPONSE, true);
+      }
+    else
+      {
+      includePath = this->ConvertToOutputForExisting(i->c_str());
+      }
     if(quotePaths && includePath.size() && includePath[0] != '\"')
       {
       includeFlags << "\"";
@@ -1292,11 +1304,11 @@ const char* cmLocalGenerator::GetIncludeFlags(const char* lang)
     {
     flags[flags.size()-1] = ' ';
     }
-  this->LanguageToIncludeFlags[lang] = flags;
+  this->LanguageToIncludeFlags[key] = flags;
 
   // Use this temorary variable for the return value to work-around a
   // bogus GCC 2.95 warning.
-  const char* ret = this->LanguageToIncludeFlags[lang].c_str();
+  const char* ret = this->LanguageToIncludeFlags[key].c_str();
   return ret;
 }
 

+ 2 - 1
Source/cmLocalGenerator.h

@@ -143,7 +143,8 @@ public:
                               const char* config);
   virtual void AppendFlags(std::string& flags, const char* newFlags);
   ///! Get the include flags for the current makefile and language
-  const char* GetIncludeFlags(const char* lang); 
+  const char* GetIncludeFlags(const char* lang,
+                              bool forResponseFile = false);
 
   /**
    * Encode a list of preprocessor definitions for the compiler

+ 14 - 0
Source/cmLocalUnixMakefileGenerator3.cxx

@@ -880,6 +880,20 @@ cmLocalUnixMakefileGenerator3
     }
 }
 
+//----------------------------------------------------------------------------
+void
+cmLocalUnixMakefileGenerator3
+::AppendRuleDepends(std::vector<std::string>& depends,
+                    std::vector<std::string> const& ruleFiles)
+{
+  // Add a dependency on the rule file itself unless an option to skip
+  // it is specifically enabled by the user or project.
+  if(!this->Makefile->IsOn("CMAKE_SKIP_RULE_DEPENDENCY"))
+    {
+    depends.insert(depends.end(), ruleFiles.begin(), ruleFiles.end());
+    }
+}
+
 //----------------------------------------------------------------------------
 void
 cmLocalUnixMakefileGenerator3

+ 2 - 0
Source/cmLocalUnixMakefileGenerator3.h

@@ -320,6 +320,8 @@ protected:
 
   void AppendRuleDepend(std::vector<std::string>& depends,
                         const char* ruleFileName);
+  void AppendRuleDepends(std::vector<std::string>& depends,
+                         std::vector<std::string> const& ruleFiles);
   void AppendCustomDepends(std::vector<std::string>& depends,
                            const std::vector<cmCustomCommand>& ccs);
   void AppendCustomDepend(std::vector<std::string>& depends,

+ 35 - 2
Source/cmMakefileTargetGenerator.cxx

@@ -310,8 +310,7 @@ void cmMakefileTargetGenerator::WriteTargetLanguageFlags()
     this->LocalGenerator->AddSharedFlags(flags, lang, shared);
 
     // Add include directory flags.
-    this->LocalGenerator->
-      AppendFlags(flags, this->LocalGenerator->GetIncludeFlags(lang));
+    this->AddIncludeFlags(flags, lang);
 
     // Append old-style preprocessor definition flags.
     this->LocalGenerator->
@@ -487,6 +486,8 @@ cmMakefileTargetGenerator
 {
   this->LocalGenerator->AppendRuleDepend(depends,
                                          this->FlagFileNameFull.c_str());
+  this->LocalGenerator->AppendRuleDepends(depends,
+                                          this->FlagFileDepends[lang]);
 
   // generate the depend scanning rule
   this->WriteObjectDependRules(source, depends);
@@ -1724,6 +1725,38 @@ cmMakefileTargetGenerator
     }
 }
 
+//----------------------------------------------------------------------------
+void cmMakefileTargetGenerator::AddIncludeFlags(std::string& flags,
+                                                const char* lang)
+{
+  std::string responseVar = "CMAKE_";
+  responseVar += lang;
+  responseVar += "_USE_RESPONSE_FILE_FOR_INCLUDES";
+  bool useResponseFile = this->Makefile->IsOn(responseVar.c_str());
+
+  std::string includeFlags =
+    this->LocalGenerator->GetIncludeFlags(lang, useResponseFile);
+  if(includeFlags.empty())
+    {
+    return;
+    }
+
+  if(useResponseFile)
+    {
+    std::string name = "includes_";
+    name += lang;
+    name += ".rsp";
+    std::string arg = "@" +
+      this->CreateResponseFile(name.c_str(), includeFlags,
+                               this->FlagFileDepends[lang]);
+    this->LocalGenerator->AppendFlags(flags, arg.c_str());
+    }
+  else
+    {
+    this->LocalGenerator->AppendFlags(flags, includeFlags.c_str());
+    }
+}
+
 //----------------------------------------------------------------------------
 const char* cmMakefileTargetGenerator::GetFortranModuleDirectory()
 {

+ 4 - 0
Source/cmMakefileTargetGenerator.h

@@ -146,6 +146,8 @@ protected:
                          bool useResponseFile, std::string& buildObjs,
                          std::vector<std::string>& makefile_depends);
 
+  void AddIncludeFlags(std::string& flags, const char* lang);
+
   virtual void CloseFileStreams();
   void RemoveForbiddenFlags(const char* flagVar, const char* linkLang,
                             std::string& linkFlags);
@@ -177,6 +179,8 @@ protected:
   // the stream for the flag file
   std::string FlagFileNameFull;
   cmGeneratedFileStream *FlagFileStream;
+  class StringList: public std::vector<std::string> {};
+  std::map<cmStdString, StringList> FlagFileDepends;
 
   // the stream for the info file
   std::string InfoFileNameFull;