我试图将我的项目链接到我开发的外部库,其中也使用CMake构建。当我尝试像这样找到RelWithDebInfo或MinSizeRel时:
FIND_LIBRARY(PCM_LIBRARY_DEBUG pcm
PATHS @CMAKE_LIBRARY_OUTPUT_DIRECTORY@
@CMAKE_LIBRARY_OUTPUT_DIRECTORY@/Debug
NO_DEFAULT_PATH
)
FIND_LIBRARY(PCM_LIBRARY_RELEASE pcm
PATHS @CMAKE_LIBRARY_OUTPUT_DIRECTORY@
@CMAKE_LIBRARY_OUTPUT_DIRECTORY@/Release
@CMAKE_LIBRARY_OUTPUT_DIRECTORY@/MinSizeRel
@CMAKE_LIBRARY_OUTPUT_DIRECTORY@/RelWithDebInfo
NO_DEFAULT_PATH
)
SET(PCM_LIBRARIES debug ${PCM_LIBRARY_DEBUG} optimized ${PCM_LIBRARY_RELEASE})
它不会搜索非Release或Debug的ather目录。我也尝试创建PCM_LIBRARY_RELWITHDEBINFO和PCM_LIBRARY_MINSIZEREL,但同样的事情发生,因为SET中只有调试和优化的前缀。任何人都知道如何链接正确的库?
答案 0 :(得分:6)
遗憾的是,这是使用find_library
的缺点之一。如果不引入大量的样板代码,就没有简单的方法。
这里的问题是,当将文件作为依赖项传递给target_link_libraries
时,您只能区分debug
和optimized
。如果需要更细粒度的控制,则必须直接操作相应的目标属性,如LINK_INTERFACE_LIBRARIES
。这不仅非常麻烦,还需要详细了解CMake物业系统的内部运作。
幸运的是,还有另一种方法:上述限制仅适用于通过文件名指定依赖关系。将它们指定为目标时,不会发生此问题。最明显的例子是,库和依赖它的可执行文件是从同一个源构建的:
add_library(foo_lib some_files.cpp)
add_executable(bar_exe more_files.cpp)
target_link_libraries(bar_exe foo_lib)
这“正常”。将为每个构建配置选择正确的库。如果库和可执行文件存在于不同的独立项目中,事情会变得复杂一些。在这种情况下,除了二进制文件之外,库还必须提供configure file with an exported target。
而不是调用find_library
来定位二进制文件,依赖可执行文件现在只加载该配置文件,然后可以使用导入的目标,就像它是来自同一项目的目标一样。
许多现代图书馆已经使用这种方法而不是传统的find_library
技术(Qt5是一个突出的例子)。因此,如果您可以随意更改依赖关系的CMakeLists,并且不需要支持非常旧的CMake版本(< 2.6),那么这可能是最佳选择。