Bladeren bron

Ninja: use deps = gcc/msvc feature

cmcldeps is now only used for .rc file processing
Peter Kümmel 12 jaren geleden
bovenliggende
commit
eeb4aece1c

+ 1 - 1
Modules/CMakeCCompiler.cmake.in

@@ -55,4 +55,4 @@ set(CMAKE_C_IMPLICIT_LINK_DIRECTORIES "@CMAKE_C_IMPLICIT_LINK_DIRECTORIES@")
 set(CMAKE_C_IMPLICIT_LINK_FRAMEWORK_DIRECTORIES "@CMAKE_C_IMPLICIT_LINK_FRAMEWORK_DIRECTORIES@")
 
 @SET_CMAKE_CMCLDEPS_EXECUTABLE@
-@SET_CMAKE_CL_SHOWINCLUDE_PREFIX@
+@SET_CMAKE_CL_SHOWINCLUDES_PREFIX@

+ 1 - 1
Modules/CMakeCXXCompiler.cmake.in

@@ -56,4 +56,4 @@ set(CMAKE_CXX_IMPLICIT_LINK_DIRECTORIES "@CMAKE_CXX_IMPLICIT_LINK_DIRECTORIES@")
 set(CMAKE_CXX_IMPLICIT_LINK_FRAMEWORK_DIRECTORIES "@CMAKE_CXX_IMPLICIT_LINK_FRAMEWORK_DIRECTORIES@")
 
 @SET_CMAKE_CMCLDEPS_EXECUTABLE@
-@SET_CMAKE_CL_SHOWINCLUDE_PREFIX@
+@SET_CMAKE_CL_SHOWINCLUDES_PREFIX@

+ 2 - 2
Modules/CMakeClDeps.cmake

@@ -20,7 +20,7 @@
 # in front of each include path, so it can remove it.
 #
 
-if(MSVC_C_ARCHITECTURE_ID AND CMAKE_GENERATOR MATCHES "Ninja" AND CMAKE_C_COMPILER AND CMAKE_COMMAND)
+if(CMAKE_GENERATOR MATCHES "Ninja" AND CMAKE_C_COMPILER AND CMAKE_COMMAND)
   string(REPLACE "cmake.exe" "cmcldeps.exe"  CMAKE_CMCLDEPS_EXECUTABLE ${CMAKE_COMMAND})
   set(showdir ${CMAKE_BINARY_DIR}/CMakeFiles/ShowIncludes)
   file(WRITE ${showdir}/foo.h "\n")
