You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为树莓派交叉编译odas库时出现未定义引用链接错误求助

树莓派交叉编译ODAS库时出现链接错误

我正尝试为树莓派交叉编译ODAS库(该库可直接在树莓派或Ubuntu平台构建),使用以下CMake工具链文件时:

# Cross-compilation system information
SET(CMAKE_SYSTEM_NAME Linux)
SET(CMAKE_SYSTEM_VERSION 1)

set(CMAKE_SYSTEM_PROCESSOR "arm")
# Specify the cross compiler
SET(CMAKE_C_COMPILER /home/raspberrypi/opt/x-tools/aarch64-rpi3-linux-gnu/bin/aarch64-rpi3-linux-gnu-gcc)
SET(CMAKE_CXX_COMPILER /home/raspberrypi/opt/x-tools/aarch64-rpi3-linux-gnu/bin/aarch64-rpi3-linux-gnu-g++)

# where is the target environment located
set(CMAKE_SYSROOT /home/raspberrypi/sysroot)
set(CMAKE_FIND_ROOT_PATH ${CMAKE_SYSROOT})

SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} --sysroot=${CMAKE_FIND_ROOT_PATH}")
SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} --sysroot=${CMAKE_FIND_ROOT_PATH}")
SET(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} --sysroot=${CMAKE_FIND_ROOT_PATH}")


# adjust the default behavior of the FIND_XXX() commands:
# search programs in the host environment
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)

# search headers and libraries in the target environment
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)

出现了一系列链接错误,例如:

[1/2] Linking C executable bin/odasserver
FAILED: bin/odasserver 
: && /home/raspberrypi/opt/x-tools/aarch64-rpi3-linux-gnu/bin/aarch64-rpi3-linux-gnu-gcc --sysroot=/home/raspberrypi/sysroot -g --sysroot=/home/raspberrypi/sysroot CMakeFiles/odasserver.dir/demo/odasserver/main.obj -o bin/odasserver  lib/libodas.so  -lfftw3f  -lasound  -lconfig  -lpulse-simple  -lpulse  -lm  -lpthread && :
/home/raspberrypi/opt/x-tools/aarch64-rpi3-linux-gnu/bin/../lib/gcc/aarch64-rpi3-linux-gnu/12.2.0/../../../../aarch64-rpi3-linux-gnu/bin/ld.bfd: lib/libodas.so: undefined reference to `__pthread_create'
/home/raspberrypi/opt/x-tools/aarch64-rpi3-linux-gnu/bin/../lib/gcc/aarch64-rpi3-linux-gnu/12.2.0/../../../../aarch64-rpi3-linux-gnu/bin/ld.bfd: lib/libodas.so: undefined reference to `_dl_wait_lookup_done'
/home/raspberrypi/opt/x-tools/aarch64-rpi3-linux-gnu/bin/../lib/gcc/aarch64-rpi3-linux-gnu/12.2.0/../../../../aarch64-rpi3-linux-gnu/bin/ld.bfd: lib/libodas.so: undefined reference to `_dl_init_static_tls'
/home/raspberrypi/opt/x-tools/aarch64-rpi3-linux-gnu/bin/../lib/gcc/aarch64-rpi3-linux-gnu/12.2.0/../../../../aarch64-rpi3-linux-gnu/bin/ld.bfd: lib/libodas.so: undefined reference to `__pointer_chk_guard_local'
/home/raspberrypi/opt/x-tools/aarch64-rpi3-linux-gnu/bin/../lib/gcc/aarch64-rpi3-linux-gnu/12.2.0/../../../../aarch64-rpi3-linux-gnu/bin/ld.bfd: lib/libodas.so: undefined reference to `_dl_stack_flags'
/home/raspberrypi/opt/x-tools/aarch64-rpi3-linux-gnu/bin/../lib/gcc/aarch64-rpi3-linux-gnu/12.2.0/../../../../aarch64-rpi3-linux-gnu/bin/ld.bfd: lib/libodas.so: undefined reference to `_dl_pagesize'
collect2: error: ld returned 1 exit status

请问可能是什么原因导致的?


问题分析与解决建议

这些链接错误大多指向动态链接器(ld.so)和线程库的符号缺失,常见原因及修复方向如下:

1. Sysroot环境不完整或版本不匹配

你的sysroot目录/home/raspberrypi/sysroot可能缺少树莓派系统的核心库文件(比如libc.so、libpthread.so),或者库文件版本与交叉编译器的版本不兼容。动态链接器相关的符号(如_dl_*系列)属于glibc的一部分,若sysroot里的glibc和交叉编译器自带的glibc版本不一致,就会出现符号找不到的问题。

解决办法:

  • 重新从树莓派设备上完整拷贝sysroot,确保包含/lib、/usr/lib下的所有库文件和头文件。可以用rsync命令同步:
    rsync -avz --rsync-path='sudo rsync' pi@<树莓派IP>:/{lib,usr} /home/raspberrypi/sysroot/
    
  • 检查交叉编译器的glibc版本,确保sysroot中的glibc版本与之匹配。

2. 工具链文件中处理器架构设置错误

你指定的CMAKE_SYSTEM_PROCESSOR是arm,但交叉编译器是针对aarch64-rpi3-linux-gnu(64位ARM架构),架构标识不匹配可能导致CMake查找库时出现偏差。

解决办法:
将工具链文件中的set(CMAKE_SYSTEM_PROCESSOR "arm")改为:

set(CMAKE_SYSTEM_PROCESSOR "aarch64")

3. 链接库顺序或参数缺失

链接命令中虽然加了-lpthread,但可能位置不对(应放在依赖它的库之后),或者缺少glibc相关的链接参数。另外,__pointer_chk_guard_local这类符号和栈保护机制有关,需确保编译时的CFLAGS包含正确参数。

解决办法:

  • 在工具链文件中添加编译和链接的通用参数,确保开启正确的栈保护并链接必要的库:
    set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fstack-protector-strong")
    set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} --sysroot=${CMAKE_FIND_ROOT_PATH} -Wl,--no-undefined")
    
  • 调整链接库的顺序,将-lpthread移到lib/libodas.so之后(CMake通常会自动处理,但手动指定时需注意)。

4. 交叉编译器配置问题

如果你的交叉编译器是自行编译的,可能存在配置错误,比如未正确指定目标系统的glibc路径。

解决办法:

  • 使用树莓派官方提供的交叉编译器,或确保编译交叉编译器时正确指定--with-sysroot参数指向你的树莓派sysroot。

内容的提问来源于stack exchange,提问作者user2109066

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.01 11:15:38