find_package 用于静态库而不是共享库

Rhe*_*eel 11 cmake static-linking

当使用 CMake 构建我的项目时,我希望它静态链接到库(如果可用)。现在,.dll.a无论文件是否存在,它都会查找.a文件。

例如,在一个小示例项目中链接到 libpng:

cmake_minimum_required(VERSION 3.15)
project(Test)

add_executable(Test main.cpp)

find_package(PNG REQUIRED)
message(${PNG_LIBRARIES})
target_link_libraries(Test PRIVATE ${PNG_LIBRARIES})
Run Code Online (Sandbox Code Playgroud)

对于message,它输出

C:/msys64/mingw64/lib/libpng.dll.aC:/msys64/mingw64/lib/libz.dll.a

libpng.alibz.a文件也可以在同一目录中使用。我如何告诉 CMake 链接.a文件?

我在 Windows 10 上使用 MinGW-w64 和 msys64,但更喜欢跨平台的解决方案。

Ale*_*ing 1

可悲的现实是静态与共享选择是在每个包(或模块)的基础上完成的。

对于提供配置文件的包,最可靠的方法是不构建您不需要的版本(例如,如果您想要的内容被共享,则不要构建静态库)。令人沮丧的是,许多项目坚持构建这两种类型。如果他们还有选择库类型的记录方法,那么您可以使用它,那么您很幸运。否则你将不得不求助于黑客。像 Conan 或 vcpkg 这样的包管理器将内置这些 hack。

对于查找模块,您必须再次查阅文档。在您的情况下,您使用的是 CMake 自己的 FindPNG 和 FindZLIB (PNG 依赖项)模块。在 CMake 3.24 之前,你只是运气不好,但从 3.24 开始,你可以向 ZLIB 暗示它应该更喜欢静态库,如下所示:

option(ZLIB_USE_STATIC_LIBS "" ON)
find_package(PNG REQUIRED)
Run Code Online (Sandbox Code Playgroud)

但是对于 PNG 该怎么办呢?好吧,看看源代码,你仍然不走运。他们在搜索共享库之后对静态库的搜索进行了硬编码。也许你可以用PNG_NAMES模块没有正确重置的变量来破解它?

否则,您将从PNG_LIBRARY{,_DEBUG,_RELEASE}工具链文件中进行设置