c++visual-studiovisual-studio-2010visual-studio-2012cmake

How to get current configuration (Release/Debug) in CMake for Visual Studio


I am on Visual Studio 2013, CMake 3.5.1, Windows 10. I am trying to copy some files via CMake like below:

file(COPY ${IMAGES} DESTINATION ${CMAKE_BINARY_DIR}/bin/Release)

Is it possible to replace "Release" with a variable that represents the configuration like:

file(COPY ${IMAGES} DESTINATION ${CMAKE_BINARY_DIR}/bin/${Variable})

I attempted

file(COPY ${IMAGES} DESTINATION ${CMAKE_BINARY_DIR}/bin/${CMAKE_BUILD_TYPE})

but CMAKE_BUILD_TYPE is an empty string when I use message to print it out, I also attempted

file(COPY ${IMAGES} DESTINATION ${CMAKE_BINARY_DIR}/bin/$<CONFIGURATION>)

but for some reason file command cannot decipher $<CONFIGURATION> whereas command like

add_custom_target(run COMMAND ${CMAKE_BINARY_DIR}/bin/$<CONFIGURATION>/Test.exe)

can. What is the right way to extract whether visual studio is currently built in Release or Debug in CMake?


Solution

  • The file command is executed during CMake runtime, not during build time (i.e. VS runtime).

    This also means, that the generator expressions (e.g. $<CONFIG>) can not be used, as these are evaluated during build time.
    (Hint: As long as there is no explicit reference to the use of generator expressions for a particular command in the CMake docu, they are not supported by that command).

    The reason, why ${CMAKE_BUILD_TYPE} is empty, is due to the reason that you probably haven't specified it on the invocation of CMake:

    cmake -DCMAKE_BUILD_TYPE=Debug ..
    

    However, using that, would mean that the build files are only generated for the Debug configuration. That's obviously not what you want.

    To solve your problem: Using generator expressions is the right way, as you've already figured out with the use of add_custom_target (or add_custom_command).

    You can use custom commands as dependencies for other "real" targets and you can specify post-/pre-build and pre-link commands for a specific target via add_custom_command.

    As the docu states for the COMMAND argument of add_custom_command:

    Arguments to COMMAND may use generator expressions. References to target names in generator expressions imply target-level dependencies, but NOT file-level dependencies. List target names with the DEPENDS option to add file-level dependencies.

    To copy a file after a successful build of a target:

    add_custom_command(TARGET myTarget POST_BUILD
                       COMMAND "${CMAKE_COMMAND}" -E copy_if_different "${IMAGE1}" "${CMAKE_BINARY_DIR}/bin/$<CONFIG>/"
                       COMMAND "${CMAKE_COMMAND}" -E copy_if_different "${IMAGE2}" "${CMAKE_BINARY_DIR}/bin/$<CONFIG>/"
    )