summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBrad King <brad.king@kitware.com>2023-11-07 14:07:36 (GMT)
committerKitware Robot <kwrobot@kitware.com>2023-11-07 14:07:46 (GMT)
commit92cc1f3b62c149326cc535220f6233357ee5d749 (patch)
tree7edb4c4b54897b1f77ef91c81d4dec591acfb9fa
parent4b92515182ce642a6f8f587d5c35f11f9e6a291c (diff)
parentbb7a0497ef41540c75183acf4ee740656aa61dd9 (diff)
downloadCMake-92cc1f3b62c149326cc535220f6233357ee5d749.zip
CMake-92cc1f3b62c149326cc535220f6233357ee5d749.tar.gz
CMake-92cc1f3b62c149326cc535220f6233357ee5d749.tar.bz2
Merge topic 'Ninja-use-depslog'
bb7a0497ef cmTransformDepfile: warn when a depfile is not written to c22c473bde Tests/Ninja*/CustomCommandDepfile: check that deps are in the database b0177003e1 cmGlobalNinjaGenerator: tell `ninja` to actually read the depfile 45eff9145e cmAddCustomCommandCommand: use `cmStrCat` c6445c615b Tests/RunCMake/Ninja: fix subdir prefix check Acked-by: Kitware Robot <kwrobot@kitware.com> Acked-by: buildbot <buildbot@kitware.com> Merge-request: !8911
-rw-r--r--Help/command/add_custom_command.rst5
-rw-r--r--Source/cmAddCustomCommandCommand.cxx4
-rw-r--r--Source/cmGlobalNinjaGenerator.cxx17
-rw-r--r--Source/cmTransformDepfile.cxx7
-rw-r--r--Tests/RunCMake/Ninja/CheckNoPrefixSubDirScript.cmake2
-rw-r--r--Tests/RunCMake/Ninja/CustomCommandDepfile-check.cmake35
-rw-r--r--Tests/RunCMake/Ninja/CustomCommandDepfileAsByproduct-check.cmake47
-rw-r--r--Tests/RunCMake/Ninja/CustomCommandDepfileAsByproduct.cmake24
-rw-r--r--Tests/RunCMake/Ninja/CustomCommandDepfileAsOutput-check.cmake47
-rw-r--r--Tests/RunCMake/Ninja/CustomCommandDepfileAsOutput.cmake24
-rw-r--r--Tests/RunCMake/Ninja/RunCMakeTest.cmake2
-rw-r--r--Tests/RunCMake/NinjaMultiConfig/CustomCommandDepfile-check.cmake35
-rw-r--r--Tests/RunCMake/NinjaMultiConfig/CustomCommandDepfileAsByproduct-check.cmake47
-rw-r--r--Tests/RunCMake/NinjaMultiConfig/CustomCommandDepfileAsByproduct.cmake22
-rw-r--r--Tests/RunCMake/NinjaMultiConfig/CustomCommandDepfileAsOutput-check.cmake47
-rw-r--r--Tests/RunCMake/NinjaMultiConfig/CustomCommandDepfileAsOutput.cmake22
-rw-r--r--Tests/RunCMake/NinjaMultiConfig/RunCMakeTest.cmake2
-rw-r--r--Tests/RunCMake/TransformDepfile/noexist-gcc-stderr.txt4
18 files changed, 389 insertions, 4 deletions
diff --git a/Help/command/add_custom_command.rst b/Help/command/add_custom_command.rst
index 5fe4326..2bb1390 100644
--- a/Help/command/add_custom_command.rst
+++ b/Help/command/add_custom_command.rst
@@ -373,6 +373,11 @@ The options are:
:manual:`generator expressions <cmake-generator-expressions(7)>` was also
added.
+ .. versionadded:: 3.29
+ The :ref:`Ninja Generators` will now incorporate the dependencies into its
+ "deps log" database if the file is not listed in ``OUTPUTS`` or
+ ``BYPRODUCTS``.
+
Using ``DEPFILE`` with generators other than those listed above is an error.
If the ``DEPFILE`` argument is relative, it should be relative to
diff --git a/Source/cmAddCustomCommandCommand.cxx b/Source/cmAddCustomCommandCommand.cxx
index b1589ff..ea97287 100644
--- a/Source/cmAddCustomCommandCommand.cxx
+++ b/Source/cmAddCustomCommandCommand.cxx
@@ -189,8 +189,8 @@ bool cmAddCustomCommandCommand(std::vector<std::string> const& args,
} else if (copy == keyDEPFILE) {
doing = doing_depfile;
if (!mf.GetGlobalGenerator()->SupportsCustomCommandDepfile()) {
- status.SetError("Option DEPFILE not supported by " +
- mf.GetGlobalGenerator()->GetName());
+ status.SetError(cmStrCat("Option DEPFILE not supported by ",
+ mf.GetGlobalGenerator()->GetName()));
return false;
}
} else if (copy == keyJOB_POOL) {
diff --git a/Source/cmGlobalNinjaGenerator.cxx b/Source/cmGlobalNinjaGenerator.cxx
index fb5c5c6..9fac513 100644
--- a/Source/cmGlobalNinjaGenerator.cxx
+++ b/Source/cmGlobalNinjaGenerator.cxx
@@ -378,6 +378,15 @@ void cmGlobalNinjaGenerator::WriteCustomCommandBuild(
}
{
+ std::string ninjaDepfilePath;
+ bool depfileIsOutput = false;
+ if (!depfile.empty()) {
+ ninjaDepfilePath = this->ConvertToNinjaPath(depfile);
+ depfileIsOutput =
+ std::find(outputs.ExplicitOuts.begin(), outputs.ExplicitOuts.end(),
+ ninjaDepfilePath) != outputs.ExplicitOuts.end();
+ }
+
cmNinjaBuild build("CUSTOM_COMMAND");
build.Comment = comment;
build.Outputs = std::move(outputs.ExplicitOuts);
@@ -405,7 +414,13 @@ void cmGlobalNinjaGenerator::WriteCustomCommandBuild(
vars["pool"] = job_pool;
}
if (!depfile.empty()) {
- vars["depfile"] = depfile;
+ vars["depfile"] = ninjaDepfilePath;
+ // Add the depfile to the `.ninja_deps` database. Since this (generally)
+ // removes the file, it cannot be declared as an output or byproduct of
+ // the command.
+ if (!depfileIsOutput) {
+ vars["deps"] = "gcc";
+ }
}
if (config.empty()) {
this->WriteBuild(*this->GetCommonFileStream(), build);
diff --git a/Source/cmTransformDepfile.cxx b/Source/cmTransformDepfile.cxx
index 914172b..ffc4de9 100644
--- a/Source/cmTransformDepfile.cxx
+++ b/Source/cmTransformDepfile.cxx
@@ -16,6 +16,9 @@
#include "cmGccDepfileReaderTypes.h"
#include "cmGlobalGenerator.h"
#include "cmLocalGenerator.h"
+#include "cmMakefile.h"
+#include "cmMessageType.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
namespace {
@@ -121,6 +124,10 @@ bool cmTransformDepfile(cmDepfileFormat format, const cmLocalGenerator& lg,
return false;
}
content = *std::move(result);
+ } else {
+ lg.GetMakefile()->IssueMessage(
+ MessageType::WARNING,
+ cmStrCat("Expected depfile does not exist.\n ", infile));
}
cmSystemTools::MakeDirectory(cmSystemTools::GetFilenamePath(outfile));
diff --git a/Tests/RunCMake/Ninja/CheckNoPrefixSubDirScript.cmake b/Tests/RunCMake/Ninja/CheckNoPrefixSubDirScript.cmake
index 5a03fcb..09fd7e9 100644
--- a/Tests/RunCMake/Ninja/CheckNoPrefixSubDirScript.cmake
+++ b/Tests/RunCMake/Ninja/CheckNoPrefixSubDirScript.cmake
@@ -1,6 +1,6 @@
# Check that the prefix sub-directory is not repeated.
-if(EXISTS "${CUR_BIN_DIR}/${NINJA_OUTPUT_PATH_PREFIX}")
+if(NINJA_OUTPUT_PATH_PREFIX AND EXISTS "${CUR_BIN_DIR}/${NINJA_OUTPUT_PATH_PREFIX}")
message(FATAL_ERROR
"no sub directory named after the CMAKE_NINJA_OUTPUT_PATH_PREFIX "
"should be in the binary directory."
diff --git a/Tests/RunCMake/Ninja/CustomCommandDepfile-check.cmake b/Tests/RunCMake/Ninja/CustomCommandDepfile-check.cmake
index edde0c0..3016816 100644
--- a/Tests/RunCMake/Ninja/CustomCommandDepfile-check.cmake
+++ b/Tests/RunCMake/Ninja/CustomCommandDepfile-check.cmake
@@ -10,3 +10,38 @@ if(NOT "${build_file}" MATCHES "depfile = test_Debug\\.d")
string(CONCAT no_test_Debug_d "\nLog file:\n ${log}\n" "does not have expected line: depfile = test_Debug.d")
list(APPEND RunCMake_TEST_FAILED "${no_test_Debug_d}")
endif()
+
+function(_run_ninja dir)
+ execute_process(
+ COMMAND "${RunCMake_MAKE_PROGRAM}" ${ARGN}
+ WORKING_DIRECTORY "${dir}"
+ OUTPUT_VARIABLE ninja_stdout
+ ERROR_VARIABLE ninja_stderr
+ RESULT_VARIABLE ninja_result
+ )
+ if(NOT ninja_result EQUAL 0)
+ message(STATUS "
+============ beginning of ninja's stdout ============
+${ninja_stdout}
+=============== end of ninja's stdout ===============
+")
+ message(STATUS "
+============ beginning of ninja's stderr ============
+${ninja_stderr}
+=============== end of ninja's stderr ===============
+")
+ message(FATAL_ERROR
+ "top ninja build failed exited with status ${ninja_result}")
+ endif()
+ set(ninja_stdout "${ninja_stdout}" PARENT_SCOPE)
+endfunction()
+
+_run_ninja("${RunCMake_BINARY_DIR}/CustomCommandDepfile-build")
+_run_ninja("${RunCMake_BINARY_DIR}/CustomCommandDepfile-build" -t deps hello.copy.c)
+if (ninja_stdout MATCHES "deps not found")
+ list(APPEND RunCMake_TEST_FAILED "Ninja did not track the deps of hello.copy.c in the database")
+endif ()
+_run_ninja("${RunCMake_BINARY_DIR}/CustomCommandDepfile-build" -t deps hello.copy2.c)
+if (ninja_stdout MATCHES "deps not found")
+ list(APPEND RunCMake_TEST_FAILED "Ninja did not track the deps of hello.copy2.c in the database")
+endif ()
diff --git a/Tests/RunCMake/Ninja/CustomCommandDepfileAsByproduct-check.cmake b/Tests/RunCMake/Ninja/CustomCommandDepfileAsByproduct-check.cmake
new file mode 100644
index 0000000..b2a553b
--- /dev/null
+++ b/Tests/RunCMake/Ninja/CustomCommandDepfileAsByproduct-check.cmake
@@ -0,0 +1,47 @@
+set(log "${RunCMake_BINARY_DIR}/CustomCommandDepfileAsByproduct-build/build.ninja")
+file(READ "${log}" build_file)
+
+set(RunCMake_TEST_FAILED)
+if(NOT "${build_file}" MATCHES "depfile = test\\.d")
+ string(CONCAT no_test_d "Log file:\n ${log}\n" "does not have expected line: depfile = test.d")
+ list(APPEND RunCMake_TEST_FAILED "${no_test_d}")
+endif()
+if(NOT "${build_file}" MATCHES "depfile = test_Debug\\.d")
+ string(CONCAT no_test_Debug_d "\nLog file:\n ${log}\n" "does not have expected line: depfile = test_Debug.d")
+ list(APPEND RunCMake_TEST_FAILED "${no_test_Debug_d}")
+endif()
+
+function(_run_ninja dir)
+ execute_process(
+ COMMAND "${RunCMake_MAKE_PROGRAM}" ${ARGN}
+ WORKING_DIRECTORY "${dir}"
+ OUTPUT_VARIABLE ninja_stdout
+ ERROR_VARIABLE ninja_stderr
+ RESULT_VARIABLE ninja_result
+ )
+ if(NOT ninja_result EQUAL 0)
+ message(STATUS "
+============ beginning of ninja's stdout ============
+${ninja_stdout}
+=============== end of ninja's stdout ===============
+")
+ message(STATUS "
+============ beginning of ninja's stderr ============
+${ninja_stderr}
+=============== end of ninja's stderr ===============
+")
+ message(FATAL_ERROR
+ "top ninja build failed exited with status ${ninja_result}")
+ endif()
+ set(ninja_stdout "${ninja_stdout}" PARENT_SCOPE)
+endfunction()
+
+_run_ninja("${RunCMake_BINARY_DIR}/CustomCommandDepfileAsByproduct-build")
+_run_ninja("${RunCMake_BINARY_DIR}/CustomCommandDepfileAsByproduct-build" -t deps hello.copy.c)
+if (NOT ninja_stdout MATCHES "deps not found")
+ list(APPEND RunCMake_TEST_FAILED "Ninja tracked the deps of hello.copy.c in the database")
+endif ()
+_run_ninja("${RunCMake_BINARY_DIR}/CustomCommandDepfileAsByproduct-build" -t deps hello.copy2.c)
+if (NOT ninja_stdout MATCHES "deps not found")
+ list(APPEND RunCMake_TEST_FAILED "Ninja tracked the deps of hello.copy2.c in the database")
+endif ()
diff --git a/Tests/RunCMake/Ninja/CustomCommandDepfileAsByproduct.cmake b/Tests/RunCMake/Ninja/CustomCommandDepfileAsByproduct.cmake
new file mode 100644
index 0000000..cf3b35d
--- /dev/null
+++ b/Tests/RunCMake/Ninja/CustomCommandDepfileAsByproduct.cmake
@@ -0,0 +1,24 @@
+add_custom_command(
+ OUTPUT hello.copy.c
+ BYPRODUCTS "test.d"
+ COMMAND "${CMAKE_COMMAND}" -E copy
+ "${CMAKE_CURRENT_SOURCE_DIR}/hello.c"
+ hello.copy.c
+ WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}"
+ DEPFILE "test.d"
+ )
+
+add_custom_command(
+ OUTPUT hello.copy2.c
+ BYPRODUCTS "test_$<CONFIG>.d"
+ COMMAND "${CMAKE_COMMAND}" -E copy
+ "${CMAKE_CURRENT_SOURCE_DIR}/hello.c"
+ hello.copy2.c
+ WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}"
+ DEPFILE "test_$<CONFIG>.d"
+ )
+
+add_custom_target(copy ALL DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/hello.copy.c"
+ "${CMAKE_CURRENT_BINARY_DIR}/hello.copy2.c")
+
+include(CheckNoPrefixSubDir.cmake)
diff --git a/Tests/RunCMake/Ninja/CustomCommandDepfileAsOutput-check.cmake b/Tests/RunCMake/Ninja/CustomCommandDepfileAsOutput-check.cmake
new file mode 100644
index 0000000..4d738c8
--- /dev/null
+++ b/Tests/RunCMake/Ninja/CustomCommandDepfileAsOutput-check.cmake
@@ -0,0 +1,47 @@
+set(log "${RunCMake_BINARY_DIR}/CustomCommandDepfileAsOutput-build/build.ninja")
+file(READ "${log}" build_file)
+
+set(RunCMake_TEST_FAILED)
+if(NOT "${build_file}" MATCHES "depfile = test\\.d")
+ string(CONCAT no_test_d "Log file:\n ${log}\n" "does not have expected line: depfile = test.d")
+ list(APPEND RunCMake_TEST_FAILED "${no_test_d}")
+endif()
+if(NOT "${build_file}" MATCHES "depfile = test_Debug\\.d")
+ string(CONCAT no_test_Debug_d "\nLog file:\n ${log}\n" "does not have expected line: depfile = test_Debug.d")
+ list(APPEND RunCMake_TEST_FAILED "${no_test_Debug_d}")
+endif()
+
+function(_run_ninja dir)
+ execute_process(
+ COMMAND "${RunCMake_MAKE_PROGRAM}" ${ARGN}
+ WORKING_DIRECTORY "${dir}"
+ OUTPUT_VARIABLE ninja_stdout
+ ERROR_VARIABLE ninja_stderr
+ RESULT_VARIABLE ninja_result
+ )
+ if(NOT ninja_result EQUAL 0)
+ message(STATUS "
+============ beginning of ninja's stdout ============
+${ninja_stdout}
+=============== end of ninja's stdout ===============
+")
+ message(STATUS "
+============ beginning of ninja's stderr ============
+${ninja_stderr}
+=============== end of ninja's stderr ===============
+")
+ message(FATAL_ERROR
+ "top ninja build failed exited with status ${ninja_result}")
+ endif()
+ set(ninja_stdout "${ninja_stdout}" PARENT_SCOPE)
+endfunction()
+
+_run_ninja("${RunCMake_BINARY_DIR}/CustomCommandDepfileAsOutput-build")
+_run_ninja("${RunCMake_BINARY_DIR}/CustomCommandDepfileAsOutput-build" -t deps hello.copy.c)
+if (NOT ninja_stdout MATCHES "deps not found")
+ list(APPEND RunCMake_TEST_FAILED "Ninja tracked the deps of hello.copy.c in the database")
+endif ()
+_run_ninja("${RunCMake_BINARY_DIR}/CustomCommandDepfileAsOutput-build" -t deps hello.copy2.c)
+if (NOT ninja_stdout MATCHES "deps not found")
+ list(APPEND RunCMake_TEST_FAILED "Ninja tracked the deps of hello.copy2.c in the database")
+endif ()
diff --git a/Tests/RunCMake/Ninja/CustomCommandDepfileAsOutput.cmake b/Tests/RunCMake/Ninja/CustomCommandDepfileAsOutput.cmake
new file mode 100644
index 0000000..07a12b7
--- /dev/null
+++ b/Tests/RunCMake/Ninja/CustomCommandDepfileAsOutput.cmake
@@ -0,0 +1,24 @@
+add_custom_command(
+ OUTPUT hello.copy.c
+ "test.d"
+ COMMAND "${CMAKE_COMMAND}" -E copy
+ "${CMAKE_CURRENT_SOURCE_DIR}/hello.c"
+ hello.copy.c
+ WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}"
+ DEPFILE "test.d"
+ )
+
+add_custom_command(
+ OUTPUT hello.copy2.c
+ "test_$<CONFIG>.d"
+ COMMAND "${CMAKE_COMMAND}" -E copy
+ "${CMAKE_CURRENT_SOURCE_DIR}/hello.c"
+ hello.copy2.c
+ WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}"
+ DEPFILE "test_$<CONFIG>.d"
+ )
+
+add_custom_target(copy ALL DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/hello.copy.c"
+ "${CMAKE_CURRENT_BINARY_DIR}/hello.copy2.c")
+
+include(CheckNoPrefixSubDir.cmake)
diff --git a/Tests/RunCMake/Ninja/RunCMakeTest.cmake b/Tests/RunCMake/Ninja/RunCMakeTest.cmake
index 69f2587..9777d17 100644
--- a/Tests/RunCMake/Ninja/RunCMakeTest.cmake
+++ b/Tests/RunCMake/Ninja/RunCMakeTest.cmake
@@ -100,6 +100,8 @@ run_CMP0058(NEW-no)
run_CMP0058(NEW-by)
run_cmake_with_options(CustomCommandDepfile -DCMAKE_BUILD_TYPE=Debug)
+run_cmake_with_options(CustomCommandDepfileAsOutput -DCMAKE_BUILD_TYPE=Debug)
+run_cmake_with_options(CustomCommandDepfileAsByproduct -DCMAKE_BUILD_TYPE=Debug)
run_cmake(CustomCommandJobPool)
run_cmake(JobPoolUsesTerminal)
diff --git a/Tests/RunCMake/NinjaMultiConfig/CustomCommandDepfile-check.cmake b/Tests/RunCMake/NinjaMultiConfig/CustomCommandDepfile-check.cmake
index 3674aba..673391c 100644
--- a/Tests/RunCMake/NinjaMultiConfig/CustomCommandDepfile-check.cmake
+++ b/Tests/RunCMake/NinjaMultiConfig/CustomCommandDepfile-check.cmake
@@ -10,3 +10,38 @@ if(NOT "${build_file}" MATCHES "depfile = test_Debug\\.d")
string(CONCAT no_test_Debug_d "\nLog file:\n ${log}\n" "does not have expected line: depfile = test_Debug.d")
list(APPEND RunCMake_TEST_FAILED "${no_test_Debug_d}")
endif()
+
+function(_run_ninja dir)
+ execute_process(
+ COMMAND "${RunCMake_MAKE_PROGRAM}" ${ARGN}
+ WORKING_DIRECTORY "${dir}"
+ OUTPUT_VARIABLE ninja_stdout
+ ERROR_VARIABLE ninja_stderr
+ RESULT_VARIABLE ninja_result
+ )
+ if(NOT ninja_result EQUAL 0)
+ message(STATUS "
+============ beginning of ninja's stdout ============
+${ninja_stdout}
+=============== end of ninja's stdout ===============
+")
+ message(STATUS "
+============ beginning of ninja's stderr ============
+${ninja_stderr}
+=============== end of ninja's stderr ===============
+")
+ message(FATAL_ERROR
+ "top ninja build failed exited with status ${ninja_result}")
+ endif()
+ set(ninja_stdout "${ninja_stdout}" PARENT_SCOPE)
+endfunction()
+
+_run_ninja("${RunCMake_BINARY_DIR}/CustomCommandDepfile-build")
+_run_ninja("${RunCMake_BINARY_DIR}/CustomCommandDepfile-build" -t deps main.copy.c)
+if (ninja_stdout MATCHES "deps not found")
+ list(APPEND RunCMake_TEST_FAILED "Ninja did not track the deps of main.copy.c in the database")
+endif ()
+_run_ninja("${RunCMake_BINARY_DIR}/CustomCommandDepfile-build" -t deps main.copy2.c)
+if (ninja_stdout MATCHES "deps not found")
+ list(APPEND RunCMake_TEST_FAILED "Ninja did not track the deps of main.copy2.c in the database")
+endif ()
diff --git a/Tests/RunCMake/NinjaMultiConfig/CustomCommandDepfileAsByproduct-check.cmake b/Tests/RunCMake/NinjaMultiConfig/CustomCommandDepfileAsByproduct-check.cmake
new file mode 100644
index 0000000..ced40ab
--- /dev/null
+++ b/Tests/RunCMake/NinjaMultiConfig/CustomCommandDepfileAsByproduct-check.cmake
@@ -0,0 +1,47 @@
+set(log "${RunCMake_BINARY_DIR}/CustomCommandDepfileAsByproduct-build/CMakeFiles/impl-Debug.ninja")
+file(READ "${log}" build_file)
+
+set(RunCMake_TEST_FAILED)
+if(NOT "${build_file}" MATCHES "depfile = test\\.d")
+ string(CONCAT no_test_d "Log file:\n ${log}\n" "does not have expected line: depfile = test.d")
+ list(APPEND RunCMake_TEST_FAILED "${no_test_d}")
+endif()
+if(NOT "${build_file}" MATCHES "depfile = test_Debug\\.d")
+ string(CONCAT no_test_Debug_d "\nLog file:\n ${log}\n" "does not have expected line: depfile = test_Debug.d")
+ list(APPEND RunCMake_TEST_FAILED "${no_test_Debug_d}")
+endif()
+
+function(_run_ninja dir)
+ execute_process(
+ COMMAND "${RunCMake_MAKE_PROGRAM}" ${ARGN}
+ WORKING_DIRECTORY "${dir}"
+ OUTPUT_VARIABLE ninja_stdout
+ ERROR_VARIABLE ninja_stderr
+ RESULT_VARIABLE ninja_result
+ )
+ if(NOT ninja_result EQUAL 0)
+ message(STATUS "
+============ beginning of ninja's stdout ============
+${ninja_stdout}
+=============== end of ninja's stdout ===============
+")
+ message(STATUS "
+============ beginning of ninja's stderr ============
+${ninja_stderr}
+=============== end of ninja's stderr ===============
+")
+ message(FATAL_ERROR
+ "top ninja build failed exited with status ${ninja_result}")
+ endif()
+ set(ninja_stdout "${ninja_stdout}" PARENT_SCOPE)
+endfunction()
+
+_run_ninja("${RunCMake_BINARY_DIR}/CustomCommandDepfileAsByproduct-build")
+_run_ninja("${RunCMake_BINARY_DIR}/CustomCommandDepfileAsByproduct-build" -t deps main.copy.c)
+if (NOT ninja_stdout MATCHES "deps not found")
+ list(APPEND RunCMake_TEST_FAILED "Ninja tracked the deps of main.copy.c in the database")
+endif ()
+_run_ninja("${RunCMake_BINARY_DIR}/CustomCommandDepfileAsByproduct-build" -t deps main.copy2.c)
+if (NOT ninja_stdout MATCHES "deps not found")
+ list(APPEND RunCMake_TEST_FAILED "Ninja tracked the deps of main.copy2.c in the database")
+endif ()
diff --git a/Tests/RunCMake/NinjaMultiConfig/CustomCommandDepfileAsByproduct.cmake b/Tests/RunCMake/NinjaMultiConfig/CustomCommandDepfileAsByproduct.cmake
new file mode 100644
index 0000000..e1e49cb
--- /dev/null
+++ b/Tests/RunCMake/NinjaMultiConfig/CustomCommandDepfileAsByproduct.cmake
@@ -0,0 +1,22 @@
+add_custom_command(
+ OUTPUT main.copy.c
+ BYPRODUCTS "test.d"
+ COMMAND "${CMAKE_COMMAND}" -E copy
+ "${CMAKE_CURRENT_SOURCE_DIR}/main.c"
+ main.copy.c
+ WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}"
+ DEPFILE "test.d"
+ )
+
+add_custom_command(
+ OUTPUT main.copy2.c
+ BYPRODUCTS "test_$<CONFIG>.d"
+ COMMAND "${CMAKE_COMMAND}" -E copy
+ "${CMAKE_CURRENT_SOURCE_DIR}/main.c"
+ main.copy2.c
+ WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}"
+ DEPFILE "test_$<CONFIG>.d"
+ )
+
+add_custom_target(copy ALL DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/main.copy.c"
+ "${CMAKE_CURRENT_BINARY_DIR}/main.copy2.c")
diff --git a/Tests/RunCMake/NinjaMultiConfig/CustomCommandDepfileAsOutput-check.cmake b/Tests/RunCMake/NinjaMultiConfig/CustomCommandDepfileAsOutput-check.cmake
new file mode 100644
index 0000000..d4a87ba
--- /dev/null
+++ b/Tests/RunCMake/NinjaMultiConfig/CustomCommandDepfileAsOutput-check.cmake
@@ -0,0 +1,47 @@
+set(log "${RunCMake_BINARY_DIR}/CustomCommandDepfileAsOutput-build/CMakeFiles/impl-Debug.ninja")
+file(READ "${log}" build_file)
+
+set(RunCMake_TEST_FAILED)
+if(NOT "${build_file}" MATCHES "depfile = test\\.d")
+ string(CONCAT no_test_d "Log file:\n ${log}\n" "does not have expected line: depfile = test.d")
+ list(APPEND RunCMake_TEST_FAILED "${no_test_d}")
+endif()
+if(NOT "${build_file}" MATCHES "depfile = test_Debug\\.d")
+ string(CONCAT no_test_Debug_d "\nLog file:\n ${log}\n" "does not have expected line: depfile = test_Debug.d")
+ list(APPEND RunCMake_TEST_FAILED "${no_test_Debug_d}")
+endif()
+
+function(_run_ninja dir)
+ execute_process(
+ COMMAND "${RunCMake_MAKE_PROGRAM}" ${ARGN}
+ WORKING_DIRECTORY "${dir}"
+ OUTPUT_VARIABLE ninja_stdout
+ ERROR_VARIABLE ninja_stderr
+ RESULT_VARIABLE ninja_result
+ )
+ if(NOT ninja_result EQUAL 0)
+ message(STATUS "
+============ beginning of ninja's stdout ============
+${ninja_stdout}
+=============== end of ninja's stdout ===============
+")
+ message(STATUS "
+============ beginning of ninja's stderr ============
+${ninja_stderr}
+=============== end of ninja's stderr ===============
+")
+ message(FATAL_ERROR
+ "top ninja build failed exited with status ${ninja_result}")
+ endif()
+ set(ninja_stdout "${ninja_stdout}" PARENT_SCOPE)
+endfunction()
+
+_run_ninja("${RunCMake_BINARY_DIR}/CustomCommandDepfileAsOutput-build")
+_run_ninja("${RunCMake_BINARY_DIR}/CustomCommandDepfileAsOutput-build" -t deps main.copy.c)
+if (NOT ninja_stdout MATCHES "deps not found")
+ list(APPEND RunCMake_TEST_FAILED "Ninja tracked the deps of main.copy.c in the database")
+endif ()
+_run_ninja("${RunCMake_BINARY_DIR}/CustomCommandDepfileAsOutput-build" -t deps main.copy2.c)
+if (NOT ninja_stdout MATCHES "deps not found")
+ list(APPEND RunCMake_TEST_FAILED "Ninja tracked the deps of main.copy2.c in the database")
+endif ()
diff --git a/Tests/RunCMake/NinjaMultiConfig/CustomCommandDepfileAsOutput.cmake b/Tests/RunCMake/NinjaMultiConfig/CustomCommandDepfileAsOutput.cmake
new file mode 100644
index 0000000..0617970
--- /dev/null
+++ b/Tests/RunCMake/NinjaMultiConfig/CustomCommandDepfileAsOutput.cmake
@@ -0,0 +1,22 @@
+add_custom_command(
+ OUTPUT main.copy.c
+ "test.d"
+ COMMAND "${CMAKE_COMMAND}" -E copy
+ "${CMAKE_CURRENT_SOURCE_DIR}/main.c"
+ main.copy.c
+ WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}"
+ DEPFILE "test.d"
+ )
+
+add_custom_command(
+ OUTPUT main.copy2.c
+ "test_$<CONFIG>.d"
+ COMMAND "${CMAKE_COMMAND}" -E copy
+ "${CMAKE_CURRENT_SOURCE_DIR}/main.c"
+ main.copy2.c
+ WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}"
+ DEPFILE "test_$<CONFIG>.d"
+ )
+
+add_custom_target(copy ALL DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/main.copy.c"
+ "${CMAKE_CURRENT_BINARY_DIR}/main.copy2.c")
diff --git a/Tests/RunCMake/NinjaMultiConfig/RunCMakeTest.cmake b/Tests/RunCMake/NinjaMultiConfig/RunCMakeTest.cmake
index 0ccf8e8..5c6a22d 100644
--- a/Tests/RunCMake/NinjaMultiConfig/RunCMakeTest.cmake
+++ b/Tests/RunCMake/NinjaMultiConfig/RunCMakeTest.cmake
@@ -388,6 +388,8 @@ unset(RunCMake_TEST_NO_CLEAN)
unset(RunCMake_TEST_BINARY_DIR)
run_cmake(CustomCommandDepfile)
+run_cmake(CustomCommandDepfileAsOutput)
+run_cmake(CustomCommandDepfileAsByproduct)
set(RunCMake_TEST_OPTIONS "-DCMAKE_CROSS_CONFIGS=all")
run_cmake(PerConfigSources)
diff --git a/Tests/RunCMake/TransformDepfile/noexist-gcc-stderr.txt b/Tests/RunCMake/TransformDepfile/noexist-gcc-stderr.txt
new file mode 100644
index 0000000..8956278
--- /dev/null
+++ b/Tests/RunCMake/TransformDepfile/noexist-gcc-stderr.txt
@@ -0,0 +1,4 @@
+^CMake Warning:
+ Expected depfile does not exist.
+
+ .*/Tests/RunCMake/TransformDepfile/noexist.d$