ChatGPT解决这个技术问题 Extra ChatGPT

在 Windows 上的 Cmake 中为调试和发布版本链接不同的库?

所以我有一个正在编译的库,我需要链接不同的第三方内容,具体取决于它是调试版本还是发布版本(特别是这些库的发布版本或调试版本)。在 Cmake 中是否有一种简单的方法可以做到这一点?

编辑:我应该注意我正在使用视觉工作室


M
Mike Willekes

根据CMake documentation

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

“debug”、“optimized”或“general”关键字表示紧随其后的库仅用于相应的构建配置。

所以你应该能够做到这一点:

add_executable( MyEXE ${SOURCES})

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

我一直这样做,更简洁地写在一行上:target_link_libraries(MyEXE debug 3PDebugLib optimize 3PReleaseLib)
如果库名称相同,但您希望 Visual Studio 在不同的路径中查找它怎么办?即我想链接 mylib.lib 但我编译了它的两个版本。一个在 /path/Debug/mylib.lib 下,另一个在 /path/Release/mylib.lib 下(某些库经常出现这种情况)。那你怎么办呢?
如果您想要 VS 2010 中的“发布”,那么您需要为 target_link_libraries 指定“发布”而不是“优化”。请注意,这是区分大小写的。您也可以像这样在 cmake 中检查“Release”:IF(CMAKE_BUILD_TYPE MATCHES Release) 再次区分大小写。
您不应该在 CMake 文件中测试 CMAKE_BUILD_TYPE,它会被多配置生成器(如 VS)忽略。如果您使用 CMAKE_BUILD_TYPE=Debug 运行 cmake 但在 VS 中发布,则 if(CMAKE_BUILD_TYPE MATCHES Release) 中的代码根本无效。
在我的项目中尝试上述操作时,它同时添加了调试和发布库......
C
Community

不知何故,@Mike Willekes 的答案让 CMake 在同一个目标中链接了我的发布和调试:(

正如@sakra in a related question 所建议的那样,我只能通过在一行中设置两个配置来实现这一点 - 并对需要链接的每个库都这样做:

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} )

# ...

啊,这就是发生在我身上的事!我们只想在发布模式下链接一个特定的库,所以你的方法不起作用。最后,我使用以下方法解决了这个问题:if (CMAKE_BUILD_TYPE STREQUAL "Release") target_link_libraries(${ARG_NAME} ${LIB_TCMALLOC} ) endif()
@SteveLorimer 的缺点是,在多配置生成器中 - 例如对于 Visual Studio - 这将不起作用,因为它是在生成时完成的。
不知道我明白吗?我们不在调试版本中链接 tcmalloc。我们在发布版本中链接 tcmalloc。也就是说,没有 tcmalloc 的调试版本,因此在优化下列出它只会导致它也链接到调试版本
这很奇怪,@SteveLorimer。查看 CMake 的文档时指出:“debug 关键字对应于 Debug 配置 (...)。optimized 关键字对应于所有其他配置。” (cmake.org/cmake/help/v3.0/command/target_link_libraries.html) 关于多配置生成器,我所说的是,只有当您在两个单独的目录中生成项目时,您所做的检查才会起作用,一个用于发布,另一个用于调试。在 MSVC 构建中,有时只有一个生成的目录具有发布和调试构建的可能性是有意义的。
啊,好的,我明白了。好吧,我肯定将 optimized 用于 tcmalloc 库,它最终出现在我们的调试版本中。虽然我们使用makefile......所以不确定VS
a
akaltar

我想在前面的答案中添加一些注释。

如果您需要创建要链接的多个文件的列表并将其存储在缓存变量中,则需要在每个库之前添加指定的 optimizeddebug。这对于较大的生成文件/项目特别有用。

因此,例如,您可以执行以下操作:

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

对我有用的是在提供给 cmake 的 lib 路径中使用 $(Configuration) 宏。

因此,假设库存储在单独的、正确命名的文件夹中,例如:

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

然后,您可以使用以下命令调用 cmake:

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

这将生成带有附加依赖项的 .vcxproj,包括 C:\boost\lib\$(Configuration)\libfoo.lib,根据所选配置评估为 C:\boost\lib\Release\libfoo.libC:\boost\lib\Debug\libfoo.lib 的内容。


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

不定期副业成功案例分享

领先一步获取最新的外包任务吗?

立即订阅