@@ -30,5 +30,5 @@ if(MSVC_C_ARCHITECTURE_ID AND CMAKE_GENERATOR MATCHES "Ninja" AND CMAKE_C_COMPIL
   string(REGEX MATCH "\n([^:]*:[^:]*:[ \t]*)" tmp "${outLine}")
   set(localizedPrefix "${CMAKE_MATCH_1}")
   set(SET_CMAKE_CMCLDEPS_EXECUTABLE   "set(CMAKE_CMCLDEPS_EXECUTABLE \"${CMAKE_CMCLDEPS_EXECUTABLE}\")")
-  set(SET_CMAKE_CL_SHOWINCLUDE_PREFIX "set(CMAKE_CL_SHOWINCLUDE_PREFIX \"${localizedPrefix}\")")
+  set(SET_CMAKE_CL_SHOWINCLUDES_PREFIX "set(CMAKE_CL_SHOWINCLUDES_PREFIX \"${localizedPrefix}\")")
 endif()

+ 2 - 1
Modules/CMakeDetermineCCompiler.cmake

@@ -176,12 +176,13 @@ if (CMAKE_CROSSCOMPILING  AND NOT _CMAKE_TOOLCHAIN_PREFIX)
 
 endif ()
 
-include(${CMAKE_ROOT}/Modules/CMakeClDeps.cmake)
 include(CMakeFindBinUtils)
 if(MSVC_C_ARCHITECTURE_ID)
+  include(${CMAKE_ROOT}/Modules/CMakeClDeps.cmake)
   set(SET_MSVC_C_ARCHITECTURE_ID
     "set(MSVC_C_ARCHITECTURE_ID ${MSVC_C_ARCHITECTURE_ID})")
 endif()
+
 # configure variables set in this file for fast reload later on
 configure_file(${CMAKE_ROOT}/Modules/CMakeCCompiler.cmake.in
   ${CMAKE_PLATFORM_INFO_DIR}/CMakeCCompiler.cmake

+ 2 - 1
Modules/CMakeDetermineCXXCompiler.cmake

@@ -175,12 +175,13 @@ if (CMAKE_CROSSCOMPILING  AND NOT  _CMAKE_TOOLCHAIN_PREFIX)
 
 endif ()
 
-include(${CMAKE_ROOT}/Modules/CMakeClDeps.cmake)
 include(CMakeFindBinUtils)
 if(MSVC_CXX_ARCHITECTURE_ID)
+  include(${CMAKE_ROOT}/Modules/CMakeClDeps.cmake)
   set(SET_MSVC_CXX_ARCHITECTURE_ID
     "set(MSVC_CXX_ARCHITECTURE_ID ${MSVC_CXX_ARCHITECTURE_ID})")
 endif()
+
 # configure all variables set in this file
 configure_file(${CMAKE_ROOT}/Modules/CMakeCXXCompiler.cmake.in
   ${CMAKE_PLATFORM_INFO_DIR}/CMakeCXXCompiler.cmake

+ 31 - 5
Source/cmGlobalNinjaGenerator.cxx

@@ -102,6 +102,13 @@ std::string cmGlobalNinjaGenerator::EncodePath(const std::string &path)
   return EncodeLiteral(result);
 }
 
+std::string cmGlobalNinjaGenerator::EncodeDepfileSpace(const std::string &path)
+{
+  std::string result = path;
+  cmSystemTools::ReplaceString(result, " ", "\\ ");
+  return result;
+}
+
 void cmGlobalNinjaGenerator::WriteBuild(std::ostream& os,
                                         const std::string& comment,
                                         const std::string& rule,
@@ -236,9 +243,11 @@ void cmGlobalNinjaGenerator::AddCustomCommandRule()
                 "$DESC",
                 "Rule for running custom commands.",
                 /*depfile*/ "",
+                /*deptype*/ "",
                 /*rspfile*/ "",
                 /*rspcontent*/ "",
-                /*restat*/ true);
+                /*restat*/ true,
+                /*generator*/ false);
 }
 
 void
@@ -247,7 +256,7 @@ cmGlobalNinjaGenerator::WriteCustomCommandBuild(const std::string& command,
                                                 const std::string& comment,
                                                 const cmNinjaDeps& outputs,
                                                 const cmNinjaDeps& deps,
-                                              const cmNinjaDeps& orderOnlyDeps)
+                                                const cmNinjaDeps& orderOnly)
 {
   std::string cmd = command;
 #ifdef _WIN32
@@ -268,7 +277,7 @@ cmGlobalNinjaGenerator::WriteCustomCommandBuild(const std::string& command,
                    outputs,
                    deps,
                    cmNinjaDeps(),
-                   orderOnlyDeps,
+                   orderOnly,
                    vars);
 }
 
@@ -287,9 +296,13 @@ cmGlobalNinjaGenerator::AddMacOSXContentRule()
   this->AddRule("COPY_OSX_CONTENT",
                 cmd.str(),
                 "Copying OS X Content $out",
-                "Rule for copying OS X bundle content file."
+                "Rule for copying OS X bundle content file.",
                 /*depfile*/ "",
-                /*rspfile*/ "");
+                /*deptype*/ "",
+                /*rspfile*/ "",
+                /*rspcontent*/ "",
+                /*restat*/ false,
+                /*generator*/ false);
 }
 
 void
