Skip to content

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.

Edited by Brad King
To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information