summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Help/command/add_custom_command.rst21
-rw-r--r--Help/release/dev/makefile-depfile.rst5
-rw-r--r--Source/cmAddCustomCommandCommand.cxx6
-rw-r--r--Source/cmDependsCompiler.cxx133
-rw-r--r--Source/cmGlobalUnixMakefileGenerator3.h6
-rw-r--r--Source/cmLocalUnixMakefileGenerator3.cxx39
-rw-r--r--Source/cmMakefileTargetGenerator.cxx19
-rw-r--r--Source/cmMakefileUtilityTargetGenerator.cxx39
-rw-r--r--Source/cmcmd.cxx2
-rw-r--r--Tests/RunCMake/BuildDepends/CustomCommandDependencies-BadArgs-result.txt (renamed from Tests/RunCMake/Make/CustomCommandDepfile-ERROR-result.txt)0
-rw-r--r--Tests/RunCMake/BuildDepends/CustomCommandDependencies-BadArgs-stderr.txt4
-rw-r--r--Tests/RunCMake/BuildDepends/CustomCommandDependencies-BadArgs.cmake10
-rw-r--r--Tests/RunCMake/BuildDepends/CustomCommandDependencies.cmake73
-rw-r--r--Tests/RunCMake/BuildDepends/CustomCommandDependencies.step1.cmake3
-rw-r--r--Tests/RunCMake/BuildDepends/CustomCommandDependencies.step2.cmake3
-rw-r--r--Tests/RunCMake/BuildDepends/GenerateDepFile.cmake6
-rw-r--r--Tests/RunCMake/BuildDepends/RunCMakeTest.cmake5
-rw-r--r--Tests/RunCMake/Make/CustomCommandDepfile-ERROR-stderr.txt5
-rw-r--r--Tests/RunCMake/Make/CustomCommandDepfile-ERROR.cmake8
-rw-r--r--Tests/RunCMake/Make/RunCMakeTest.cmake1
20 files changed, 309 insertions, 79 deletions
diff --git a/Help/command/add_custom_command.rst b/Help/command/add_custom_command.rst
index 567af16..9a4efd1 100644
--- a/Help/command/add_custom_command.rst
+++ b/Help/command/add_custom_command.rst
@@ -201,6 +201,10 @@ The options are:
Note that the ``IMPLICIT_DEPENDS`` option is currently supported
only for Makefile generators and will be ignored by other generators.
+ .. note::
+
+ This option cannot be specified at the same time as ``DEPFILE`` option.
+
``JOB_POOL``
.. versionadded:: 3.15
@@ -263,15 +267,26 @@ The options are:
``DEPFILE``
.. versionadded:: 3.7
- Specify a ``.d`` depfile for the :generator:`Ninja` generator.
+ Specify a ``.d`` depfile for the :generator:`Ninja` generator and
+ :ref:`Makefile Generators`.
A ``.d`` file holds dependencies usually emitted by the custom
command itself.
- Using ``DEPFILE`` with other generators than Ninja is an error.
+ Using ``DEPFILE`` with other generators than :generator:`Ninja` or
+ :ref:`Makefile Generators` is an error.
+
+ .. versionadded:: 3.20
+ Added the support of :ref:`Makefile Generators`.
If the ``DEPFILE`` argument is relative, it should be relative to
:variable:`CMAKE_CURRENT_BINARY_DIR`, and any relative paths inside the
``DEPFILE`` should also be relative to :variable:`CMAKE_CURRENT_BINARY_DIR`
- (see policy :policy:`CMP0116`.)
+ (see policy :policy:`CMP0116`. This policy is always ``NEW`` for
+ :ref:`Makefile Generators`).
+
+ .. note::
+
+ For :ref:`Makefile Generators`, this option cannot be specified at the
+ same time as ``IMPLICIT_DEPENDS`` option.
Examples: Generating Files
^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/Help/release/dev/makefile-depfile.rst b/Help/release/dev/makefile-depfile.rst
new file mode 100644
index 0000000..4a3e5fb
--- /dev/null
+++ b/Help/release/dev/makefile-depfile.rst
@@ -0,0 +1,5 @@
+makefile-depfile
+----------------
+
+* The :command:`add_custom_command` command gained ``DEPFILE`` support on
+ :ref:`Makefile Generators`.
diff --git a/Source/cmAddCustomCommandCommand.cxx b/Source/cmAddCustomCommandCommand.cxx
index ccd7255..ff2cc3e 100644
--- a/Source/cmAddCustomCommandCommand.cxx
+++ b/Source/cmAddCustomCommandCommand.cxx
@@ -296,6 +296,12 @@ bool cmAddCustomCommandCommand(std::vector<std::string> const& args,
status.SetError("given APPEND option with no OUTPUT.");
return false;
}
+ if (!implicit_depends.empty() && !depfile.empty() &&
+ mf.GetGlobalGenerator()->GetName() != "Ninja") {
+ // Makefiles generators does not support both at the same time
+ status.SetError("IMPLICIT_DEPENDS and DEPFILE can not both be specified.");
+ return false;
+ }
// Check for an append request.
if (append) {
diff --git a/Source/cmDependsCompiler.cxx b/Source/cmDependsCompiler.cxx
index f6e5af8..beb080f 100644
--- a/Source/cmDependsCompiler.cxx
+++ b/Source/cmDependsCompiler.cxx
@@ -19,6 +19,7 @@
#include "cmFileTime.h"
#include "cmGccDepfileReader.h"
+#include "cmGccDepfileReaderTypes.h"
#include "cmGlobalUnixMakefileGenerator3.h"
#include "cmLocalUnixMakefileGenerator3.h"
#include "cmStringAlgorithms.h"
@@ -86,7 +87,7 @@ bool cmDependsCompiler::CheckDependencies(
if (!forceReadDeps) {
depFileTime.Load(depFile);
}
- if (forceReadDeps || depFileTime.Newer(internalDepFileTime)) {
+ if (forceReadDeps || depFileTime.Compare(internalDepFileTime) >= 0) {
status = false;
if (this->Verbose) {
cmSystemTools::Stdout(cmStrCat("Dependencies file \"", depFile,
@@ -95,59 +96,92 @@ bool cmDependsCompiler::CheckDependencies(
}
std::vector<std::string> depends;
- if (format == "msvc"_s) {
- cmsys::ifstream fin(depFile.c_str());
- if (!fin) {
- continue;
+ if (format == "custom"_s) {
+ std::string prefix;
+ if (this->LocalGenerator->GetCurrentBinaryDirectory() !=
+ this->LocalGenerator->GetBinaryDirectory()) {
+ prefix =
+ cmStrCat(this->LocalGenerator->MaybeConvertToRelativePath(
+ this->LocalGenerator->GetBinaryDirectory(),
+ this->LocalGenerator->GetCurrentBinaryDirectory()),
+ '/');
}
- std::string line;
- if (!isValidPath) {
- // insert source as first dependency
- depends.push_back(source);
- }
- while (cmSystemTools::GetLineFromStream(fin, line)) {
- depends.emplace_back(std::move(line));
- }
- } else {
- auto deps = cmReadGccDepfile(depFile.c_str());
+ auto deps = cmReadGccDepfile(depFile.c_str(), prefix);
if (!deps) {
continue;
}
- // dependencies generated by the compiler contains only one target
- depends = std::move(deps->front().paths);
- if (depends.empty()) {
- // unexpectedly empty, ignore it and continue
- continue;
- }
-
- // depending of the effective format of the dependencies file generated
- // by the compiler, the target can be wrongly identified as a
- // dependency so remove it from the list
- if (depends.front() == target) {
- depends.erase(depends.begin());
+ for (auto& entry : *deps) {
+ depends = std::move(entry.paths);
+ if (isValidPath) {
+ cm::erase_if(depends, isValidPath);
+ }
+ // copy depends for each target, except first one, which can be
+ // moved
+ for (auto index = entry.rules.size() - 1; index > 0; --index) {
+ dependencies[entry.rules[index]] = depends;
+ }
+ dependencies[entry.rules.front()] = std::move(depends);
}
+ } else {
+ if (format == "msvc"_s) {
+ cmsys::ifstream fin(depFile.c_str());
+ if (!fin) {
+ continue;
+ }
- // ensure source file is the first dependency
- if (depends.front() != source) {
- cm::erase(depends, source);
+ std::string line;
if (!isValidPath) {
- depends.insert(depends.begin(), source);
+ // insert source as first dependency
+ depends.push_back(source);
+ }
+ while (cmSystemTools::GetLineFromStream(fin, line)) {
+ depends.emplace_back(std::move(line));
+ }
+ } else if (format == "gcc"_s) {
+ auto deps = cmReadGccDepfile(depFile.c_str());
+ if (!deps) {
+ continue;
}
- } else if (isValidPath) {
- // remove first dependency because it must not be filtered out
- depends.erase(depends.begin());
+
+ // dependencies generated by the compiler contains only one target
+ depends = std::move(deps->front().paths);
+ if (depends.empty()) {
+ // unexpectedly empty, ignore it and continue
+ continue;
+ }
+
+ // depending of the effective format of the dependencies file
+ // generated by the compiler, the target can be wrongly identified
+ // as a dependency so remove it from the list
+ if (depends.front() == target) {
+ depends.erase(depends.begin());
+ }
+
+ // ensure source file is the first dependency
+ if (depends.front() != source) {
+ cm::erase(depends, source);
+ if (!isValidPath) {
+ depends.insert(depends.begin(), source);
+ }
+ } else if (isValidPath) {
+ // remove first dependency because it must not be filtered out
+ depends.erase(depends.begin());
+ }
+ } else {
+ // unknown format, ignore it
+ continue;
}
- }
- if (isValidPath) {
- cm::erase_if(depends, isValidPath);
- // insert source as first dependency
- depends.insert(depends.begin(), source);
- }
+ if (isValidPath) {
+ cm::erase_if(depends, isValidPath);
+ // insert source as first dependency
+ depends.insert(depends.begin(), source);
+ }
- dependencies[target] = std::move(depends);
+ dependencies[target] = std::move(depends);
+ }
}
}
@@ -168,6 +202,8 @@ void cmDependsCompiler::WriteDependencies(
// external dependencies file
for (auto& node : makeDependencies) {
+ auto target = LocalGenerator->ConvertToMakefilePath(
+ this->LocalGenerator->MaybeConvertToRelativePath(binDir, node.first));
auto& deps = node.second;
std::transform(
deps.cbegin(), deps.cend(), deps.begin(),
@@ -176,13 +212,16 @@ void cmDependsCompiler::WriteDependencies(
this->LocalGenerator->MaybeConvertToRelativePath(binDir, dep));
});
- makeDepends << this->LocalGenerator->ConvertToMakefilePath(node.first)
- << ": " << deps.front();
- // first dependency is the source, remove it because should not be declared
- // as phony target
- deps.erase(deps.begin());
+ bool first_dep = true;
+ makeDepends << target << ": ";
for (const auto& dep : deps) {
- makeDepends << ' ' << lineContinue << " " << dep;
+ if (first_dep) {
+ first_dep = false;
+ makeDepends << dep;
+ } else {
+ makeDepends << ' ' << lineContinue << " " << dep;
+ }
+
phonyTargets.emplace(dep.data(), dep.length());
}
makeDepends << std::endl << std::endl;
diff --git a/Source/cmGlobalUnixMakefileGenerator3.h b/Source/cmGlobalUnixMakefileGenerator3.h
index 6459771..09679a7 100644
--- a/Source/cmGlobalUnixMakefileGenerator3.h
+++ b/Source/cmGlobalUnixMakefileGenerator3.h
@@ -93,6 +93,12 @@ public:
*/
static bool SupportsPlatform() { return false; }
+ /**
+ * Utilized to determine if this generator
+ * supports DEPFILE option.
+ */
+ bool SupportsCustomCommandDepfile() const override { return true; }
+
/** Get the documentation entry for this generator. */
static void GetDocumentation(cmDocumentationEntry& entry);
diff --git a/Source/cmLocalUnixMakefileGenerator3.cxx b/Source/cmLocalUnixMakefileGenerator3.cxx
index 08cefb7..358df9d 100644
--- a/Source/cmLocalUnixMakefileGenerator3.cxx
+++ b/Source/cmLocalUnixMakefileGenerator3.cxx
@@ -13,6 +13,7 @@
#include <cm/string_view>
#include <cm/vector>
#include <cmext/algorithm>
+#include <cmext/string_view>
#include "cmsys/FStream.hxx"
#include "cmsys/Terminal.h"
@@ -1435,7 +1436,7 @@ bool cmLocalUnixMakefileGenerator3::UpdateDependencies(
this->Makefile->GetSafeDefinition("CMAKE_DEPENDS_DEPENDENCY_FILES");
if (!depends.empty()) {
// dependencies are managed by compiler
- auto depFiles = cmExpandedList(depends);
+ auto depFiles = cmExpandedList(depends, true);
std::string const internalDepFile =
targetDir + "/compiler_depend.internal";
std::string const depFile = targetDir + "/compiler_depend.make";
@@ -1998,18 +1999,32 @@ void cmLocalUnixMakefileGenerator3::WriteDependLanguageInfo(
cmakefileStream << "\n# The set of dependency files which are needed:\n";
cmakefileStream << "set(CMAKE_DEPENDS_DEPENDENCY_FILES\n";
for (auto const& compilerLang : compilerLangs) {
- auto depFormat = this->Makefile->GetSafeDefinition(
- cmStrCat("CMAKE_", compilerLang.first, "_DEPFILE_FORMAT"));
auto const& compilerPairs = compilerLang.second;
- for (auto const& compilerPair : compilerPairs) {
- for (auto const& src : compilerPair.second) {
- cmakefileStream << " \"" << src << "\" \""
- << this->MaybeConvertToRelativePath(
- this->GetBinaryDirectory(), compilerPair.first)
- << "\" \"" << depFormat << "\" \""
- << this->MaybeConvertToRelativePath(
- this->GetBinaryDirectory(), compilerPair.first)
- << ".d\"\n";
+ if (compilerLang.first == "CUSTOM"_s) {
+ for (auto const& compilerPair : compilerPairs) {
+ for (auto const& src : compilerPair.second) {
+ cmakefileStream << R"( "" ")"
+ << this->MaybeConvertToRelativePath(
+ this->GetBinaryDirectory(), compilerPair.first)
+ << R"(" "custom" ")"
+ << this->MaybeConvertToRelativePath(
+ this->GetBinaryDirectory(), src)
+ << "\"\n";
+ }
+ }
+ } else {
+ auto depFormat = this->Makefile->GetSafeDefinition(
+ cmStrCat("CMAKE_", compilerLang.first, "_DEPFILE_FORMAT"));
+ for (auto const& compilerPair : compilerPairs) {
+ for (auto const& src : compilerPair.second) {
+ cmakefileStream << " \"" << src << "\" \""
+ << this->MaybeConvertToRelativePath(
+ this->GetBinaryDirectory(), compilerPair.first)
+ << "\" \"" << depFormat << "\" \""
+ << this->MaybeConvertToRelativePath(
+ this->GetBinaryDirectory(), compilerPair.first)
+ << ".d\"\n";
+ }
}
}
}
diff --git a/Source/cmMakefileTargetGenerator.cxx b/Source/cmMakefileTargetGenerator.cxx
index 1f23424..70a0393 100644
--- a/Source/cmMakefileTargetGenerator.cxx
+++ b/Source/cmMakefileTargetGenerator.cxx
@@ -1617,6 +1617,16 @@ void cmMakefileTargetGenerator::GenerateCustomRuleFile(
std::vector<std::string> depends;
this->LocalGenerator->AppendCustomDepend(depends, ccg);
+ if (!ccg.GetCC().GetDepfile().empty()) {
+ // Add dependency over timestamp file for dependencies management
+ auto dependTimestamp = cmSystemTools::ConvertToOutputPath(
+ this->LocalGenerator->MaybeConvertToRelativePath(
+ this->LocalGenerator->GetBinaryDirectory(),
+ cmStrCat(this->TargetBuildDirectoryFull, "/compiler_depend.ts")));
+
+ depends.push_back(dependTimestamp);
+ }
+
// Write the rule.
const std::vector<std::string>& outputs = ccg.GetOutputs();
bool symbolic = this->WriteMakeRule(*this->BuildFileStream, nullptr, outputs,
@@ -1653,6 +1663,15 @@ void cmMakefileTargetGenerator::GenerateCustomRuleFile(
objFullPath, srcFullPath);
}
+ // Setup implicit depend for depfile if any
+ if (!ccg.GetCC().GetDepfile().empty()) {
+ std::string objFullPath = cmSystemTools::CollapseFullPath(
+ outputs[0], this->LocalGenerator->GetCurrentBinaryDirectory());
+ this->LocalGenerator->AddImplicitDepends(
+ this->GeneratorTarget, "CUSTOM", objFullPath, ccg.GetFullDepfile(),
+ cmDependencyScannerKind::Compiler);
+ }
+
this->CustomCommandOutputs.insert(outputs.begin(), outputs.end());
}
diff --git a/Source/cmMakefileUtilityTargetGenerator.cxx b/Source/cmMakefileUtilityTargetGenerator.cxx
index 6c18e48..a885b17 100644
--- a/Source/cmMakefileUtilityTargetGenerator.cxx
+++ b/Source/cmMakefileUtilityTargetGenerator.cxx
@@ -15,6 +15,7 @@
#include "cmLocalUnixMakefileGenerator3.h"
#include "cmMakefile.h"
#include "cmOSXBundleGenerator.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
cmMakefileUtilityTargetGenerator::cmMakefileUtilityTargetGenerator(
@@ -36,10 +37,42 @@ void cmMakefileUtilityTargetGenerator::WriteRuleFiles()
*this->BuildFileStream << "# Utility rule file for "
<< this->GeneratorTarget->GetName() << ".\n\n";
+ const char* root = (this->Makefile->IsOn("CMAKE_MAKE_INCLUDE_FROM_ROOT")
+ ? "$(CMAKE_BINARY_DIR)/"
+ : "");
+
+ // Include the dependencies for the target.
+ std::string dependFile =
+ cmStrCat(this->TargetBuildDirectoryFull, "/compiler_depend.make");
+ *this->BuildFileStream
+ << "# Include any custom commands dependencies for this target.\n"
+ << this->GlobalGenerator->IncludeDirective << " " << root
+ << cmSystemTools::ConvertToOutputPath(
+ this->LocalGenerator->MaybeConvertToRelativePath(
+ this->LocalGenerator->GetBinaryDirectory(), dependFile))
+ << "\n\n";
+ if (!cmSystemTools::FileExists(dependFile)) {
+ // Write an empty dependency file.
+ cmGeneratedFileStream depFileStream(
+ dependFile, false, this->GlobalGenerator->GetMakefileEncoding());
+ depFileStream << "# Empty custom commands generated dependencies file for "
+ << this->GeneratorTarget->GetName() << ".\n"
+ << "# This may be replaced when dependencies are built.\n";
+ }
+
+ std::string dependTimestamp =
+ cmStrCat(this->TargetBuildDirectoryFull, "/compiler_depend.ts");
+ if (!cmSystemTools::FileExists(dependTimestamp)) {
+ // Write a dependency timestamp file.
+ cmGeneratedFileStream depFileStream(
+ dependTimestamp, false, this->GlobalGenerator->GetMakefileEncoding());
+ depFileStream << "# CMAKE generated file: DO NOT EDIT!\n"
+ << "# Timestamp file for custom commands dependencies "
+ "management for "
+ << this->GeneratorTarget->GetName() << ".\n";
+ }
+
if (!this->NoRuleMessages) {
- const char* root = (this->Makefile->IsOn("CMAKE_MAKE_INCLUDE_FROM_ROOT")
- ? "$(CMAKE_BINARY_DIR)/"
- : "");
// Include the progress variables for the target.
*this->BuildFileStream
<< "# Include the progress variables for this target.\n"
diff --git a/Source/cmcmd.cxx b/Source/cmcmd.cxx
index b8464f2..73fbfb6 100644
--- a/Source/cmcmd.cxx
+++ b/Source/cmcmd.cxx
@@ -1272,6 +1272,8 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string> const& args,
cmStateSnapshot snapshot = cm.GetCurrentSnapshot();
snapshot.GetDirectory().SetCurrentBinary(startOutDir);
snapshot.GetDirectory().SetCurrentSource(startDir);
+ snapshot.GetDirectory().SetRelativePathTopSource(homeDir.c_str());
+ snapshot.GetDirectory().SetRelativePathTopBinary(homeOutDir.c_str());
cmMakefile mf(cm.GetGlobalGenerator(), snapshot);
auto lgd = cm.GetGlobalGenerator()->CreateLocalGenerator(&mf);
diff --git a/Tests/RunCMake/Make/CustomCommandDepfile-ERROR-result.txt b/Tests/RunCMake/BuildDepends/CustomCommandDependencies-BadArgs-result.txt
index d00491f..d00491f 100644
--- a/Tests/RunCMake/Make/CustomCommandDepfile-ERROR-result.txt
+++ b/Tests/RunCMake/BuildDepends/CustomCommandDependencies-BadArgs-result.txt
diff --git a/Tests/RunCMake/BuildDepends/CustomCommandDependencies-BadArgs-stderr.txt b/Tests/RunCMake/BuildDepends/CustomCommandDependencies-BadArgs-stderr.txt
new file mode 100644
index 0000000..cddea3c
--- /dev/null
+++ b/Tests/RunCMake/BuildDepends/CustomCommandDependencies-BadArgs-stderr.txt
@@ -0,0 +1,4 @@
+CMake Error at CustomCommandDependencies-BadArgs.cmake:[0-9]+ \(add_custom_command\):
+ add_custom_command IMPLICIT_DEPENDS and DEPFILE can not both be specified.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/BuildDepends/CustomCommandDependencies-BadArgs.cmake b/Tests/RunCMake/BuildDepends/CustomCommandDependencies-BadArgs.cmake
new file mode 100644
index 0000000..91ee338
--- /dev/null
+++ b/Tests/RunCMake/BuildDepends/CustomCommandDependencies-BadArgs.cmake
@@ -0,0 +1,10 @@
+enable_language(C)
+
+add_custom_command(OUTPUT main.c
+ DEPFILE main.c.d
+ IMPLICIT_DEPENDS C main.c.in
+ COMMAND "${CMAKE_COMMAND}" -DINFILE=main.c.in -DOUTFILE=main.c -DDEPFILE=main.c.d
+ -P "${CMAKE_CURRENT_SOURCE_DIR}/GenerateDepFile.cmake"
+ WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}")
+
+add_custom_target(mainc ALL DEPENDS main.c)
diff --git a/Tests/RunCMake/BuildDepends/CustomCommandDependencies.cmake b/Tests/RunCMake/BuildDepends/CustomCommandDependencies.cmake
new file mode 100644
index 0000000..28bbf11
--- /dev/null
+++ b/Tests/RunCMake/BuildDepends/CustomCommandDependencies.cmake
@@ -0,0 +1,73 @@
+enable_language(C)
+
+add_custom_command(OUTPUT main.c
+ DEPFILE main.c.d
+ COMMAND "${CMAKE_COMMAND}" -DINFILE=main.c.in -DOUTFILE=main.c -DDEPFILE=main.c.d
+ -P "${CMAKE_CURRENT_SOURCE_DIR}/GenerateDepFile.cmake"
+ WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}")
+
+add_custom_target(mainc ALL DEPENDS main.c)
+
+add_executable(main ${CMAKE_CURRENT_BINARY_DIR}/main.c)
+
+file(GENERATE OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/check-$<LOWER_CASE:$<CONFIG>>.cmake CONTENT "
+cmake_minimum_required(VERSION 3.19)
+set(check_pairs
+ \"$<TARGET_FILE:main>|${CMAKE_CURRENT_BINARY_DIR}/main.c.in\"
+ \"$<TARGET_FILE:main>|${CMAKE_CURRENT_BINARY_DIR}/main.c\"
+ )
+set(check_exes
+ \"$<TARGET_FILE:main>\"
+ )
+
+if (check_step EQUAL 2)
+ include(\"${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/Makefile.cmake\")
+ if (NOT CMAKE_DEPEND_INFO_FILES)
+ set(RunCMake_TEST_FAILED \"Variable CMAKE_DEPEND_INFO_FILES not found.\")
+ else()
+ foreach(DEPEND_INFO_FILE IN LISTS CMAKE_DEPEND_INFO_FILES)
+ include(\"${CMAKE_CURRENT_BINARY_DIR}/\${DEPEND_INFO_FILE}\")
+ if (NOT CMAKE_DEPENDS_DEPENDENCY_FILES)
+ set(RunCMake_TEST_FAILED \"Variable CMAKE_DEPENDS_DEPENDENCY_FILES not found.\")
+ else()
+ list(LENGTH CMAKE_DEPENDS_DEPENDENCY_FILES DEPENDENCY_FILES_SIZE)
+ math(EXPR STOP_INDEX \"\${DEPENDENCY_FILES_SIZE} - 1\")
+ foreach(INDEX RANGE 0 \${STOP_INDEX} 4)
+ math(EXPR OBJECT_INDEX \"\${INDEX} + 1\")
+ math(EXPR FORMAT_INDEX \"\${INDEX} + 2\")
+ math(EXPR DEP_INDEX \"\${INDEX} + 3\")
+ list(GET CMAKE_DEPENDS_DEPENDENCY_FILES \${OBJECT_INDEX} OBJECT_FILE)
+ list(GET CMAKE_DEPENDS_DEPENDENCY_FILES \${FORMAT_INDEX} DEP_FORMAT)
+ list(GET CMAKE_DEPENDS_DEPENDENCY_FILES \${DEP_INDEX} DEP_FILE)
+ if (NOT EXISTS \"${CMAKE_CURRENT_BINARY_DIR}/\${DEP_FILE}\")
+ set(RunCMake_TEST_FAILED \"File \${DEP_FILE} not found.\")
+ else()
+ cmake_path(APPEND TARGET_DEP_FILE \"${CMAKE_CURRENT_BINARY_DIR}\" \"\${DEPEND_INFO_FILE}\")
+ cmake_path(REPLACE_FILENAME TARGET_DEP_FILE \"compiler_depend.make\")
+ file(READ \"\${TARGET_DEP_FILE}\" DEPENDS_CONTENT)
+ if (WIN32)
+ string (REPLACE \"\\\\\" \"/\" DEPENDS_CONTENT \"\${DEPENDS_CONTENT}\")
+ string (TOLOWER \"\${DEPENDS_CONTENT}\" DEPENDS_CONTENT)
+ string (TOLOWER \"\${OBJECT_FILE}\" OBJECT_FILE)
+ else()
+ string(REPLACE \"\\\\ \" \" \" DEPENDS_CONTENT \"\${DEPENDS_CONTENT}\")
+ endif()
+ if(DEPEND_INFO_FILE MATCHES \"main\\\\.dir\")
+ if (DEP_FORMAT STREQUAL \"gcc\" AND NOT DEPENDS_CONTENT MATCHES \"\${OBJECT_FILE} *:.+main.c\")
+ set(RunCMake_TEST_FAILED \"Dependency file '\${TARGET_DEP_FILE}' badly generated:\\n\${DEPENDS_CONTENT}\")
+ endif()
+ if (DEP_FORMAT STREQUAL \"custom\" AND NOT DEPENDS_CONTENT MATCHES \"\${OBJECT_FILE} *:.+main.c.in\")
+ set(RunCMake_TEST_FAILED \"Dependency file '\${TARGET_DEP_FILE}' badly generated:\\n\${DEPENDS_CONTENT}\")
+ endif()
+ else()
+ if (NOT DEPENDS_CONTENT MATCHES \"\${OBJECT_FILE} *:.+main.c.in\")
+ set(RunCMake_TEST_FAILED \"Dependency file '\${TARGET_DEP_FILE}' badly generated:\\n\${DEPENDS_CONTENT}\")
+ endif()
+ endif()
+ endif()
+ endforeach()
+ endif()
+ endforeach()
+ endif()
+endif()
+")
diff --git a/Tests/RunCMake/BuildDepends/CustomCommandDependencies.step1.cmake b/Tests/RunCMake/BuildDepends/CustomCommandDependencies.step1.cmake
new file mode 100644
index 0000000..87576eb
--- /dev/null
+++ b/Tests/RunCMake/BuildDepends/CustomCommandDependencies.step1.cmake
@@ -0,0 +1,3 @@
+file(WRITE "${RunCMake_TEST_BINARY_DIR}/main.c.in" [[
+int main(void) { return 1; }
+]])
diff --git a/Tests/RunCMake/BuildDepends/CustomCommandDependencies.step2.cmake b/Tests/RunCMake/BuildDepends/CustomCommandDependencies.step2.cmake
new file mode 100644
index 0000000..69b21b8
--- /dev/null
+++ b/Tests/RunCMake/BuildDepends/CustomCommandDependencies.step2.cmake
@@ -0,0 +1,3 @@
+file(WRITE "${RunCMake_TEST_BINARY_DIR}/main.c.in" [[
+int main(void) { return 2; }
+]])
diff --git a/Tests/RunCMake/BuildDepends/GenerateDepFile.cmake b/Tests/RunCMake/BuildDepends/GenerateDepFile.cmake
new file mode 100644
index 0000000..f7d0f13
--- /dev/null
+++ b/Tests/RunCMake/BuildDepends/GenerateDepFile.cmake
@@ -0,0 +1,6 @@
+file(READ "${INFILE}" INCONTENT)
+file(WRITE "${OUTFILE}" "${INCONTENT}")
+
+string(REPLACE [[ ]] [[\ ]] OUTFILE "${OUTFILE}")
+string(REPLACE [[ ]] [[\ ]] INFILE "${INFILE}")
+file(WRITE "${DEPFILE}" "${OUTFILE}: ${INFILE}\n")
diff --git a/Tests/RunCMake/BuildDepends/RunCMakeTest.cmake b/Tests/RunCMake/BuildDepends/RunCMakeTest.cmake
index 23e222a..f40cde6 100644
--- a/Tests/RunCMake/BuildDepends/RunCMakeTest.cmake
+++ b/Tests/RunCMake/BuildDepends/RunCMakeTest.cmake
@@ -122,4 +122,9 @@ if ((RunCMake_GENERATOR STREQUAL "Unix Makefiles"
AND MSVC_VERSION GREATER 1300
AND CMAKE_C_COMPILER_ID STREQUAL "MSVC"))
run_BuildDepends(CompilerDependencies)
+ run_BuildDepends(CustomCommandDependencies)
+endif()
+
+if (RunCMake_GENERATOR MATCHES "Makefiles")
+ run_cmake(CustomCommandDependencies-BadArgs)
endif()
diff --git a/Tests/RunCMake/Make/CustomCommandDepfile-ERROR-stderr.txt b/Tests/RunCMake/Make/CustomCommandDepfile-ERROR-stderr.txt
deleted file mode 100644
index 74d62a4..0000000
--- a/Tests/RunCMake/Make/CustomCommandDepfile-ERROR-stderr.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-^CMake Error at CustomCommandDepfile-ERROR.cmake:1 \(add_custom_command\):
- add_custom_command Option DEPFILE not supported by [^
-]+
-Call Stack \(most recent call first\):
- CMakeLists.txt:3 \(include\)$
diff --git a/Tests/RunCMake/Make/CustomCommandDepfile-ERROR.cmake b/Tests/RunCMake/Make/CustomCommandDepfile-ERROR.cmake
deleted file mode 100644
index bad7955..0000000
--- a/Tests/RunCMake/Make/CustomCommandDepfile-ERROR.cmake
+++ /dev/null
@@ -1,8 +0,0 @@
-add_custom_command(
- OUTPUT hello.copy.c
- COMMAND "${CMAKE_COMMAND}" -E copy
- "${CMAKE_CURRENT_SOURCE_DIR}/hello.c"
- hello.copy.c
- WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}"
- DEPFILE "test.d"
- )
diff --git a/Tests/RunCMake/Make/RunCMakeTest.cmake b/Tests/RunCMake/Make/RunCMakeTest.cmake
index b66e30e..c7717ec 100644
--- a/Tests/RunCMake/Make/RunCMakeTest.cmake
+++ b/Tests/RunCMake/Make/RunCMakeTest.cmake
@@ -39,7 +39,6 @@ function(run_VerboseBuild)
endfunction()
run_VerboseBuild()
-run_cmake(CustomCommandDepfile-ERROR)
run_cmake(IncludeRegexSubdir)
function(run_MakefileConflict)