diff options
author | Marc Chevrier <marc.chevrier@gmail.com> | 2021-04-09 17:09:52 (GMT) |
---|---|---|
committer | Marc Chevrier <marc.chevrier@gmail.com> | 2021-04-12 11:06:49 (GMT) |
commit | 0c47b91fccf5d55a0edc1512a543b8445a8fa4ba (patch) | |
tree | 564276e97cb2c4c0d08a8784d6cbbcac71dc1800 | |
parent | 43ecda68eb85bdb38c635ecd3e5a5296a2451f81 (diff) | |
download | CMake-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.rst | 7 | ||||
-rw-r--r-- | Help/release/dev/add_custom_command-DEPFILE-genex.rst | 5 | ||||
-rw-r--r-- | Source/cmCustomCommandGenerator.cxx | 21 | ||||
-rw-r--r-- | Source/cmCustomCommandGenerator.h | 1 | ||||
-rw-r--r-- | Source/cmLocalNinjaGenerator.cxx | 2 | ||||
-rw-r--r-- | Tests/RunCMake/BuildDepends/CustomCommandDepfile.cmake | 8 | ||||
-rw-r--r-- | Tests/RunCMake/Ninja/CustomCommandDepfile-check.cmake | 7 | ||||
-rw-r--r-- | Tests/RunCMake/Ninja/CustomCommandDepfile.cmake | 13 | ||||
-rw-r--r-- | Tests/RunCMake/Ninja/RunCMakeTest.cmake | 2 | ||||
-rw-r--r-- | Tests/RunCMake/NinjaMultiConfig/CustomCommandDepfile-check.cmake | 7 | ||||
-rw-r--r-- | Tests/RunCMake/NinjaMultiConfig/CustomCommandDepfile.cmake | 13 |
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") |