Empty argument in add_custom_command crashes when using single-configuration generator and COMMAND_EXPAND_LISTS is provided
See also MR !2073 (closed).
Consider the following CMakeLists.txt
:
cmake_minimum_required(VERSION 3.9)
project(test CXX)
if(NOT EXISTS foo.cpp)
file(WRITE foo.cpp "")
endif()
add_library(foo STATIC foo.cpp)
add_custom_command(
# In real life, the empty string on the next line would be a generator expression that evaluates to the empty string for some configurations.
TARGET foo POST_BUILD COMMAND ""
COMMAND_EXPAND_LISTS
)
Use a single-configuration generator to configure and observe that CMake crashes somewhere in between the configuration and generation phase.
I had a closer look at the problem and the cause seems to lie in the constructor of cmCustomCommandGenerator
. In case the command is empty and COMMAND_EXPAND_LISTS
is unset, the empty string is added to the argument list. In case COMMAND_EXPAND_LISTS
is given, however, it is not. Later on in the code, the crash is caused when the first element of an empty vector is accessed (see cmCustomCommandGenerator::GetArgv0Location
).
My fix was to mimick the behavior of the constructor for the case in which COMMAND_EXPAND_LISTS
is absent, i.e., not removing empty arguments. To me, this made sense, as:
- the explicit absence of a
COMMAND
inadd_custom_command
is already considered a FATAL_ERROR. This, and the fact that the first element in the list is accessed later on, suggests to me that there is an invariant stating that there should always be a command, but it might be empty. - I noticed the existence of a method
cmCustomCommandGenerator::HasOnlyEmptyCommandLines
, which suggests that custom commands, at least internally, are allowed to be empty.
it seems, however, that things might not be as simple as I initially thought as one of the reasons of being of COMMAND_EXPAND_LISTS
was exactly to filter out the empty lines, so I would like to open a discussion on how to best fix the crash.