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
Opencv Grouprectangles - Getting Grouped and Ungrouped Rectangles
Lambda Expression VS Functor in C++
Use of Typename Keyword with Template Function Parameters
How to Temporarily Disable a MACro Expansion in C/C++
How to Pass a C++ Lambda to a C-Callback That Expects a Function Pointer and a Context
Why Does the Size of a Class Depends on the Order of the Member Declaration? and How
C++11 Is_Same Type Trait for Templates
Visual Studio: Link:Fatal Error Lnk1181: Cannot Open Input File
What Does 'Using Std::Swap' Inside the Body of a Class Method Implementation Mean
Is It Safe to Use the "This" Pointer in an Initialization List
How to Safely Average Two Unsigned Ints in C++
Why Can't I Store References in a 'Std::Map' in C++
How to Initialize Static Members in the Header
One Way of Eliminating C4251 Warning When Using Stl-Classes in the Dll-Interface