Merge topic 'Xcode-add_custom_command-DEPFILE'

253aff6c94 Xcode: Add support of DEPFILE for add_custom_command, part 2

Acked-by: Kitware Robot <kwrobot@kitware.com>
Merge-request: !6015
diff --git a/Help/command/add_custom_command.rst b/Help/command/add_custom_command.rst
index c0ff81a..569f1e8 100644
--- a/Help/command/add_custom_command.rst
+++ b/Help/command/add_custom_command.rst
@@ -299,14 +299,6 @@
     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
 ^^^^^^^^^^^^^^^^^^^^^^^^^^
 
diff --git a/Source/cmCustomCommandGenerator.cxx b/Source/cmCustomCommandGenerator.cxx
index 7659792..1054beb 100644
--- a/Source/cmCustomCommandGenerator.cxx
+++ b/Source/cmCustomCommandGenerator.cxx
@@ -226,6 +226,9 @@
       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 extension;
   switch (*this->LG->GetGlobalGenerator()->DepfileFormat()) {
     case cmDepfileFormat::GccDepfile:
+    case cmDepfileFormat::MakeDepfile:
       extension = ".d";
       break;
     case cmDepfileFormat::VsTlog:
diff --git a/Source/cmGlobalXCodeGenerator.cxx b/Source/cmGlobalXCodeGenerator.cxx
index dc3d3f2..92dd555 100644
--- a/Source/cmGlobalXCodeGenerator.cxx
+++ b/Source/cmGlobalXCodeGenerator.cxx
@@ -2213,9 +2213,33 @@
     }
   }
   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()) {
diff --git a/Source/cmGlobalXCodeGenerator.h b/Source/cmGlobalXCodeGenerator.h
index 2406472..ef61601 100644
--- a/Source/cmGlobalXCodeGenerator.h
+++ b/Source/cmGlobalXCodeGenerator.h
@@ -115,13 +115,12 @@
   /**
    * 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;
diff --git a/Source/cmTransformDepfile.cxx b/Source/cmTransformDepfile.cxx
index b693582..6e0366c 100644
--- a/Source/cmTransformDepfile.cxx
+++ b/Source/cmTransformDepfile.cxx
@@ -36,8 +36,9 @@
   }
 }
 
-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 @@
     }
     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 @@
   }
   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);
diff --git a/Source/cmTransformDepfile.h b/Source/cmTransformDepfile.h
index c43a45f..c31e4ab 100644
--- a/Source/cmTransformDepfile.h
+++ b/Source/cmTransformDepfile.h
@@ -8,6 +8,7 @@
 {
   GccDepfile,
   VsTlog,
+  MakeDepfile
 };
 
 class cmLocalGenerator;
diff --git a/Source/cmcmd.cxx b/Source/cmcmd.cxx
index 928435e..2c2ae4d 100644
--- a/Source/cmcmd.cxx
+++ b/Source/cmcmd.cxx
@@ -1527,6 +1527,8 @@
         format = cmDepfileFormat::GccDepfile;
       } else if (args[3] == "vstlog") {
         format = cmDepfileFormat::VsTlog;
+      } else if (args[3] == "makedepfile") {
+        format = cmDepfileFormat::MakeDepfile;
       } else {
         return 1;
       }
diff --git a/Tests/RunCMake/BuildDepends/RunCMakeTest.cmake b/Tests/RunCMake/BuildDepends/RunCMakeTest.cmake
index a6e08da..72faddb 100644
--- a/Tests/RunCMake/BuildDepends/RunCMakeTest.cmake
+++ b/Tests/RunCMake/BuildDepends/RunCMakeTest.cmake
@@ -155,8 +155,7 @@
   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)
diff --git a/Tests/RunCMake/CMakeLists.txt b/Tests/RunCMake/CMakeLists.txt
index be59a55..5f23c05 100644
--- a/Tests/RunCMake/CMakeLists.txt
+++ b/Tests/RunCMake/CMakeLists.txt
@@ -222,7 +222,6 @@
 
 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}
   )