@@ -320,6 +333,7 @@ void cmGlobalNinjaGenerator::WriteRule(std::ostream& os,
                                        const std::string& description,
                                        const std::string& comment,
                                        const std::string& depfile,
+                                       const std::string& deptype,
                                        const std::string& rspfile,
                                        const std::string& rspcontent,
                                        bool restat,
@@ -355,6 +369,13 @@ void cmGlobalNinjaGenerator::WriteRule(std::ostream& os,
     os << "depfile = " << depfile << "\n";
     }
 
+  // Write the deptype if any.
+  if (!deptype.empty())
+    {
+    cmGlobalNinjaGenerator::Indent(os, 1);
+    os << "deps = " << deptype << "\n";
+    }
+
   // Write the command.
   cmGlobalNinjaGenerator::Indent(os, 1);
   os << "command = " << command << "\n";
@@ -583,6 +604,7 @@ void cmGlobalNinjaGenerator::AddRule(const std::string& name,
                                      const std::string& description,
                                      const std::string& comment,
                                      const std::string& depfile,
+                                     const std::string& deptype,
                                      const std::string& rspfile,
                                      const std::string& rspcontent,
                                      bool restat,
@@ -601,6 +623,7 @@ void cmGlobalNinjaGenerator::AddRule(const std::string& name,
                                     description,
                                     comment,
                                     depfile,
+                                    deptype,
                                     rspfile,
                                     rspcontent,
                                     restat,
@@ -1089,6 +1112,7 @@ void cmGlobalNinjaGenerator::WriteTargetRebuildManifest(std::ostream& os)
             "Re-running CMake...",
             "Rule for re-running cmake.",
             /*depfile=*/ "",
+            /*deptype=*/ "",
             /*rspfile=*/ "",
             /*rspcontent*/ "",
             /*restat=*/ false,
@@ -1142,6 +1166,7 @@ void cmGlobalNinjaGenerator::WriteTargetClean(std::ostream& os)
             "Cleaning all built files...",
             "Rule for cleaning all built files.",
             /*depfile=*/ "",
+            /*deptype=*/ "",
             /*rspfile=*/ "",
             /*rspcontent*/ "",
             /*restat=*/ false,
@@ -1164,6 +1189,7 @@ void cmGlobalNinjaGenerator::WriteTargetHelp(std::ostream& os)
             "All primary targets available:",
             "Rule for printing all primary targets available.",
             /*depfile=*/ "",
+            /*deptype=*/ "",
             /*rspfile=*/ "",
             /*rspcontent*/ "",
             /*restat=*/ false,

+ 9 - 6
Source/cmGlobalNinjaGenerator.h

@@ -64,6 +64,7 @@ public:
   static std::string EncodeIdent(const std::string &ident, std::ostream &vars);
   static std::string EncodeLiteral(const std::string &lit);
   static std::string EncodePath(const std::string &path);
+  static std::string EncodeDepfileSpace(const std::string &path);
 
   /**
    * Write the given @a comment to the output stream @a os. It
@@ -104,7 +105,7 @@ public:
                                const std::string& comment,
                                const cmNinjaDeps& outputs,
                                const cmNinjaDeps& deps = cmNinjaDeps(),
-                             const cmNinjaDeps& orderOnlyDeps = cmNinjaDeps());
+                               const cmNinjaDeps& orderOnly = cmNinjaDeps());
   void WriteMacOSXContentBuild(const std::string& input,
                                const std::string& output);
 
@@ -120,6 +121,7 @@ public:
                         const std::string& description,
                         const std::string& comment,
                         const std::string& depfile,
+                        const std::string& deptype,
                         const std::string& rspfile,
                         const std::string& rspcontent,
                         bool restat,
@@ -239,11 +241,12 @@ public:
                const std::string& command,
                const std::string& description,
                const std::string& comment,
-               const std::string& depfile = "",
-               const std::string& rspfile = "",
-               const std::string& rspcontent = "",
-               bool restat = false,
-               bool generator = false);
+               const std::string& depfile,
+               const std::string& deptype,
+               const std::string& rspfile,
+               const std::string& rspcontent,
+               bool restat,
+               bool generator);
 
   bool HasRule(const std::string& name);
 

+ 15 - 5
Source/cmLocalNinjaGenerator.cxx

@@ -48,7 +48,21 @@ void cmLocalNinjaGenerator::Generate()
   this->WriteProcessedMakefile(this->GetRulesFileStream());
 #endif
 
-  this->WriteBuildFileTop();
+  // We do that only once for the top CMakeLists.txt file.
+  if(this->isRootMakefile())
+    {
+    this->WriteBuildFileTop();
+
+    const std::string showIncludesPrefix = this->GetMakefile()
+             ->GetSafeDefinition("CMAKE_CL_SHOWINCLUDES_PREFIX");
+    if (!showIncludesPrefix.empty())
+      {
+      cmGlobalNinjaGenerator::WriteComment(this->GetRulesFileStream(),
+                                           "localized /showIncludes string");
+      this->GetRulesFileStream()
+            << "msvc_deps_prefix = " << showIncludesPrefix << "\n\n";
+      }
+    }
 
   cmTargets& targets = this->GetMakefile()->GetTargets();
   for(cmTargets::iterator t = targets.begin(); t != targets.end(); ++t)
@@ -163,10 +177,6 @@ bool cmLocalNinjaGenerator::isRootMakefile() const
 
 void cmLocalNinjaGenerator::WriteBuildFileTop()
 {
-  // We do that only once for the top CMakeLists.txt file.
-  if(!this->isRootMakefile())
-    return;
-
   // For the build file.
   this->WriteProjectHeader(this->GetBuildFileStream());
   this->WriteNinjaFilesInclusion(this->GetBuildFileStream());

+ 20 - 3
Source/cmNinjaNormalTargetGenerator.cxx

@@ -261,8 +261,11 @@ cmNinjaNormalTargetGenerator
                                         description.str(),
                                         comment.str(),
                                         /*depfile*/ "",
+                                        /*deptype*/ "",
                                         rspfile,
-                                        rspcontent);
+                                        rspcontent,
+                                        /*restat*/ false,
+                                        /*generator*/ false);
   }
 
   if (this->TargetNameOut != this->TargetNameReal &&
@@ -277,14 +280,28 @@ cmNinjaNormalTargetGenerator
                                           " -E cmake_symlink_executable"
                                           " $in $out && $POST_BUILD",
                                           "Creating executable symlink $out",
-                                      "Rule for creating executable symlink.");
+                                          "Rule for creating "
+                                          "executable symlink.",
+                                          /*depfile*/ "",
+                                          /*deptype*/ "",
+                                          /*rspfile*/ "",
+                                          /*rspcontent*/ "",
+                                          /*restat*/ false,
+                                          /*generator*/ false);
     else
       this->GetGlobalGenerator()->AddRule("CMAKE_SYMLINK_LIBRARY",
                                           cmakeCommand +
                                           " -E cmake_symlink_library"
                                           " $in $SONAME $out && $POST_BUILD",
                                           "Creating library symlink $out",
-                                         "Rule for creating library symlink.");
+                                          "Rule for creating "
+                                          "library symlink.",
+                                          /*depfile*/ "",
+                                          /*deptype*/ "",
+                                          /*rspfile*/ "",
+                                          /*rspcontent*/ "",
+                                          /*restat*/ false,
+                                          /*generator*/ false);
   }
 }
 

