CMAKE(VISUAL STUDIO)下的调试和发布库链接

25

已经有一个线程,但没有真正帮助。我想能够链接例如Foo.libRelease配置,以及Foo_d.libDebug配置,我该怎么做?如果我这样做:

target_link_libraries(MyEXE debug Foo_d)
target_link_libraries(MyEXE optimized Foo)

那么在我的项目中,调试配置下我同时拥有这两个库?为什么没有发布选项?

非常感谢!

5个回答

30

target_link_libraries需要一个列表,你不需要调用它两次。以下代码可以正常工作:

target_link_libraries需要一个列表,你不需要调用它两次。以下会生效:

target_link_libraries(MyEXE debug Foo_d optimized Foo)

回答另一个答案评论中提出的问题,使用多个库的工作方式如下:

target_link_libraries(MyEXE
    debug Foo1_d optimized Foo1
    debug Foo2_d optimized Foo2)

请注意,如果您将该库作为CMake项目的一部分进行构建,则无需指定debug或optimized。 CMake会为您选择正确的一个。


这是我所见过的唯一一个指出必须根据每个库文件单独进行调试和优化的答案。 - jjxtra

25
解决方案是:
SET(LINK_LIBRARY optimized Foo debug Foo_d)
target_link_libraries(MyEXE ${LINK_LIBRARY})

1
我总是在预制模块中寻找解决方案。例如:在FindQt4.cmake中。 - Naszta
1
如果我有多个调试和发布库,这将如何工作呢?例如,我有_Foo1_d_,_Foo2_d_和_Foo1_,_Foo2_。如何将它们合并到单个变量下?目前它只能检测与第一个关联库(调试或发布)相关的关键字,并且不会识别下一个库。 - user1036908

22

当您的库是项目的一部分或者您使用find_package命令的配置模式导入它时(请参见文档示例),就不会出现问题。 如果您无法修改第三方库以便它生成<package>Config.cmake文件(可能不使用cmake工具或者您不想这样做),那么答案就是模拟这个过程:

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)

请注意,与“调试”/“优化”功能不同,这种方法不仅限于Debug/Release配置:
set_target_properties(foo PROPERTIES IMPORTED_LOCATION_MINSIZEREL "/path/to/foo-small.lib")

此外,您还有一些好东西,如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

以及传递性链接:

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

当然,您可以使用常规的cmake命令,如find_libraryfind_package(... MODULE)来估计位置,而不是硬编码它们。

我正在使用CMake 3.20,如果我不将IMPORTED_LOCATION设置为属性,则会收到以下警告: Policy CMP0111 is not set: An imported target missing its location property fails during generation. Run "cmake --help-policy CMP0111" for policy details. Use the cmake_policy command to set the policy and suppress this warning. IMPORTED_LOCATION not set for imported target "mytarget::mytarget" configuration "Debug". This warning is for project developers. Use -Wno-dev to suppress it. - Michael Ngarimu
根据使用set_library_configurations(mytarget)设置的mytarget_LIBRARY来设置IMPORTED_LOCATION,然后再次限制为优化/调试模式。它可在DEBUG和RELEASE配置下正常运行,但不如看起来那么灵活。 - Michael Ngarimu

8
如果您有遵循特定模式(如在调试库上使用“_d”)的调试/发布库,您可以使用以下代码避免重复:
set (MY_LIBS
    foo
    bar
    baz
)

# Generate the list of files to link, per flavor.
set (LINK_LIST "")
foreach(x ${MY_LIBS})
    list (APPEND LINK_LIST debug ${x}_d optimized ${x})
endforeach()

target_link_libraries (mytarget
    commonlib1
    commonlib2
    ${LINK_LIST}
    )

这将生成相应的代码。
debug foo_d optimized foo
debug bar_d optimized bar
< p >target_link_libraries 期望的行。


1

对于我的CMake 3.14.6版本,使用带有debug和optimized参数的target_link_libraries无法运行。 如果您遇到此问题,请尝试使用以下类型的代码:

set (FreeImage debug "FreeImageD" optimized "FreeImage")
set (Glog debug "glogd" optimized "glog")
set (EXTRA_LIBS ${FreeImage} ${Glog})
target_link_libraries(TexCompressor ${EXTRA_LIBS})

它只是将调试/优化对转换为变量定义。这对于我的版本有效。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接