add_custom_command: OUTPUT with TARGET_FILE_ genex also used as a source file
With the WIP implementation of genex support in add_custom_command
at !5402 (merged) , it's not possible to use genexes like TARGET_FILE_BASE_NAME
and TARGET_FILE_PREFIX
in the OUTPUT
of a custom command.
The use case is creating build system specific support files to be used by another build tool (Qt prl files in my case, somewhat similar to pkg-config files). The names of the files must follow the naming of the generated library files.
To create the supporting files, we first need to use file(GENERATE)
for the skeleton content, and then do a post-processing step in a custom command, creating and processing a file for each value in CMAKE_CONFIGURATION_TYPES
.
Here's a minimal example. It fails both with single config Ninja
and multi-config Ninja Multi-Config
.
cmake_minimum_required(VERSION 3.18)
project(helperlib LANGUAGES CXX)
set(CMAKE_DEBUG_POSTFIX _debug)
set(main_path "${CMAKE_CURRENT_BINARY_DIR}/main.cpp")
file(WRITE "${main_path}" "int main() {return 0;}")
set(target "helperlib")
add_library(${target} "${main_path}")
set(base_name "$<TARGET_FILE_PREFIX:${target}>$<TARGET_FILE_BASE_NAME:${target}>")
set(unprocessed_prl_path "${CMAKE_CURRENT_BINARY_DIR}/unprocessed_${base_name}.prl")
file(GENERATE OUTPUT "${unprocessed_prl_path}" CONTENT "TARGET_NAME = $<TARGET_FILE_NAME:${target}>\nOTHER_DATA_HERE = 1")
set(final_file_path "${CMAKE_CURRENT_BINARY_DIR}/final_${base_name}.prl")
add_custom_command(
OUTPUT "${final_file_path}"
DEPENDS "${unprocessed_prl_path}"
COMMAND ${CMAKE_COMMAND} -E copy_if_different # do processing
"${unprocessed_prl_path}"
"${final_file_path}"
VERBATIM
)
set_source_files_properties("${final_file_path}" PROPERTIES GENERATED TRUE)
# Failed alternative 1 (preferred), so that building the target automatically creates the files
#target_sources(${target} PRIVATE "${final_file_path}")
# Failed alternative 2, where the creation of the files is done via a custom target
add_custom_target(helperlib_supporting_files "${final_file_path}")
$ cmake ..
-- Configuring done
CMake Error at CMakeLists.txt:19 (add_custom_command):
Error evaluating generator expression:
$<TARGET_FILE_PREFIX:helperlib>
No target "helperlib"
CMake Error at CMakeLists.txt:19 (add_custom_command):
Error evaluating generator expression:
$<TARGET_FILE_PREFIX:helperlib>
No target "helperlib"
CMake Error at CMakeLists.txt:19 (add_custom_command):
Error evaluating generator expression:
$<TARGET_FILE_PREFIX:helperlib>
No target "helperlib"
CMake Error at CMakeLists.txt:19 (add_custom_command):
Error evaluating generator expression:
$<TARGET_FILE_PREFIX:helperlib>
No target "helperlib"
-- Generating done
CMake Generate step failed. Build files cannot be regenerated correctly.