This works, but it raises another question, what are you supposed to do if later an argument must contain a semicolon? “Passing lists or strings with semi-colon to add_custom_command” exists but that looks a lot like a hack that works in one specific generator only. Is there a proper supported way of doing this?
"$<$<CONFIG:Debug>:--debug>" will definitely always generates an argument. That seems consistent across versions and generators. (observed in at least 3.26.5 with Makefiles and in 4.1.2 with Ninja). The documentation mentions this under generator expressions. I don’t see a mention of what happens without the quotes but it seems to always generate an argument as well.
Just testing with a toy example:
args.sh:
for arg in "$@"; do
printf '"%s"\n' "$arg"
done
CMakeLists.txt:
cmake_minimum_required(VERSION 3.24)
project(test)
add_custom_target(our_tool_command
COMMAND sh "${CMAKE_CURRENT_LIST_DIR}/args.sh" foo "$<$<CONFIG:Debug>:--debug>" bar $<$<CONFIG:Debug>:--debug>
VERBATIM)
Building the our_tool_command target in Release config results in
"foo"
""
"bar"
""
for cmake 4.1.2 using either Ninja, Unix Makefiles or Xcode.
Yes I thought passing VERBATIM is mandatory if you don’t want to be tied to one platform and generator.
So to summarize
Pass --debug for debug builds, and no argument for release build. This is solved by adding COMMAND_EXPAND_LISTS and "$<$<config:Debug>:--debug>"
But then we have no documented way of passing arguments containing semicolons.
So the solution to producing a literal ;:
\\; works and is consistent with cmake-language § Lists but that page cautions against relying on this when passing lists to other commands, so is this reliable behaviour across generators?