Generate header file containing the path to a build artifact for multi-config generators

Hi,

I have problems generating a file that contains a target_file-generator expression.

I reduced the issue to a small example:

CMakeLists.txt

cmake_minimum_required(VERSION 3.19)
project(GenerateTest LANGUAGES CXX)

add_executable(generateTest main.cpp)

file(GENERATE OUTPUT test.h INPUT test.h.in)

main.cpp

int main(int argc, char *argv[]){
    return 0;
}

test.h.in

const char* test = "$<TARGET_FILE:generateTest>";

If I try to generate the project using the MSVC generator it fails:

cmake ..
-- Building for: Visual Studio 17 2022
-- Selecting Windows SDK version 10.0.22621.0 to target Windows 10.0.26100.
-- The CXX compiler identification is MSVC 19.43.34810.0
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: C:/Program Files (x86)/Microsoft Visual Studio/2022/BuildTools/VC/Tools/MSVC/14.43.34808/bin/Hostx64/x64/cl.exe - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Configuring done (2.7s)
CMake Error in CMakeLists.txt:
  Evaluation file to be written multiple times with different content.  This
  is generally caused by the content evaluating the configuration type,
  language, or location of object files:

   test.h
....

The same error also occurs for “Ninja Multi-Config” - however, using the single-config Ninja-generator works.

I asked this before and got the answer to use $<CONFIG> to get the a unique output filename (cf. https://gitlab.kitware.com/cmake/cmake/-/issues/26898#note_1652172 & https://cmake.org/cmake/help/latest/command/file.html#generate)

If I do this, i.e.

file(GENERATE OUTPUT test$<CONFIG>.h INPUT test.h.in),

I end up with 4 header files testDebug.h, testRelease.h etc. - this would mean that wherever I use this file, I need to write #include <test$<CONFIG>.h> and apply file(GENERATE) to all files containing this. I think, that I don’t want to do this - how could I manage to get a header-file with a fixed name containing the path to the executable (which could change with build type)?

Thanks and best regards
oz

Try using $<CONFIG> as a directory component and setting target_include_directories with a corresponding generator expression. Then your header file is the same name, but there’s a debug directory and a release directory, etc.