CMake:覆盖 target_link_libraries 添加的库

CMake: Override libraries added by target_link_libraries

所以我 运行 非常头疼用 CMake 构建我的软件。

我正在静态构建第三方库 (dlib),它需要 zlib 和 libpng(都是静态的,我预先构建了这些)库来支持 PNG 功能。 COTS dlib 库提供的 CMakeFile 正在做一个基本的:

target_link_libraries( dlib ${dlib_required_libs}) 

这会将其所有库配置为 "general" 库,最终用于发布和调试版本。

这在 Linux 中不是问题,但 Windows 有一个可爱的 "feature" 指定运行时库(/MT 或 /MD 或 /MTd 或 /MDd) .这些标志之间的任何不匹配都会在 link 时导致多个符号定义错误。即,如果 libpng 是使用 /MT 构建的,而我的软件使用的是 /MTd,它们将不兼容。

为了缓解这个问题,我构建了两个版本的 zlib 和 libpng。一组使用 /MT 标志用于发布版本,另一组使用 /MTd 用于调试版本。在使用它们的地方 target_link_libraries 上使用 optimized/debug 标志,这些愉快地 link 到我自己的软件中。但是,dlib(第 3 方)仅通过编写 CMakeFile 的方式 linking zlib 和 libpng 库的发布集。

我的主要问题是,有没有一种方法可以 'override' dlib 是什么 linking 而无需修改它提供的 CMakeFile? 我试图覆盖 dlib_LIB_DEPENDS 并出于绝望将其强制放入缓存,但无济于事。

Dlib 在 dlib/external 中附带了 libpng 和 zlib 的副本。默认情况下,dlib 的 CMakeLists.txt 将以正确的方式构建它们并将它们静态地 link 到您的程序中。所以解决方案是让它这样做。不要尝试创建一个单独的静态库,因为正如您所指出的,这会在 windows.

上造成很多麻烦

FindPNG.cmake 脚本,与 find_package() 使用的许多其他 Find*.cmake 脚本一样,不关心多配置构建。所以它只是搜索 单个库 ,而多配置构建自然需要 library-per-config.

为了使搜索到的 PNG 库成为每个配置文件,可以编写自己的 FindPNG.cmake 脚本(并设置 CMAKE_MODULE_PATH 以使用此脚本指向目录)。

但对于具体使用来说,重写原始脚本的输出更简单,即设置 PNG_LIBRARY 缓存变量指向 library-per-config:

optimized png-lib-release debug png-lib-debug

或者,使用生成器表达式,

$<$<CONFIG:Release>:png-lib-release>$<$<CONFIG:Debug>:png-lib-debug>`

(而不是 png-lib-releasepng-lib-debug 应该是发布和调试版本的路径图书馆相应地)。

这两个值都应与 target_link_libraries 命令一起使用, 生成每个配置的链接。