Debug and Release Library Linking with Cmake (Visual Studio)

Linking different libraries for Debug and Release builds in Cmake on windows?

According to the CMake documentation:

target_link_libraries(<target> [lib1 [lib2 [...]]] [[debug|optimized|general] <lib>] ...)

A "debug", "optimized", or "general"
keyword indicates that the library
immediately following it is to be used
only for the corresponding build
configuration.

So you should be able to do this:

add_executable( MyEXE ${SOURCES})

target_link_libraries( MyEXE debug 3PDebugLib)
target_link_libraries( MyEXE optimized 3PReleaseLib)

Debug and Release Library Linking with CMAKE (VISUAL STUDIO)

There is no problems when your library is a part of the project or you're
importing it using config mode of find_package command (see documentation and example).
In case you can't modify 3rd party so it will produce <package>Config.cmake
(it may not use cmake tool or you don't want to do it) the answer is to emulate
such process:

add_library(foo STATIC IMPORTED)
set_target_properties(foo PROPERTIES IMPORTED_LOCATION_DEBUG "/path/to/foo-d.lib")
set_target_properties(foo PROPERTIES IMPORTED_LOCATION_RELEASE "/path/to/foo.lib")

target_link_libraries(MyEXE foo)

note that unlike "debug"/"optimized" feature such approach is not limited to Debug/Release configs:

set_target_properties(foo PROPERTIES IMPORTED_LOCATION_MINSIZEREL "/path/to/foo-small.lib")

also you've got some goodies like INTERFACE_INCLUDE_DIRECTORIES:

set_target_properties(foo PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "/path/to/foo/includes")

include_directories("/path/to/foo/includes") # this line not needed
target_link_libraries(MyEXE foo) # this command will add "/path/to/foo/includes" for you

and transitive linking:

add_library(boo STATIC IMPORTED)
set_target_properties(boo PROPERTIES IMPORTED_LOCATION_DEBUG "/path/to/boo-d.lib")
set_target_properties(boo PROPERTIES IMPORTED_LOCATION_RELEASE "/path/to/boo.lib")

add_library(foo STATIC IMPORTED)
set_target_properties(foo PROPERTIES IMPORTED_LOCATION_DEBUG "/path/to/foo-d.lib")
set_target_properties(foo PROPERTIES IMPORTED_LOCATION_RELEASE "/path/to/foo.lib")

set_target_properties(foo PROPERTIES INTERFACE_LINK_LIBRARIES boo) # foo depends on boo

target_link_libraries(MyEXE foo) # boo will be linked automatically

Of course you can use regular cmake commands like find_library and find_package(... MODULE) to estimate locations instead of hardcoding them.

Force linking against Python release library in debug mode in Windows/Visual Studio from CMake

It seems that set(Python_FIND_ABI "OFF" "ANY" "ANY") as suggested in the comments by kanstar would be the correct way to do this. However, while Python_FIND_ABI is in CMake master, it hasn't been released yet in the latest version (v3.15.2 as of this writing).

In the meantime, there are solutions dependent on the CMake version.

CMake 3.12 and above

It's possible to link against FindPython's Python_LIBRARY_RELEASE, which isn't meant to be part of the module's public interface, but the variable is set correctly nonetheless.

cmake_minimum_required (VERSION 3.12)
find_package(Python ..<choose your COMPONENTS; refer to FindPython docs>..)
if(WIN32 AND MSVC)
target_link_libraries(my_python_module ${Python_LIBRARY_RELEASE})
endif()

CMake 3.0.4 to 3.11

Thanks to a comment by @Phil, we can expand the answer to include earlier CMake versions which had the FindPythonLibs module that sets the PYTHON_LIBRARY_RELEASE variable instead.

cmake_minimum_required (VERSION 3.0)
find_package(PythonLibs ..<refer to FindPythonLibs docs>..)
if(WIN32 AND MSVC)
target_link_libraries(my_python_module ${PYTHON_LIBRARY_RELEASE})
endif()

Specifying different libraries for Debug & Release mode

The target_link_libraries command supports "debug" and "optimized" keywords, which indicate that the library immediately following it is to be used only for the corresponding build configuration:

target_link_libraries(MyTarget debug externalLib_d optimized externalLib)

If the debug and release libraries reside in different directories, specify the full path, i.e.:

target_link_libraries(MyTarget debug "debug_dir/externalLib_d" optimized "release_dir/externalLib")

Also see the target_link_libraries command documentation.

CMake - Linking different libraries for Debug and Release builds with variable from find_package

Use a loop:

foreach (_lib ${Cairomm_LIBRARIES})
target_link_libraries(Paint debug ${_lib})
endforeach()

CMake conditional for Release,Debug and Etc

Variable CMAKE_BUILD_TYPE has no sense with multiconfiguration generators, and Visual Studio is one of such generators.

Canonical way for define in CMake a pre-built library which have different locations for different configuration is to create IMPORTED library target with several properties IMPORTED_LOCATION_<CONFIG> to be set:

add_library(thirdPartyLib IMPORTED UNKNOWN)
set_target_properties(thirdPartyLib PROPERTIES
IMPORTED_LOCATION_RELEASE
${CMAKE_CURRENT_SOURCE_DIR}/external_libs/mylibalpha/win64/release/libalpha.a
IMPORTED_LOCATION_DEBUG
${CMAKE_CURRENT_SOURCE_DIR}/external_libs/mylibalpha/win64/debug/libalpha.a
)

Then you need to create a mapping between build types of the main project and build types of the IMPORTED target.

Such mapping could be created either on per-target basis, by setting properties MAP_IMPORTED_CONFIG_<CONFIG>:

set_target_properties(thirdPartyLib PROPERTIES
# For Debug version of the project use DEBUG-suffixed library location
MAP_IMPORTED_CONFIG_DEBUG DEBUG
# For Release version of the project use RELEASE-suffixed library location
MAP_IMPORTED_CONFIG_RELEASE RELEASE
# For ReleaseWithDebInfo version of the project use DEBUG-suffixed library location
MAP_IMPORTED_CONFIG_RELWITHDEBINFO DEBUG
# For MinSizeRel version of the project use RELEASE-suffixed library location
MAP_IMPORTED_CONFIG_MINSIZEREL RELEASE
)

Alternatively, the mapping could be created for all IMPORTED targets by setting variables CMAKE_MAP_IMPORTED_CONFIG_<CONFIG>. Note, that these variables should be set before creation of IMPORTED target(s).

# For Debug version of the project use DEBUG-suffixed locations of IMPORTED targets
set(CMAKE_MAP_IMPORTED_CONFIG_DEBUG DEBUG)
# For Release version of the project use RELEASE-suffixed locations of IMPORTED targets
set(CMAKE_MAP_IMPORTED_CONFIG_RELEASE RELEASE)
# For ReleaseWithDebInfo version of the project use DEBUG-suffixed locations of IMPORTED targets
set(CMAKE_MAP_IMPORTED_CONFIG_RELWITHDEBINFO DEBUG)
# For MinSizeRel version of the project use RELEASE-suffixed locations of IMPORTED targets
set(CMAKE_MAP_IMPORTED_CONFIG_MINSIZEREL RELEASE)

Having IMPORTED libraries and configurations mapping, using these libraries is quite straightforward:

target_link_libraries(my_exe PRIVATE thirdPartyLib)

Depending on the build type of the project, CMake will automatically select proper library for linking.

Linking against a debug version of a library with CMake

You should not rename the file manually. Use CMake's CMAKE_DEBUG_POSTFIX variable or the DEBUG_POSTFIX target property instead:

add_library(myLib SHARED ${SOURCES})
set_target_properties(mylib PROPERTIES DEBUG_POSTFIX "d")

[...]
add_executable(myApp WIN32 ${SOURCES})
target_link_libraries(myApp myLib)


Related Topics



Leave a reply



Submit