+ 73 - 52
Source/cmNinjaTargetGenerator.cxx

@@ -187,6 +187,21 @@ cmNinjaTargetGenerator::ComputeFlagsForObject(cmSourceFile *source,
   return flags;
 }
 
+
+bool cmNinjaTargetGenerator::needsDepFile(const std::string& lang)
+{
+  cmMakefile* mf = this->GetMakefile();
+
+  const bool usingMSVC = std::string("MSVC") ==
+                       (mf->GetDefinition("CMAKE_C_COMPILER_ID") ?
+                    mf->GetSafeDefinition("CMAKE_C_COMPILER_ID") :
+                    mf->GetSafeDefinition("CMAKE_CXX_COMPILER_ID"));
+
+  return !usingMSVC || lang == "RC";
+}
+
+
+
 // TODO: Refactor with
 // void cmMakefileTargetGenerator::WriteTargetLanguageFlags().
 std::string
@@ -331,77 +346,75 @@ cmNinjaTargetGenerator
 
 void
 cmNinjaTargetGenerator
-::WriteCompileRule(const std::string& language)
+::WriteCompileRule(const std::string& lang)
 {
   cmLocalGenerator::RuleVariables vars;
   vars.RuleLauncher = "RULE_LAUNCH_COMPILE";
   vars.CMTarget = this->GetTarget();
-  std::string lang = language;
   vars.Language = lang.c_str();
   vars.Source = "$in";
   vars.Object = "$out";
-  std::string flags = "$FLAGS";
   vars.Defines = "$DEFINES";
   vars.TargetPDB = "$TARGET_PDB";
   vars.ObjectDir = "$OBJECT_DIR";
 
   cmMakefile* mf = this->GetMakefile();
 
-  bool useClDeps = false;
-  std::string clBinary;
-  std::string clDepsBinary;
-  std::string clShowPrefix;
-  if (lang == "C" || lang == "CXX" || lang == "RC")
+  const bool usingMSVC = std::string("MSVC") ==
+                       (mf->GetDefinition("CMAKE_C_COMPILER_ID") ?
+                    mf->GetSafeDefinition("CMAKE_C_COMPILER_ID") :
+                    mf->GetSafeDefinition("CMAKE_CXX_COMPILER_ID"));
+
+  // Tell ninja dependency format so all deps can be loaded into a database
+  std::string deptype;
+  std::string depfile;
+  std::string cldeps;
+  std::string flags = "$FLAGS";
+  if (usingMSVC)
     {
-    clDepsBinary = mf->GetSafeDefinition("CMAKE_CMCLDEPS_EXECUTABLE");
-    if (!clDepsBinary.empty() && !mf->GetIsSourceFileTryCompile())
+    if (!mf->GetIsSourceFileTryCompile() && lang == "RC")
       {
-      clShowPrefix = mf->GetSafeDefinition("CMAKE_CL_SHOWINCLUDE_PREFIX");
-      clBinary = mf->GetDefinition("CMAKE_C_COMPILER") ?
-                 mf->GetSafeDefinition("CMAKE_C_COMPILER") :
-                 mf->GetSafeDefinition("CMAKE_CXX_COMPILER");
-      if (!clBinary.empty() && !clShowPrefix.empty())
-        {
-        useClDeps = true;
-        const std::string quote = " \"";
-        clBinary     = quote + clBinary     + "\" ";
-        clDepsBinary = quote + clDepsBinary + "\" ";
-        clShowPrefix = quote + clShowPrefix + "\" ";
-        vars.DependencyFile = "$DEP_FILE";
-        }
+      deptype = "gcc";
+      depfile = "$DEP_FILE";
+      const std::string cl = mf->GetDefinition("CMAKE_C_COMPILER") ?
+                        mf->GetSafeDefinition("CMAKE_C_COMPILER") :
+                        mf->GetSafeDefinition("CMAKE_CXX_COMPILER");
+      cldeps =  "\"";
+      cldeps += mf->GetSafeDefinition("CMAKE_CMCLDEPS_EXECUTABLE");
+      cldeps += "\" " + lang + " $in \"$DEP_FILE\" $out \"";
+      cldeps += mf->GetSafeDefinition("CMAKE_CL_SHOWINCLUDES_PREFIX");
+      cldeps += "\" \"" + cl + "\" ";
+      }
+    else
+      {
+      deptype = "msvc";
+      depfile = "";
+      flags += " /showIncludes";
       }
     }
-
-
-  std::string depfile;
-  std::string depfileFlagsName = "CMAKE_DEPFILE_FLAGS_" + language;
-  const char *depfileFlags = mf->GetDefinition(depfileFlagsName.c_str());
-  if (depfileFlags || useClDeps) {
-    std::string depFlagsStr = depfileFlags ? depfileFlags : "";
+  else
+    {
+    deptype = "gcc";
     depfile = "$DEP_FILE";
-    cmSystemTools::ReplaceString(depFlagsStr, "<DEPFILE>", "\"$DEP_FILE\"");
-    cmSystemTools::ReplaceString(depFlagsStr, "<OBJECT>",  "$out");
-    cmSystemTools::ReplaceString(depFlagsStr, "<CMAKE_C_COMPILER>",
-                       mf->GetDefinition("CMAKE_C_COMPILER"));
-    flags += " " + depFlagsStr;
-  }
-  vars.Flags = flags.c_str();
+    const std::string flagsName = "CMAKE_DEPFILE_FLAGS_" + lang;
+    std::string depfileFlags = mf->GetSafeDefinition(flagsName.c_str());
+    cmSystemTools::ReplaceString(depfileFlags, "<DEPFILE>", "$DEP_FILE");
+    cmSystemTools::ReplaceString(depfileFlags, "<OBJECT>",  "$out");
+    cmSystemTools::ReplaceString(depfileFlags, "<CMAKE_C_COMPILER>",
+                                 mf->GetDefinition("CMAKE_C_COMPILER"));
+    flags += " " + depfileFlags;
+    }
 
+  vars.Flags = flags.c_str();
+  vars.DependencyFile = depfile.c_str();
 
   // Rule for compiling object file.
-  std::string compileCmdVar = "CMAKE_";
-  compileCmdVar += language;
-  compileCmdVar += "_COMPILE_OBJECT";
-  std::string compileCmd = mf->GetRequiredDefinition(compileCmdVar.c_str());
+  const std::string cmdVar = std::string("CMAKE_") + lang + "_COMPILE_OBJECT";
+  std::string compileCmd = mf->GetRequiredDefinition(cmdVar.c_str());
   std::vector<std::string> compileCmds;
   cmSystemTools::ExpandListArgument(compileCmd, compileCmds);
 
-  if(useClDeps)
-    {
-    std::string cmdPrefix = clDepsBinary + lang + " $in \"$DEP_FILE\" $out " +
-                            clShowPrefix + clBinary;
-    compileCmds.front().insert(0, cmdPrefix);
-    }
+  compileCmds.front().insert(0, cldeps);
 
   for (std::vector<std::string>::iterator i = compileCmds.begin();
        i != compileCmds.end(); ++i)
@@ -413,14 +426,19 @@ cmNinjaTargetGenerator
 
   // Write the rule for compiling file of the given language.
   cmOStringStream comment;
-  comment << "Rule for compiling " << language << " files.";
+  comment << "Rule for compiling " << lang << " files.";
   cmOStringStream description;
-  description << "Building " << language << " object $out";
-  this->GetGlobalGenerator()->AddRule(this->LanguageCompilerRule(language),
+  description << "Building " << lang << " object $out";
+  this->GetGlobalGenerator()->AddRule(this->LanguageCompilerRule(lang),
                                       cmdLine,
                                       description.str(),
                                       comment.str(),
-                                      depfile);
+                                      depfile,
+                                      deptype,
+                                      /*rspfile*/ "",
+                                      /*rspcontent*/ "",
+                                      /*restat*/ false,
+                                      /*generator*/ false);
 }
 
 void
@@ -540,7 +558,10 @@ cmNinjaTargetGenerator
   cmNinjaVars vars;
   vars["FLAGS"] = this->ComputeFlagsForObject(source, language);
   vars["DEFINES"] = this->ComputeDefines(source, language);
-  vars["DEP_FILE"] = objectFileName + ".d";;
+  if (needsDepFile(language)) {
+    vars["DEP_FILE"] =
+            cmGlobalNinjaGenerator::EncodeDepfileSpace(objectFileName + ".d");
+  }
   EnsureParentDirectoryExists(objectFileName);
 
   std::string objectDir = cmSystemTools::GetFilenamePath(objectFileName);

+ 2 - 0
Source/cmNinjaTargetGenerator.h

@@ -42,6 +42,8 @@ public:
 
   std::string GetTargetName() const;
 
+  bool needsDepFile(const std::string& lang);
+
 protected:
 
   bool SetMsvcTargetPdbVariable(cmNinjaVars&) const;