使用Visual Studio同时查找debug和release的find_package

6

我正在为如何在我的cmake项目中包含第三方库而苦恼。目前,我构建了Poco和一堆其他库,它们都生成了各自的Config.cmake文件,我使用这些文件与find_package一起使用。我有一个封装的构建脚本,它构建了我所有的依赖项,并将它们分别打包为调试和发布版本(除非我真的需要进行维护,否则我不想调整它们的cmake脚本)。

我以为我可以只需执行:

find_package(Foo
            HINTS "${CMAKE_SOURCE_DIR}/some/path/debug/libFoo/lib/cmake"
            REQUIRED
)
get_target_property(LIB_FOO_DEBUG lib_foo LOCATION)

find_package(Foo
            HINTS "${CMAKE_SOURCE_DIR}/some/path/release/libFoo/lib/cmake"
            REQUIRED
)
get_target_property(LIB_FOO_RELEASE lib_foo LOCATION)

set(LIB_FOO_LIBRARIES optimized "${LIB_FOO_RELEASE}" debug "${LIB_FOO_DEBUG}")

message("LIB_FOO_LIBRARIES: \"${LIB_FOO_LIBRARIES}\"")

这将产生:LIB_FOO_LIBRARIES: "optimized;C:/path/to/proj/some/path/debug/libFoo/lib/foo.lib;debug;C:/path/to/proj/some/path/debug/libFoo/lib/foo.lib" 似乎第一次针对目标Foo调用find_package已被缓存,这并不是我想要的。
我是不是走错了路?如何正确地使用Visual Studio生成器处理第三方库?
非常感谢任何指导。
1个回答

6
对于目标Foo的第一次find_package调用被缓存。因此,您不能两次发出find_package并获得不同的结果(除非第一次调用失败)。
多配置使用由第三方包负责,即它应该有正确编写的*Config.cmake/Find*.cmake文件。(例如,FindBoost.cmake支持多配置使用)。
否则,您需要进行一些技巧来以多配置方式使用包。
例如,如果您猜测配置之间唯一的区别是路径中的debug/release子字符串,则可以为debug安装调用find_package(),然后使用string(REPLACE)获取特定于release的路径:
find_package(Foo
        HINTS "${CMAKE_SOURCE_DIR}/some/path/debug/libFoo/lib/cmake"
        REQUIRED
)

get_target_property(LIB_FOO_DEBUG lib_foo LOCATION)
string(REPLACE debug release LIB_FOO_RELEASE ${LIB_FOO_DEBUG})

# Use generator expressions, so variable can be used not only by target_link_libraries.
set(LIB_FOO_LIBRARIES
        "$<$<NOT:$<CONFIG:DEBUG>>:${LIB_FOO_RELEASE}>"
        "$<$<CONFIG:DEBUG>:${LIB_FOO_DEBUG}>"
)

我目前正在使用你的第二个答案,它可以完成任务(虽然感觉有点 hacky)。你是否有建议如何正确生成一个 multiconfig *Config.cmake?如果不是太麻烦的话,我可能会走这条路,并向相关的库提交一个 pull request。 - JBarberU
2
我发现了这个package-example。它的“Foo”包可以作为导出包的示例,而且在多配置中正确工作。 - Tsyvarev

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