Is there a way to add a resource file to Visual Studio project and copy it to the executable directory?

I have some text files that I want to add to the Visual Studio project. I can’t add it to the add_executable() call because I get this error:

  Cannot find source file:

    my_text_file.txt

  Tried extensions .c .C .c++ .cc .cpp .cxx .cu .mpp .m .M .mm .ixx .cppm .h
  .hh .h++ .hm .hpp .hxx .in .txx .f .F .for .f77 .f90 .f95 .f03 .hip .ispc

I also want to copy these to the build directory. I tried the command:

  add_custom_command(
        TARGET ${PROJECT_NAME} POST_BUILD
        COMMAND ${CMAKE_COMMAND} -E copy_if_different
                "${CMAKE_SOURCE_DIR}/my_text_file.txt"
                ${CMAKE_CURRENT_BINARY_DIR})

But it didn’t seem to work.

To add text files, I add them as sources, but you will need to mark them explicitly as header files:

set_source_files_properties(my_text_file.txt PROPERTIES HEADER_FILE_ONLY TRUE)

This will prevent it from being compiled but will still appear in your IDE, etc. They should still be added to the project using add_executable. Make sure that the path you give add_executable is correct since I think it only tries the various extensions if the file (as named) cannot be found in the current source dir.

For the copying, I do not see anything obviously wrong with your custom command. Just note that there is a difference between CMAKE_SOURCE_DIR and CMAKE_CURRENT_SOURCE_DIR. This could also be why your add_executable call is failing.

1 Like

Thanks Chris,

set_source_files_properties(my_text_file.txt PROPERTIES HEADER_FILE_ONLY TRUE)

That worked great.

As for the copy, I changed the command to:

  add_custom_command(
        TARGET ${PROJECT_NAME} POST_BUILD
        COMMAND ${CMAKE_COMMAND} -E copy
                ${CMAKE_CURRENT_SOURCE_DIR}/filenames_to_hash.txt
                ${CMAKE_CURRENT_BINARY_DIR})

and it worked, sorta. It put it in one level down from where the executable was put. So instead of build/project/Debug/, it put it in build/project/. What should I be making the target directory?

You can use the CMAKE_CFG_INTDIR variable for the subdir that is made per-generator (if relevant).

Attempted to show all the variables listed here: cmake-variables(7) — CMake 3.25.0 Documentation, but none showed the actual directory where the build was placed.

Hmmm, CMAKE_CFG_INTDIR seems to expand to $(Configuration). Not very useful. :frowning:

For Visual Studio, that is IDE-expanded into the name of the current configuration. This should work:

add_custom_command(
  TARGET ${PROJECT_NAME} POST_BUILD
  COMMAND ${CMAKE_COMMAND} -E copy
    ${CMAKE_CURRENT_SOURCE_DIR}/filenames_to_hash.txt
    ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR})

Alternatively, this is probably simpler:

add_custom_command(
  TARGET ${PROJECT_NAME} POST_BUILD
  COMMAND ${CMAKE_COMMAND} -E copy
    ${CMAKE_CURRENT_SOURCE_DIR}/filenames_to_hash.txt
    $<TARGET_FILE_DIR:${PROJECT_NAME}>)
1 Like

The generator expression was exactly what I was looking for. The other one didn’t work.

Thx for the help!

FYI: I couldn’t mark two messages as solutions, so I quoted them here.