I am trying to figure out how to copy some libs depending on the config in cmake.
I tried this:
add_custom_command(TARGET Myapp
POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_if_different
$<$<CONFIG:Debug>:${_LIBS_DEBUG}>
$<$<CONFIG:Release>:${_LIBS_RELEASE}>
$<TARGET_FILE_DIR:MyApp>)
It copies libs in Debug but not in release:
- Is this supposed to be legal and should work?
- If it is not legal (I do not get error), how can I achieve the same effect?
Turning my comments into an answer
What I normally do to debug those case is to add another COMMAND
before the actual line in question that just echos the command line. In your case:
COMMAND ${CMAKE_COMMAND} -E echo
$<$<CONFIG:Debug>:${_LIBS_DEBUG}>
$<$<CONFIG:Release>:${_LIBS_RELEASE}>
I've run this a few tests and you will see that the $<1:...>
and $<0:...>
expressions are not evaluated.
So seeing this I was searching CMake's bug tracker database and this is a known issue and yet (as for CMake 3.5.2) unresolved: 0009974: CMake should support custom commands that can vary by configuration.
There are several ways proposed in this ticket that do work with existing versions of CMake.
In your case - until this issue is resolved and if you want to have it shell independent - I would do it the "old way" and call a CMake script:
CopyLibsByConfig.cmake.in
if (_CONFIG STREQUAL "Debug")
file(COPY @_LIBS_DEBUG@ DESTINATION "${_DEST_PATH}")
else()
file(COPY @_LIBS_RELEASE@ DESTINATION "${_DEST_PATH}")
endif()
CMakeLists.txt
...
configure_file(CopyLibsByConfig.cmake.in CopyLibsByConfig.cmake @ONLY)
add_custom_command(TARGET MyApp
POST_BUILD
COMMAND ${CMAKE_COMMAND}
-D _CONFIG=$<CONFIG>
-D _DEST_PATH="$<TARGET_FILE_DIR:MyApp>"
-P "${CMAKE_CURRENT_BINARY_DIR}/CopyLibsByConfig.cmake"
)
But the solution can very much depend on the files you want to copy to your binary output folder. And there are a lot of way doing it, like using install()
:
install(FILES ${_LIBS_DEBUG} CONFIGURATIONS Debug DESTINATION $<TARGET_FILE_DIR:MyApp>)
install(FILES ${_LIBS_RELEASE} CONFIGURATIONS Release DESTINATION $<TARGET_FILE_DIR:MyApp>)
set(CMAKE_VS_INCLUDE_INSTALL_TO_DEFAULT_BUILD 1)
Obviously that's not the way install()
is meant to be used, so consider using the INSTALL
or PACKAGE
targets properly to distribute your application and all its dependencies.
And if we are talking about Visual Studio runtime DLLs you most likely want to take a look at the InstallRequiredSystemLibraries CMake module.