custom_command with directory as first OUTPUT fail!

OS: Linux
Generator: Unix Makefiles
CMake: 3.28.1

If have this custom command:

add_custom_command(
  OUTPUT 
    ${CMAKE_CURRENT_SOURCE_DIR}/out
    ${CMAKE_CURRENT_SOURCE_DIR}/out/out1.txt
    ${CMAKE_CURRENT_SOURCE_DIR}/out/out2.txt
  COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_CURRENT_SOURCE_DIR}/out
  COMMAND ${CMAKE_COMMAND} -E touch ${CMAKE_CURRENT_SOURCE_DIR}/out
  COMMAND ${CMAKE_COMMAND} -E touch ${CMAKE_CURRENT_SOURCE_DIR}/out/out1.txt
  COMMAND ${CMAKE_COMMAND} -E touch ${CMAKE_CURRENT_SOURCE_DIR}/out/out2.txt
  COMMENT "Generating out"
)

add_custom_target(
  CustomTarget1
  DEPENDS 
    ${CMAKE_CURRENT_SOURCE_DIR}/out
    ${CMAKE_CURRENT_SOURCE_DIR}/out/out1.txt
    ${CMAKE_CURRENT_SOURCE_DIR}/out/out2.txt
)

First build of CustomTarget1 and the custom command is executed as expected.
If I delete one of the out1.txt or out2.txt files and rebuild CustomTarget1 the custom command is not rerun.
If I however move the directory being the first output down the list so that the first output is a file everything works fine. I can delete any of the generated files or the directory and a rebuild will rerun the command. But as soon as the first output is a directory it falls apart.

Bonus info. With the “Ninja” generator everything works as expected and it makes no difference what the first output is. So my guess is that the problem is with the generated makefiles!

Regards
Klaus

You can only list files after the OUTPUT keyword. Listing a directory is not supported, and doing so should be considered undefined behavior.

@craig.scott thanks for the ultra quick response and the clarification.

The reason I have added the directory as output is that a “cmake clean” will then actually remove the entire folder and not only the content generated by whatever script is in the COMMAND.

It would be a nice addition to the docs if it was stated clearly there that directories are not good as OUTPUT!

Regards
Klaus

I don’t know what “cmake clean” is, I assume you meant a typical “make clean” or its equivalent for your chosen build tool.

Take a look at the ADDITIONAL_CLEAN_FILES directory property. Despite its name, it does allow you to list directories too (says so in its docs).