summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarc Chevrier <marc.chevrier@gmail.com>2021-04-09 17:09:52 (GMT)
committerMarc Chevrier <marc.chevrier@gmail.com>2021-04-12 11:06:49 (GMT)
commit0c47b91fccf5d55a0edc1512a543b8445a8fa4ba (patch)
tree564276e97cb2c4c0d08a8784d6cbbcac71dc1800
parent43ecda68eb85bdb38c635ecd3e5a5296a2451f81 (diff)
downloadCMake-0c47b91fccf5d55a0edc1512a543b8445a8fa4ba.zip
CMake-0c47b91fccf5d55a0edc1512a543b8445a8fa4ba.tar.gz
CMake-0c47b91fccf5d55a0edc1512a543b8445a8fa4ba.tar.bz2
Genex: add_custom_command: DEPFILE supports genex
This facility is very useful for 'Ninja Multi-Config' and required as well for future support of DEPFILE in 'Xcode' and 'Visual Studio' generators (#20286).
-rw-r--r--Help/command/add_custom_command.rst7
-rw-r--r--Help/release/dev/add_custom_command-DEPFILE-genex.rst5
-rw-r--r--Source/cmCustomCommandGenerator.cxx21
-rw-r--r--Source/cmCustomCommandGenerator.h1
-rw-r--r--Source/cmLocalNinjaGenerator.cxx2
-rw-r--r--Tests/RunCMake/BuildDepends/CustomCommandDepfile.cmake8
-rw-r--r--Tests/RunCMake/Ninja/CustomCommandDepfile-check.cmake7
-rw-r--r--Tests/RunCMake/Ninja/CustomCommandDepfile.cmake13
-rw-r--r--Tests/RunCMake/Ninja/RunCMakeTest.cmake2
-rw-r--r--Tests/RunCMake/NinjaMultiConfig/CustomCommandDepfile-check.cmake7
-rw-r--r--Tests/RunCMake/NinjaMultiConfig/CustomCommandDepfile.cmake13
11 files changed, 74 insertions, 12 deletions
diff --git a/Help/command/add_custom_command.rst b/Help/command/add_custom_command.rst
index c0b9593..b6ff0ea 100644
--- a/Help/command/add_custom_command.rst
+++ b/Help/command/add_custom_command.rst
@@ -272,7 +272,9 @@ The options are:
.. versionadded:: 3.7
Specify a ``.d`` depfile for the :generator:`Ninja` generator and
- :ref:`Makefile Generators`.
+ :ref:`Makefile Generators`. The depfile may use "generator expressions" with
+ the syntax ``$<...>``. See the :manual:`generator-expressions(7)
+ <cmake-generator-expressions(7)>` manual for available expressions.
A ``.d`` file holds dependencies usually emitted by the custom
command itself.
Using ``DEPFILE`` with other generators than :generator:`Ninja` or
@@ -281,6 +283,9 @@ The options are:
.. versionadded:: 3.20
Added the support of :ref:`Makefile Generators`.
+ .. versionadded:: 3.21
+ Added the support of :manual:`generator expressions <cmake-generator-expressions(7)>`.
+
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`
diff --git a/Help/release/dev/add_custom_command-DEPFILE-genex.rst b/Help/release/dev/add_custom_command-DEPFILE-genex.rst
new file mode 100644
index 0000000..52e5e9f
--- /dev/null
+++ b/Help/release/dev/add_custom_command-DEPFILE-genex.rst
@@ -0,0 +1,5 @@
+add_custom_command-DEPFILE-genex
+--------------------------------
+
+* The :command:`add_custom_command` command ``DEPFILE`` option learned to
+ support :manual:`generator expressions <cmake-generator-expressions(7)>`.
diff --git a/Source/cmCustomCommandGenerator.cxx b/Source/cmCustomCommandGenerator.cxx
index 4329caf..4705443 100644
--- a/Source/cmCustomCommandGenerator.cxx
+++ b/Source/cmCustomCommandGenerator.cxx
@@ -139,6 +139,14 @@ std::vector<std::string> EvaluateOutputs(std::vector<std::string> const& paths,
}
return outputs;
}
+
+std::string EvaluateDepfile(std::string const& path,
+ cmGeneratorExpression const& ge,
+ cmLocalGenerator* lg, std::string const& config)
+{
+ std::unique_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(path);
+ return cge->Evaluate(lg, config);
+}
}
cmCustomCommandGenerator::cmCustomCommandGenerator(
@@ -381,9 +389,20 @@ void cmCustomCommandGenerator::AppendArguments(unsigned int c,
}
}
+std::string cmCustomCommandGenerator::GetDepfile() const
+{
+ const auto& depfile = this->CC->GetDepfile();
+ if (depfile.empty()) {
+ return "";
+ }
+
+ cmGeneratorExpression ge(this->CC->GetBacktrace());
+ return EvaluateDepfile(depfile, ge, this->LG, this->OutputConfig);
+}
+
std::string cmCustomCommandGenerator::GetFullDepfile() const
{
- std::string depfile = this->CC->GetDepfile();
+ std::string depfile = this->GetDepfile();
if (depfile.empty()) {
return "";
}
diff --git a/Source/cmCustomCommandGenerator.h b/Source/cmCustomCommandGenerator.h
index 4be5b3f..53e5573 100644
--- a/Source/cmCustomCommandGenerator.h
+++ b/Source/cmCustomCommandGenerator.h
@@ -57,6 +57,7 @@ public:
std::vector<std::string> const& GetDepends() const;
std::set<BT<std::pair<std::string, bool>>> const& GetUtilities() const;
bool HasOnlyEmptyCommandLines() const;
+ std::string GetDepfile() const;
std::string GetFullDepfile() const;
std::string GetInternalDepfile() const;
diff --git a/Source/cmLocalNinjaGenerator.cxx b/Source/cmLocalNinjaGenerator.cxx
index 03d1697..c2a6410 100644
--- a/Source/cmLocalNinjaGenerator.cxx
+++ b/Source/cmLocalNinjaGenerator.cxx
@@ -670,7 +670,7 @@ void cmLocalNinjaGenerator::WriteCustomCommandBuildStatement(
cmCryptoHash hash(cmCryptoHash::AlgoSHA256);
customStep += hash.HashString(ninjaOutputs[0]).substr(0, 7);
- std::string depfile = cc->GetDepfile();
+ std::string depfile = ccg.GetDepfile();
if (!depfile.empty()) {
switch (cc->GetCMP0116Status()) {
case cmPolicies::WARN:
diff --git a/Tests/RunCMake/BuildDepends/CustomCommandDepfile.cmake b/Tests/RunCMake/BuildDepends/CustomCommandDepfile.cmake
index 01eac91..e4fdb4a 100644
--- a/Tests/RunCMake/BuildDepends/CustomCommandDepfile.cmake
+++ b/Tests/RunCMake/BuildDepends/CustomCommandDepfile.cmake
@@ -3,15 +3,15 @@ enable_language(C)
add_custom_command(
OUTPUT topcc.c
- DEPFILE topcc.c.d
- COMMAND ${CMAKE_COMMAND} -DOUTFILE=${CMAKE_CURRENT_BINARY_DIR}/topcc.c -DINFILE=topccdep.txt -DDEPFILE=topcc.c.d -P "${CMAKE_CURRENT_LIST_DIR}/WriteDepfile.cmake"
+ DEPFILE topcc_$<CONFIG>.c.d
+ COMMAND ${CMAKE_COMMAND} -DOUTFILE=${CMAKE_CURRENT_BINARY_DIR}/topcc.c -DINFILE=topccdep.txt -DDEPFILE=topcc_$<CONFIG>.c.d -P "${CMAKE_CURRENT_LIST_DIR}/WriteDepfile.cmake"
)
add_custom_target(topcc ALL DEPENDS topcc.c)
add_custom_command(
OUTPUT topexe.c
- DEPFILE ${CMAKE_CURRENT_BINARY_DIR}/topexe.c.d
- COMMAND ${CMAKE_COMMAND} -DOUTFILE=topexe.c "-DINFILE=${CMAKE_CURRENT_BINARY_DIR}/topexedep.txt" -DDEPFILE=topexe.c.d -P "${CMAKE_CURRENT_LIST_DIR}/WriteDepfile.cmake"
+ DEPFILE ${CMAKE_CURRENT_BINARY_DIR}/topexe_$<CONFIG>.c.d
+ COMMAND ${CMAKE_COMMAND} -DOUTFILE=topexe.c "-DINFILE=${CMAKE_CURRENT_BINARY_DIR}/topexedep.txt" -DDEPFILE=topexe_$<CONFIG>.c.d -P "${CMAKE_CURRENT_LIST_DIR}/WriteDepfile.cmake"
)
add_executable(topexe "${CMAKE_CURRENT_BINARY_DIR}/topexe.c")
diff --git a/Tests/RunCMake/Ninja/CustomCommandDepfile-check.cmake b/Tests/RunCMake/Ninja/CustomCommandDepfile-check.cmake
index 189de64..51f4f52 100644
--- a/Tests/RunCMake/Ninja/CustomCommandDepfile-check.cmake
+++ b/Tests/RunCMake/Ninja/CustomCommandDepfile-check.cmake
@@ -1,5 +1,10 @@
set(log "${RunCMake_BINARY_DIR}/CustomCommandDepfile-build/build.ninja")
file(READ "${log}" build_file)
+
+set(RunCMake_TEST_FAILED)
if(NOT "${build_file}" MATCHES "depfile = test\\.d")
- set(RunCMake_TEST_FAILED "Log file:\n ${log}\ndoes not have expected line: depfile = test.d")
+ list(APPEND RunCMake_TEST_FAILED "Log file:\n ${log}\ndoes not have expected line: depfile = test.d")
+endif()
+if(NOT "${build_file}" MATCHES "depfile = test_Debug\\.d")
+ list(APPEND RunCMake_TEST_FAILED "\nLog file:\n ${log}\ndoes not have expected line: depfile = test_Debug.d")
endif()
diff --git a/Tests/RunCMake/Ninja/CustomCommandDepfile.cmake b/Tests/RunCMake/Ninja/CustomCommandDepfile.cmake
index dbef2a5..0838d14 100644
--- a/Tests/RunCMake/Ninja/CustomCommandDepfile.cmake
+++ b/Tests/RunCMake/Ninja/CustomCommandDepfile.cmake
@@ -6,6 +6,17 @@ add_custom_command(
WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}"
DEPFILE "test.d"
)
-add_custom_target(copy ALL DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/hello.copy.c")
+
+add_custom_command(
+ OUTPUT hello.copy2.c
+ 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 0c0619d..1350326 100644
--- a/Tests/RunCMake/Ninja/RunCMakeTest.cmake
+++ b/Tests/RunCMake/Ninja/RunCMakeTest.cmake
@@ -67,7 +67,7 @@ run_CMP0058(WARN-by)
run_CMP0058(NEW-no)
run_CMP0058(NEW-by)
-run_cmake(CustomCommandDepfile)
+run_cmake_with_options(CustomCommandDepfile -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 c595b10..a7837ca 100644
--- a/Tests/RunCMake/NinjaMultiConfig/CustomCommandDepfile-check.cmake
+++ b/Tests/RunCMake/NinjaMultiConfig/CustomCommandDepfile-check.cmake
@@ -1,5 +1,10 @@
set(log "${RunCMake_BINARY_DIR}/CustomCommandDepfile-build/CMakeFiles/impl-Debug.ninja")
file(READ "${log}" build_file)
+
+set(RunCMake_TEST_FAILED)
if(NOT "${build_file}" MATCHES "depfile = test\\.d")
- set(RunCMake_TEST_FAILED "Log file:\n ${log}\ndoes not have expected line: depfile = test.d")
+ list(APPEND RunCMake_TEST_FAILED "Log file:\n ${log}\ndoes not have expected line: depfile = test.d")
+endif()
+if(NOT "${build_file}" MATCHES "depfile = test_Debug\\.d")
+ list(APPEND RunCMake_TEST_FAILED "\nLog file:\n ${log}\ndoes not have expected line: depfile = test_Debug.d")
endif()
diff --git a/Tests/RunCMake/NinjaMultiConfig/CustomCommandDepfile.cmake b/Tests/RunCMake/NinjaMultiConfig/CustomCommandDepfile.cmake
index 1a42670..4f8c114 100644
--- a/Tests/RunCMake/NinjaMultiConfig/CustomCommandDepfile.cmake
+++ b/Tests/RunCMake/NinjaMultiConfig/CustomCommandDepfile.cmake
@@ -6,4 +6,15 @@ add_custom_command(
WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}"
DEPFILE "test.d"
)
-add_custom_target(copy ALL DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/main.copy.c")
+
+add_custom_command(
+ OUTPUT main.copy2.c
+ 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")