CMake:检查静态 C++ 库的可用性

Posted

技术标签:

【中文标题】CMake:检查静态 C++ 库的可用性【英文标题】:CMake: check for availability of static C++ libraries 【发布时间】:2020-04-09 09:16:12 【问题描述】:

我正在尝试静态链接多线程二进制文件。如果 CMake 可以警告缺少静态库,那就太好了。

注意:我知道解决方案是安装静态库(Fedora 31 中的 libstdc++-static 和 glibc-static,如果这对任何人都有帮助的话),我只希望 CMake 报告丢失的库和不是在构建时。

(顺便说一句,有没有更好的方法来支持静态链接?目前我有一些平台相关的东西可以在我们的目标系统中支持它,我还没有发现任何更便携的东西......)

这是一个示例 CMakeLists.txt:

cmake_minimum_required(VERSION 3.17)

project(test)

set(CMAKE_CXX_STANDARD 17)

add_link_options(-static)
find_package(Threads REQUIRED)

add_executable(test)
target_link_libraries(test PRIVATE Threads::Threads)

target_sources(test PRIVATE test.cpp)

这是输出:

$ cmake ..
-- The C compiler identification is GNU 9.3.1
-- The CXX compiler identification is GNU 9.3.1
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc - works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ - works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Looking for pthread.h
-- Looking for pthread.h - found
-- Performing Test CMAKE_HAVE_LIBC_PTHREAD
-- Performing Test CMAKE_HAVE_LIBC_PTHREAD - Failed
-- Looking for pthread_create in pthreads
-- Looking for pthread_create in pthreads - not found
-- Looking for pthread_create in pthread
-- Looking for pthread_create in pthread - found
-- Found Threads: TRUE  
-- Configuring done
-- Generating done
-- Build files have been written to: /home/sergio/src/static_cmake/build
$ make
Scanning dependencies of target test
[ 50%] Linking CXX executable test
/usr/bin/ld: cannot find -lpthread
/usr/bin/ld: cannot find -lstdc++
/usr/bin/ld: cannot find -lm
/usr/bin/ld: cannot find -lc
collect2: error: ld returned 1 exit status
make[2]: *** [CMakeFiles/test.dir/build.make:101: test] Error 1
make[1]: *** [CMakeFiles/Makefile2:93: CMakeFiles/test.dir/all] Error 2
make: *** [Makefile:101: all] Error 2

【问题讨论】:

find_library(libpthread.a)? 【参考方案1】:

正如所评论的,在 CMake 中(在编译/链接之前)为缺少的库产生错误的一种方法是使用 find_library()。如果CMake找不到具体的库,使用库变量时会报错:

# Define a variable my_pthread_static_lib to store the library, if found.
find_library(my_pthread_static_lib libpthread.a)

add_executable(test)
# Error will occur here during CMake configuration, if not found
target_link_libraries(test PRIVATE $my_pthread_static_lib)

如果找不到my_pthread_static_lib库,就会出现这个错误:

CMake Error: The following variables are used in this project, but they are set to NOTFOUND.
Please set them or make sure they are set and tested correctly in the CMake files:
my_pthread_static_lib
    linked by target "test" in directory /path/to/CMake/file

【讨论】:

谢谢。所以似乎没有任何可移植的方式来做到这一点...... @SergioLosilla 我认为这取决于图书馆。可能有一些库XXX,其中find_package(XXX ...) 调用为静态库提供了一个单独 导入目标(例如XXX::XXX_static)。在这种情况下,您可以简单地使用 target_link_libraries() 中提供的目标 XXX::XXX_static 来检查库是否存在。 在这种特殊情况下,问题有两个方面:FindThreads 似乎没有提供这一点,并且 C++ 标准/运行时库不需要特定的 find_package 调用。

以上是关于CMake:检查静态 C++ 库的可用性的主要内容,如果未能解决你的问题,请参考以下文章

iOS合并lib(.a)库的可用方法(可用于解决duplicate symbol静态库冲突)

在现代CMake项目中存档静态依赖项

从父 cmake 动态/静态库构建 cmake 静态库的最佳方法

C++ 为啥 Traits 在对象上不可用,而是作为静态成员变量可用

使用cmake构建静态库的静态库

静态库与动态库的简单说明