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
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
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
add_custom_commandis 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.