ChatGPT解决这个技术问题 Extra ChatGPT

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

So I've got a library I'm compiling and I need to link different third party things in depending on if it's the debug or release build (specifically the release or debug versions of those libraries). Is there an easy way to do this in Cmake?

Edit: I should note I'm using visual studio


M
Mike Willekes

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)

I do this all the time, even more compactly on one line: target_link_libraries(MyEXE debug 3PDebugLib optimized 3PReleaseLib)
What if the library name is the same, but you want visual studio to look for it at a different path? i.e. I want to link mylib.lib but I have two versions of it compiled. one under /path/Debug/mylib.lib and another under /path/Release/mylib.lib (as is often the case with some libraries). What do you do then?
If you want "Release" as in VS 2010 then you need to specify "Release" instead of "optimized" for target_link_libraries. Note that this is case-sensitive. Also you can check for "Release" in your cmake like that: IF(CMAKE_BUILD_TYPE MATCHES Release) again case sensitive.
You should not test CMAKE_BUILD_TYPE in the CMake file, it is ignored by multi configuration generators (like VS). If you run cmake with CMAKE_BUILD_TYPE=Debug but Release in VS the code in if(CMAKE_BUILD_TYPE MATCHES Release) is simply ineffective.
It's adding both the debug and release libs when trying the above in my project...
C
Community

Somehow the answer from @Mike Willekes got CMake linking in the same target both release and debug for me :(

I only got this working by setting both configurations in one line, as suggested by @sakra in a related question - and doing so for every library that needed to be linked:

target_link_libraries ( app
    debug ${Boost_FILESYSTEM_LIBRARY_DEBUG}
    optimized ${Boost_FILESYSTEM_LIBRARY_RELEASE} )

target_link_libraries ( app
    debug ${Boost_LOG_LIBRARY_DEBUG}
    optimized ${Boost_LOG_LIBRARY_RELEASE} )

target_link_libraries ( app
    debug ${Boost_PROGRAM_OPTIONS_LIBRARY_DEBUG}
    optimized ${Boost_PROGRAM_OPTIONS_LIBRARY_RELEASE} )

# ...

Ah, this is what was happening to me! We only want to link a particular library in release mode, so your method didn't work. In the end I worked around it by using something like the following: if (CMAKE_BUILD_TYPE STREQUAL "Release") target_link_libraries(${ARG_NAME} ${LIB_TCMALLOC} ) endif()
The drawback, @SteveLorimer, is that in multi config generators - such as for Visual Studio - this would not work as it is done in generate time.
not sure I understand? We don't link tcmalloc in debug builds. We do link tcmalloc in release builds. That is, there isn't a debug version of tcmalloc, so listing it under optimized only results in it getting linked into debug builds as well
That's strange, @SteveLorimer. Looking into CMake's docs it's stated that: "The debug keyword corresponds to the Debug configuration (...). The optimized keyword corresponds to all other configurations." (cmake.org/cmake/help/v3.0/command/target_link_libraries.html) What I was saying about multi configuration generators is that the check you put only will work if you generate the project in two separate directories, one for release, the other for debug. In MSVC builds, it makes sense sometimes to have only one generated directory with the possibility of release and debug builds.
Ah ok, I see. Well I definitely used optimized for the tcmalloc library and it ended up in our debug builds. We use makefiles though... so not sure about VS
a
akaltar

I would like to add a few notes to the previous answers.

If you need to create a list of multiple files you want to link and store that in a cache variable then you need to add the optimized or debug specified before each and every library. This can be especially useful for larger makefiles/projects.

So for example you could do something like this:

set( MyFavLib_LIBRARIES 
    debug debug/module1.lib optimized release/module1.lib
    debug debug/module2.lib optimized release/module2.lib )
target_link_libraries( app ${MyFavLib_LIBRARIES} )

K
Konrad

What worked for me was to use $(Configuration) macro in a lib path provided to cmake.

So, assuming libs are stored in separate, correctly named folders, e.g.:

C:\boost\lib\Debug\libfoo.lib
C:\boost\lib\Release\libfoo.lib

You can then call cmake with:

cmake -G "Visual Studio 10 2010" -DBOOST_LIBRARYDIR=C:\boost\lib\$(Configuration)\libfoo.lib

That'll generate .vcxproj with Additional Dependencies including C:\boost\lib\$(Configuration)\libfoo.lib, what is evaluated to either C:\boost\lib\Release\libfoo.lib or C:\boost\lib\Debug\libfoo.lib depending on a chosen Configuration.


关注公众号,不定期副业成功案例分享
Follow WeChat

Success story sharing

Want to stay one step ahead of the latest teleworks?

Subscribe Now