From 8d2a503c1e65142732ca78d3df60dce9a929dee2 Mon Sep 17 00:00:00 2001 From: Glenn Coombs Date: Mon, 13 May 2024 12:09:19 +0800 Subject: add_custom_command: Allow OUTPUT filenames containing a hash '#' character Most generators now support this character after escaping and quoting cleanups over time. Disallow it only on generators that do support it. Fixes: #25604 --- Help/command/add_custom_command.rst | 6 ++++++ Source/cmLocalGenerator.cxx | 7 ++++++- Tests/CustomCommand/CMakeLists.txt | 9 +++++++++ Tests/RunCMake/add_custom_command/BadByproduct-stderr.txt | 8 +------- Tests/RunCMake/add_custom_command/BadByproduct.cmake | 4 ++-- Tests/RunCMake/add_custom_command/BadOutput-stderr.txt | 8 +------- Tests/RunCMake/add_custom_command/BadOutput.cmake | 4 ++-- Tests/RunCMake/add_custom_target/BadByproduct-stderr.txt | 8 +------- Tests/RunCMake/add_custom_target/BadByproduct.cmake | 4 ++-- 9 files changed, 30 insertions(+), 28 deletions(-) diff --git a/Help/command/add_custom_command.rst b/Help/command/add_custom_command.rst index c184a96..77357c0 100644 --- a/Help/command/add_custom_command.rst +++ b/Help/command/add_custom_command.rst @@ -269,6 +269,8 @@ The options are: source tree is mentioned as an absolute source file path elsewhere in the current directory. + The output file path may not contain ``<`` or ``>`` characters. + .. versionadded:: 3.20 Arguments to ``OUTPUT`` may use a restricted set of :manual:`generator expressions `. @@ -280,6 +282,10 @@ The options are: considered private unless they are listed in a non-private file set. See policy :policy:`CMP0154`. + .. versionchanged:: 3.30 + The output file path may now use ``#`` characters, except + when using the :generator:`Borland Makefiles` generator. + ``USES_TERMINAL`` .. versionadded:: 3.2 diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx index 22daa0e..1440771 100644 --- a/Source/cmLocalGenerator.cxx +++ b/Source/cmLocalGenerator.cxx @@ -4403,7 +4403,12 @@ void CreateGeneratedSource(cmLocalGenerator& lg, const std::string& output, } // Make sure the output file name has no invalid characters. - std::string::size_type pos = output.find_first_of("#<>"); + const bool hashNotAllowed = lg.GetState()->UseBorlandMake(); + std::string::size_type pos = output.find_first_of("<>"); + if (pos == std::string::npos && hashNotAllowed) { + pos = output.find_first_of('#'); + } + if (pos != std::string::npos) { lg.GetCMakeInstance()->IssueMessage( MessageType::FATAL_ERROR, diff --git a/Tests/CustomCommand/CMakeLists.txt b/Tests/CustomCommand/CMakeLists.txt index d46ee08..c145907 100644 --- a/Tests/CustomCommand/CMakeLists.txt +++ b/Tests/CustomCommand/CMakeLists.txt @@ -588,3 +588,12 @@ add_custom_target(drive_mac_fw ALL DEPENDS mac_fw.txt) # Test empty COMMANDs are omitted add_executable(empty_command empty_command.cxx) add_custom_command(TARGET empty_command POST_BUILD COMMAND $<0:date>) + +# Test OUTPUT allows filenames containing "#" on generators that support this +if(NOT CMAKE_GENERATOR MATCHES "Borland Makefiles") + add_custom_target(file_with_hash ALL DEPENDS "${PROJECT_BINARY_DIR}/hash#in#name.txt") + add_custom_command( + OUTPUT "${PROJECT_BINARY_DIR}/hash#in#name.txt" + COMMAND ${CMAKE_COMMAND} -E touch "${PROJECT_BINARY_DIR}/hash#in#name.txt" + ) +endif() diff --git a/Tests/RunCMake/add_custom_command/BadByproduct-stderr.txt b/Tests/RunCMake/add_custom_command/BadByproduct-stderr.txt index 547fb1c..5741ae5 100644 --- a/Tests/RunCMake/add_custom_command/BadByproduct-stderr.txt +++ b/Tests/RunCMake/add_custom_command/BadByproduct-stderr.txt @@ -1,9 +1,3 @@ -CMake Error at BadByproduct.cmake:2 \(add_custom_command\): - BYPRODUCTS containing a "#" is not allowed. -Call Stack \(most recent call first\): - CMakeLists.txt:3 \(include\) - - CMake Error at BadByproduct.cmake:3 \(add_custom_command\): BYPRODUCTS containing a "<" is not allowed. Call Stack \(most recent call first\): @@ -17,7 +11,7 @@ Call Stack \(most recent call first\): ( CMake Error at BadByproduct.cmake:5 \(add_custom_command\): - BYPRODUCTS containing a "#" is not allowed. + BYPRODUCTS containing a ">" is not allowed. Call Stack \(most recent call first\): CMakeLists.txt:3 \(include\) diff --git a/Tests/RunCMake/add_custom_command/BadByproduct.cmake b/Tests/RunCMake/add_custom_command/BadByproduct.cmake index cf00f5b..4fe0b82 100644 --- a/Tests/RunCMake/add_custom_command/BadByproduct.cmake +++ b/Tests/RunCMake/add_custom_command/BadByproduct.cmake @@ -1,8 +1,8 @@ set(CMAKE_DISABLE_SOURCE_CHANGES ON) -add_custom_command(OUTPUT a BYPRODUCTS "a#") + add_custom_command(OUTPUT b BYPRODUCTS "a<") add_custom_command(OUTPUT c BYPRODUCTS "a>") -add_custom_command(OUTPUT d BYPRODUCTS "$/#") +add_custom_command(OUTPUT d BYPRODUCTS "$/$") add_custom_command(OUTPUT e BYPRODUCTS ${CMAKE_CURRENT_SOURCE_DIR}/f) add_custom_command(OUTPUT f BYPRODUCTS "$") add_custom_command(OUTPUT h BYPRODUCTS "$") diff --git a/Tests/RunCMake/add_custom_command/BadOutput-stderr.txt b/Tests/RunCMake/add_custom_command/BadOutput-stderr.txt index 2e43568..9d25949 100644 --- a/Tests/RunCMake/add_custom_command/BadOutput-stderr.txt +++ b/Tests/RunCMake/add_custom_command/BadOutput-stderr.txt @@ -1,9 +1,3 @@ -CMake Error at BadOutput.cmake:2 \(add_custom_command\): - OUTPUT containing a "#" is not allowed. -Call Stack \(most recent call first\): - CMakeLists.txt:3 \(include\) - - CMake Error at BadOutput.cmake:3 \(add_custom_command\): OUTPUT containing a "<" is not allowed. Call Stack \(most recent call first\): @@ -17,7 +11,7 @@ Call Stack \(most recent call first\): ( CMake Error at BadOutput.cmake:5 \(add_custom_command\): - OUTPUT containing a "#" is not allowed. + OUTPUT containing a ">" is not allowed. Call Stack \(most recent call first\): CMakeLists.txt:3 \(include\) diff --git a/Tests/RunCMake/add_custom_command/BadOutput.cmake b/Tests/RunCMake/add_custom_command/BadOutput.cmake index f04bdd1..0f6bd07 100644 --- a/Tests/RunCMake/add_custom_command/BadOutput.cmake +++ b/Tests/RunCMake/add_custom_command/BadOutput.cmake @@ -1,8 +1,8 @@ set(CMAKE_DISABLE_SOURCE_CHANGES ON) -add_custom_command(OUTPUT "a#" COMMAND a) + add_custom_command(OUTPUT "a<" COMMAND b) add_custom_command(OUTPUT "a>" COMMAND c) -add_custom_command(OUTPUT "$/#" COMMAND d) +add_custom_command(OUTPUT "$/$" COMMAND d) add_custom_command(OUTPUT ${CMAKE_CURRENT_SOURCE_DIR}/e COMMAND f) add_custom_command(OUTPUT "$" COMMAND g) add_custom_command(OUTPUT "$" COMMAND h) diff --git a/Tests/RunCMake/add_custom_target/BadByproduct-stderr.txt b/Tests/RunCMake/add_custom_target/BadByproduct-stderr.txt index da9af49..b734ddd 100644 --- a/Tests/RunCMake/add_custom_target/BadByproduct-stderr.txt +++ b/Tests/RunCMake/add_custom_target/BadByproduct-stderr.txt @@ -1,9 +1,3 @@ -CMake Error at BadByproduct.cmake:2 \(add_custom_target\): - BYPRODUCTS containing a "#" is not allowed. -Call Stack \(most recent call first\): - CMakeLists.txt:3 \(include\) - - CMake Error at BadByproduct.cmake:3 \(add_custom_target\): BYPRODUCTS containing a "<" is not allowed. Call Stack \(most recent call first\): @@ -17,7 +11,7 @@ Call Stack \(most recent call first\): ( CMake Error at BadByproduct.cmake:5 \(add_custom_target\): - BYPRODUCTS containing a "#" is not allowed. + BYPRODUCTS containing a ">" is not allowed. Call Stack \(most recent call first\): CMakeLists.txt:3 \(include\) diff --git a/Tests/RunCMake/add_custom_target/BadByproduct.cmake b/Tests/RunCMake/add_custom_target/BadByproduct.cmake index c317b83..d29c02f 100644 --- a/Tests/RunCMake/add_custom_target/BadByproduct.cmake +++ b/Tests/RunCMake/add_custom_target/BadByproduct.cmake @@ -1,8 +1,8 @@ set(CMAKE_DISABLE_SOURCE_CHANGES ON) -add_custom_target(a BYPRODUCTS "a#" COMMAND b) + add_custom_target(c BYPRODUCTS "a<" COMMAND d) add_custom_target(e BYPRODUCTS "a>" COMMAND f) -add_custom_target(g BYPRODUCTS "$/#" COMMAND h) +add_custom_target(g BYPRODUCTS "$/$" COMMAND h) add_custom_target(i BYPRODUCTS ${CMAKE_CURRENT_SOURCE_DIR}/j COMMAND k) add_custom_target(l BYPRODUCTS "$" COMMAND m) add_custom_target(n BYPRODUCTS "$" COMMAND o) -- cgit v0.12