diff --git a/Help/command/add_custom_command.rst b/Help/command/add_custom_command.rst index c184a96d6c..77357c0eee 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 22daa0e111..1440771d4d 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 d46ee08d11..c145907a1b 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 547fb1c33f..5741ae5276 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 cf00f5b852..4fe0b82843 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 2e43568d4c..9d25949cb8 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 f04bdd16a8..0f6bd07382 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 da9af49a03..b734ddd8ec 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 c317b83544..d29c02f588 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)