Explorar o código

Xcode: Add support of DEPFILE for add_custom_command, part 2

This MR extend the support of 'DEPFILE' to buildsystem version 1.

Issue: #20286
Marc Chevrier %!s(int64=4) %!d(string=hai) anos
pai
achega
253aff6c94

+ 0 - 8
Help/command/add_custom_command.rst

@@ -299,14 +299,6 @@ The options are:
     For :ref:`Makefile Generators`, this option cannot be specified at the
     same time as ``IMPLICIT_DEPENDS`` option.
 
-  .. note::
-
-    For the :generator:`Xcode` generator, this option requires that the
-    :ref:`Xcode Build System Selection` uses the ``buildsystem=12`` variant
-    or higher.  This is the default when using Xcode 12 or above.
-    The :variable:`CMAKE_XCODE_BUILD_SYSTEM` variable indicates which variant
-    of the Xcode build system is used.
-
 Examples: Generating Files
 ^^^^^^^^^^^^^^^^^^^^^^^^^^
 

+ 4 - 0
Source/cmCustomCommandGenerator.cxx

@@ -226,6 +226,9 @@ cmCustomCommandGenerator::cmCustomCommandGenerator(
       case cmDepfileFormat::VsTlog:
         argv.emplace_back("vstlog");
         break;
+      case cmDepfileFormat::MakeDepfile:
+        argv.emplace_back("makedepfile");
+        break;
     }
     argv.push_back(this->LG->GetSourceDirectory());
     argv.push_back(this->LG->GetCurrentSourceDirectory());
@@ -430,6 +433,7 @@ std::string cmCustomCommandGenerator::GetInternalDepfileName(
   std::string extension;
   switch (*this->LG->GetGlobalGenerator()->DepfileFormat()) {
     case cmDepfileFormat::GccDepfile:
+    case cmDepfileFormat::MakeDepfile:
       extension = ".d";
       break;
     case cmDepfileFormat::VsTlog:

+ 26 - 2
Source/cmGlobalXCodeGenerator.cxx

@@ -2213,9 +2213,33 @@ void cmGlobalXCodeGenerator::CreateCustomRulesMakefile(
     }
   }
   makefileStream << "\n\n";
+
+  auto depfilesDirectory =
+    cmStrCat(target->GetLocalGenerator()->GetCurrentBinaryDirectory(),
+             "/CMakeFiles/d/");
+
   for (auto const& command : commands) {
-    cmCustomCommandGenerator ccg(command, configName,
-                                 this->CurrentLocalGenerator);
+    cmCustomCommandGenerator ccg(
+      command, configName, this->CurrentLocalGenerator, true, {},
+      [this, &depfilesDirectory](const std::string& config,
+                                 const std::string& file) -> std::string {
+        return cmStrCat(
+          depfilesDirectory,
+          this->GetObjectId(cmXCodeObject::PBXShellScriptBuildPhase, file),
+          ".", config, ".d");
+      });
+
+    auto depfile = ccg.GetInternalDepfile();
+    if (!depfile.empty()) {
+      makefileStream << "include "
+                     << cmSystemTools::ConvertToOutputPath(depfile) << "\n\n";
+
+      cmSystemTools::MakeDirectory(depfilesDirectory);
+      if (!cmSystemTools::FileExists(depfile)) {
+        cmSystemTools::Touch(depfile, true);
+      }
+    }
+
     std::vector<std::string> realDepends;
     realDepends.reserve(ccg.GetDepends().size());
     for (auto const& d : ccg.GetDepends()) {

+ 4 - 5
Source/cmGlobalXCodeGenerator.h

@@ -115,13 +115,12 @@ public:
   /**
    * Used to determine if this generator supports DEPFILE option.
    */
-  bool SupportsCustomCommandDepfile() const override
-  {
-    return this->XcodeBuildSystem >= BuildSystem::Twelve;
-  }
+  bool SupportsCustomCommandDepfile() const override { return true; }
   virtual cm::optional<cmDepfileFormat> DepfileFormat() const override
   {
-    return cmDepfileFormat::GccDepfile;
+    return this->XcodeBuildSystem == BuildSystem::One
+      ? cmDepfileFormat::MakeDepfile
+      : cmDepfileFormat::GccDepfile;
   }
 
   bool SetSystemName(std::string const& s, cmMakefile* mf) override;

+ 17 - 3
Source/cmTransformDepfile.cxx

@@ -36,8 +36,9 @@ void WriteFilenameGcc(cmsys::ofstream& fout, const std::string& filename)
   }
 }
 
-void WriteGccDepfile(cmsys::ofstream& fout, const cmLocalGenerator& lg,
-                     const cmGccDepfileContent& content)
+void WriteDepfile(cmDepfileFormat format, cmsys::ofstream& fout,
+                  const cmLocalGenerator& lg,
+                  const cmGccDepfileContent& content)
 {
   const auto& binDir = lg.GetBinaryDirectory();
   std::function<std::string(const std::string&)> formatPath =
@@ -65,6 +66,18 @@ void WriteGccDepfile(cmsys::ofstream& fout, const cmLocalGenerator& lg,
     }
     fout << '\n';
   }
+
+  if (format == cmDepfileFormat::MakeDepfile) {
+    // In this case, phony targets must be added for all dependencies
+    fout << "\n";
+    for (auto const& dep : content) {
+      for (auto const& path : dep.paths) {
+        fout << "\n";
+        WriteFilenameGcc(fout, formatPath(path));
+        fout << ":\n";
+      }
+    }
+  }
 }
 
 // tlog format : always windows paths on Windows regardless the generator
