构建Aeron共享库静态链接libbsd.a时-fPIC错误的解决咨询
问题
构建Aeron media driver共享库时,需要静态链接依赖库libbsd.a,对原CMakeLists.txt做了如下修改:
add_library(libbsd STATIC IMPORTED) set_target_properties(libbsd PROPERTIES IMPORTED_LOCATION /usr/lib/x86_64-linux-gnu/libbsd.a) set_target_properties(libbsd PROPERTIES INTERFACE_INCLUDE_DIRECTORIES /usr/include) target_link_libraries( aeron_driver ${CMAKE_DL_LIBS} libbsd ${AERON_LIB_UUID_LIBS} ${AERON_LIB_M_LIBS} ${AERON_LIB_ATOMIC_LIBS} ${CMAKE_THREAD_LIBS_INIT} ${AERON_LIB_WINSOCK_LIBS})
但CMake链接阶段报错:
/usr/bin/ld: /usr/lib/x86_64-linux-gnu/libbsd.a(getentropy.o): relocation R_X86_64_PC32 against symbol `getentropy' can not be used when making a shared object; recompile with -fPIC /usr/bin/ld: final link failed: bad value collect2: error: ld returned 1 exit status
尝试给libbsd目标添加INTERFACE编译选项:
target_compile_options(libbsd INTERFACE -fPIC)
但错误依旧,询问如何正确设置编译标志,应该在aeron_driver还是libbsd目标上设置?
解决方案
这个错误的核心原因是:你使用的libbsd.a静态库没有用-fPIC编译,而链接到共享库(aeron_driver是共享库)时,所有参与链接的目标文件必须包含位置无关代码(PIC)。
你尝试的target_compile_options(libbsd INTERFACE -fPIC)无效,因为这个选项只会传递给依赖libbsd的目标(也就是aeron_driver)的编译阶段,但aeron_driver作为共享库应该已经启用了-fPIC——问题出在libbsd.a本身的二进制代码不包含PIC,无法通过后续的编译选项补救。
解决方法有两种:
1. 使用发行版提供的PIC版本静态库
部分Linux发行版(如Debian/Ubuntu)提供了预编译的PIC版本libbsd静态库,通常路径为/usr/lib/x86_64-linux-gnu/libbsd_pic.a,可通过安装libbsd-dev包获取(若包内未包含,需自行确认发行版的包管理信息)。
修改CMake配置,指向这个PIC版本的静态库:
set_target_properties(libbsd PROPERTIES IMPORTED_LOCATION /usr/lib/x86_64-linux-gnu/libbsd_pic.a)
2. 自行编译带-fPIC的libbsd
如果发行版没有提供PIC版本的静态库,需要自己编译libbsd源码并添加-fPIC选项:
- 克隆libbsd源码
- 编译时指定
-fPIC:mkdir build && cd build cmake -DCMAKE_C_FLAGS="-fPIC" .. make - 编译完成后,将生成的
libbsd.a路径替换到Aeron的CMake配置中。
内容的提问来源于stack exchange,提问作者Guillaume Paris
相关产品推荐
相关产品推荐

