CMake:在配置时按CMAKE_REQUIRED_LIBRARY中的库顺序测试最小程序
我编写了这段小代码,以确保我的软件在必要时可以链接到libatics。通常,只有在覆盆子PI上才需要链接到脂组学。目前,我使用的是Raspberry PI 4,64位Raspbian Bullseye。
以下是cmake代码:
set(ATOMIC32_TEST_CODE "
#include <atomic>
#include <stdint.h>
int main() {
std::atomic<int32_t> x;
x.store(1);
x--;
return x.load();
}")
set(ATOMIC64_TEST_CODE "
#include <atomic>
#include <stdint.h>
int main() {
std::atomic<int64_t> x;
x.store(1);
x--;
return x.load();
}")
macro(ATOMIC_CHECK)
# test whether atomic works
check_cxx_source_compiles("${ATOMIC32_TEST_CODE}" atomic32_test)
check_cxx_source_compiles("${ATOMIC64_TEST_CODE}" atomic64_test)
# if doesn't work, attempt to find the atomic library, link with it and try again
if(NOT atomic32_test OR NOT atomic64_test)
find_library(ATOMIC NAMES libatomic.so.1
HINTS
$ENV{HOME}/local/lib64
$ENV{HOME}/local/lib
/usr/local/lib64
/usr/local/lib
/opt/local/lib64
/opt/local/lib
/usr/lib64
/usr/lib
/lib64
/lib
/usr/lib/arm-linux-gnueabihf
)
if(ATOMIC)
set(LIBATOMIC ${ATOMIC})
message(STATUS "Found libatomic: ${LIBATOMIC}")
message(STATUS "Attempting to test atomic with atomic library linked")
get_filename_component(atomic_lib_dir ${LIBATOMIC} DIRECTORY)
# Before setting CMAKE_REQUIRED_FLAGS, we preserve the current state
cmake_push_check_state()
set(CMAKE_REQUIRED_LIBRARIES "-L${atomic_lib_dir} -latomic")
check_cxx_source_compiles("${ATOMIC32_TEST_CODE}" atomic32_test_with_atomic_linking)
check_cxx_source_compiles("${ATOMIC64_TEST_CODE}" atomic64_test_with_atomic_linking)
cmake_pop_check_state()
if(NOT atomic32_test_with_atomic_linking)
message(FATAL_ERROR "Even after linking with the atomic library, atomic 32-bit compilation failed.")
endif()
if(NOT atomic64_test_with_atomic_linking)
message(FATAL_ERROR "Even after linking with the atomic library, atomic 64-bit compilation failed.")
endif()
set(ATOMIC_LINKER_LIBS "-L${atomic_lib_dir} -latomic")
else()
message(FATAL_ERROR "Failed to find libatomic even though it seems to be required")
endif()
endif()
endmacro()
ATOMIC_CHECK()
此代码的作用如下:
- 尝试编译32位和64位版本的代码,并确保它们在退出时返回0。
- 如果它们中的任何一个没有编译,则查找libatics,如果找不到,则查找错误。
- 如果找到,请尝试链接到它并重新编译相同的小源代码
- 如果它们成功了,很好,我们将使用新找到的库作为编译其他一切的基础。如果不是,cmake配置将停止。
最近,我的PI上突然出现了链接错误。所以我调查了一下,结果我找到了this problem。
在CMakeError.log
中,我看到以下链接错误:
/usr/bin/c++ -Wall -Wextra -Wno-unused-variable -Wno-unused-function -Wno-unused-private-field -Wno-class-memacces>
/usr/bin/ld: CMakeFiles/cmTC_7285b.dir/src.cxx.o: in function `main':
src.cxx:(.text+0x40): undefined reference to `__atomic_store_8'
/usr/bin/ld: src.cxx:(.text+0x80): undefined reference to `__atomic_load_8'
/usr/bin/ld: CMakeFiles/cmTC_7285b.dir/src.cxx.o: in function `std::__atomic_base<long long>::operator--(int)':
src.cxx:(.text._ZNSt13__atomic_baseIxEmmEi[_ZNSt13__atomic_baseIxEmmEi]+0x40): undefined reference to `__atomic_fetch_s>
collect2: error: ld returned 1 exit status
最终,我发现唯一的问题是链接顺序。Cmake所要做的就是将-latomic
放在它试图编译的源文件之后。
如何告诉cmake将链接命令放在源文件之后,而不是放在它之前?
解决方案
正如其他地方有人指出的,改变
set(CMAKE_REQUIRED_LIBRARIES "-L${atomic_lib_dir} -latomic")
收件人:
set(CMAKE_REQUIRED_LIBRARIES "-L${atomic_lib_dir}" "-latomic")
已修复该问题。CMake显然可以识别前缀。
相关文章