@@ -122,7 +135,8 @@ bool cmTransformDepfile(cmDepfileFormat format, const cmLocalGenerator& lg,
   }
   switch (format) {
     case cmDepfileFormat::GccDepfile:
-      WriteGccDepfile(fout, lg, content);
+    case cmDepfileFormat::MakeDepfile:
+      WriteDepfile(format, fout, lg, content);
       break;
     case cmDepfileFormat::VsTlog:
       WriteVsTlog(fout, lg, content);

+ 1 - 0
Source/cmTransformDepfile.h

@@ -8,6 +8,7 @@ enum class cmDepfileFormat
 {
   GccDepfile,
   VsTlog,
+  MakeDepfile
 };
 
 class cmLocalGenerator;

+ 2 - 0
Source/cmcmd.cxx

@@ -1527,6 +1527,8 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string> const& args,
         format = cmDepfileFormat::GccDepfile;
       } else if (args[3] == "vstlog") {
         format = cmDepfileFormat::VsTlog;
+      } else if (args[3] == "makedepfile") {
+        format = cmDepfileFormat::MakeDepfile;
       } else {
         return 1;
       }

+ 1 - 2
Tests/RunCMake/BuildDepends/RunCMakeTest.cmake

@@ -155,8 +155,7 @@ if (RunCMake_GENERATOR MATCHES "Makefiles")
   run_cmake(CustomCommandDependencies-BadArgs)
 endif()
 
-if(RunCMake_GENERATOR MATCHES "Make|Ninja" OR
-    (RunCMake_GENERATOR STREQUAL "Xcode" AND CMAKE_XCODE_BUILD_SYSTEM GREATER_EQUAL "12"))
+if(RunCMake_GENERATOR MATCHES "Make|Ninja|Xcode")
   unset(run_BuildDepends_skip_step_3)
   run_BuildDepends(CustomCommandDepfile)
   set(run_BuildDepends_skip_step_3 1)

+ 0 - 1
Tests/RunCMake/CMakeLists.txt

@@ -222,7 +222,6 @@ endif()
 
 add_RunCMake_test(BuildDepends
   -DMSVC_VERSION=${MSVC_VERSION}
-  -DCMAKE_XCODE_BUILD_SYSTEM=${CMAKE_XCODE_BUILD_SYSTEM}
   -DCMAKE_C_COMPILER_ID=${CMAKE_C_COMPILER_ID}
   -DCMake_TEST_BuildDepends_GNU_AS=${CMake_TEST_BuildDepends_GNU_AS}
   )