Copy data files to build dir and avoid Debug/Release folder when using MSVC

Hi,

In my tests (I use google test) I use some external my_file.txt. Thus I need to put this my_file.txt to the build dir.
It is known that MSVC creates additional config (Debug/Release) folder and other compilers don’t.

I ve tried to remove these additional config folders in the same way as it was proposed in the link above:

# First for the generic no-config case (e.g. with mingw)
set( CMAKE_RUNTIME_OUTPUT_DIRECTORY ${youroutputdirectory} )
set( CMAKE_LIBRARY_OUTPUT_DIRECTORY ${youroutputdirectory} )
set( CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${youroutputdirectory} )
# Second, for multi-config builds (e.g. msvc)
foreach( OUTPUTCONFIG ${CMAKE_CONFIGURATION_TYPES} )
    string( TOUPPER ${OUTPUTCONFIG} OUTPUTCONFIG )
    set( CMAKE_RUNTIME_OUTPUT_DIRECTORY_${OUTPUTCONFIG} ${youroutputdirectory} )
    set( CMAKE_LIBRARY_OUTPUT_DIRECTORY_${OUTPUTCONFIG} ${youroutputdirectory} )
    set( CMAKE_ARCHIVE_OUTPUT_DIRECTORY_${OUTPUTCONFIG} ${youroutputdirectory} )
endforeach( OUTPUTCONFIG CMAKE_CONFIGURATION_TYPES )

It works for my own project but google test (wich is a subproject) creates Debug folder and put there its .moc-files like in the picture:

If someone has idea how to make this approach crosscompile please share.
For now I copy my file (folder actually) with command:

file(COPY "data"
  DESTINATION ${CMAKE_RUNTIME_OUTPUT_DIRECTORY})

This has nothing to do with MSVC or the compiler in use. It is completely controlled by the generator in use. If you don’t want these directories, don’t use a multi-config generator (Visual Studio or Xcode). They are there to avoid clobbering each other when building in different configurations.

1 Like

If you use a multi-configuration generator, and then try to flatten Debug/Release/etc into a single folder, I expect that trying to switch configurations would lead to all sorts of weird issues.

In our root cmake, we check if we’re multi- or single-configuration and set a (suitably escaped) variable:

get_property(MULTI_PROJ_GENERATOR GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
if (NOT MULTI_PROJ_GENERATOR)
  # default to a release build if no configuraton was set
  set(CMAKE_BUILD_TYPE Release CACHE STRING "Default build configuration")
  set(INSTALL_DIR "\${CMAKE_INSTALL_CONFIG_NAME}")
else()
  set(INSTALL_DIR ".")
endif()

now you can write your install statements using that variable, and they work for single- and multi-config generators, I think that even cpack is ok with this approach…

install(
  DIRECTORY "${CMAKE_SOURCE_DIR}/data/stuff"
  DESTINATION ${INSTALL_DIR}/data
  )
1 Like

Thank you, I’m going to try