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

交叉编译树莓派ODAS项目:CMAKE两种链接方式差异导致报错

交叉编译树莓派项目时,直接链接pthread/m库出现未定义引用错误

问题场景

我正在基于ODAS库交叉编译树莓派aarch64平台的音频项目,原CMake配置通过CMAKE_EXE_LINKER_FLAGS添加-lm -lpthread可以正常编译构建。但改成在target_link_libraries中直接声明m和pthread库后,链接阶段抛出大量未定义引用错误,涉及_dl_stack_flags、_dl_pagesize、__pointer_chk_guard_local等符号。

正常编译的CMake片段

SET(GCC_COVERAGE_LINK_FLAGS    "-lm -lpthread " )

# ... 其他配置省略 ...

target_link_libraries(${PROJECT_NAME}
    odas
    ${PC_FFTW3_LIBRARIES}
    ${PC_ALSA_LIBRARIES}
    ${PC_LIBCONFIG_LIBRARIES}
    ${PC_PULSEAUDIO_LIBRARIES}
#     m
#     pthread
   )

SET(CMAKE_EXE_LINKER_FLAGS  "${CMAKE_EXE_LINKER_FLAGS} ${GCC_COVERAGE_LINK_FLAGS}")

修改后报错的CMake片段

# SET(GCC_COVERAGE_LINK_FLAGS    "-lm -lpthread " )

# ... 其他配置省略 ...

target_link_libraries(${PROJECT_NAME}
    odas
    ${PC_FFTW3_LIBRARIES}
    ${PC_ALSA_LIBRARIES}
    ${PC_LIBCONFIG_LIBRARIES}
    ${PC_PULSEAUDIO_LIBRARIES}
    m
    pthread
   )

# SET(CMAKE_EXE_LINKER_FLAGS  "${CMAKE_EXE_LINKER_FLAGS} ${GCC_COVERAGE_LINK_FLAGS}")

核心报错信息

/opt/x-tools/aarch64-rpi3-linux-gnu/bin/../lib/gcc/aarch64-rpi3-linux-gnu/12.2.0/../../../../aarch64-rpi3-linux-gnu/bin/ld.bfd: /sysroot/lib/aarch64-linux-gnu/libpthread.a(pthread_create.o): in function `allocate_stack':
./nptl/allocatestack.c:525: undefined reference to `_dl_stack_flags'
/opt/x-tools/aarch64-rpi3-linux-gnu/bin/../lib/gcc/aarch64-rpi3-linux-gnu/12.2.0/../../../../aarch64-rpi3-linux-gnu/bin/ld.bfd: /sysroot/lib/aarch64-linux-gnu/libpthread.a(nptl-init.o): in function `__pthread_initialize_minimal_internal':
./nptl/nptl-init.c:335: undefined reference to `_dl_pagesize'
/opt/x-tools/aarch64-rpi3-linux-gnu/bin/../lib/gcc/aarch64-rpi3-linux-gnu/12.2.0/../../../../aarch64-rpi3-linux-gnu/bin/ld.bfd: /sysroot/lib/aarch64-linux-gnu/libpthread.a(unwind.o): in function `_jmpbuf_sp':
./nptl/../sysdeps/aarch64/jmpbuf-offsets.h:52: undefined reference to `__pointer_chk_guard_local'

问题原因

  1. 库类型与隐式依赖差异:当使用-lpthread作为链接标志时,GCC会自动处理pthread的隐式依赖(比如动态链接器所需的libdl.so,对应_dl_*符号),同时适配aarch64平台的指针检查机制。但直接在target_link_libraries中写pthread时,CMake默认会链接静态库libpthread.a,而静态版本需要显式声明所有依赖,缺失的话就会出现未定义引用。
  2. 链接顺序问题:GCC处理-lpthread时会自动调整链接顺序,确保依赖关系正确解析;但手动指定pthread库时,CMake不会自动调整顺序,可能导致依赖符号无法被找到。

解决方案

方案1:使用CMake标准线程模块(推荐)

CMake提供的FindThreads模块可以跨平台处理线程库链接,自动适配交叉编译场景,无需手动处理依赖:

# 在配置pkg_check_modules之前添加
find_package(Threads REQUIRED)

# 修改target_link_libraries部分
target_link_libraries(${PROJECT_NAME}
    odas
    ${PC_FFTW3_LIBRARIES}
    ${PC_ALSA_LIBRARIES}
    ${PC_LIBCONFIG_LIBRARIES}
    ${PC_PULSEAUDIO_LIBRARIES}
    m
    Threads::Threads
)

方案2:显式添加缺失的依赖库

如果要手动链接,需要补充dl库来提供动态链接器相关符号,同时确保链接顺序正确:

target_link_libraries(${PROJECT_NAME}
    odas
    ${PC_FFTW3_LIBRARIES}
    ${PC_ALSA_LIBRARIES}
    ${PC_LIBCONFIG_LIBRARIES}
    ${PC_PULSEAUDIO_LIBRARIES}
    m
    pthread
    dl
)

如果偏好使用链接标志的方式,建议用CMake的target_link_options替代全局的CMAKE_EXE_LINKER_FLAGS,更符合现代CMake的目标级配置规范:

# 移除原有的GCC_COVERAGE_LINK_FLAGS相关配置,添加以下内容
target_link_options(${PROJECT_NAME} PRIVATE -lm -lpthread)

内容的提问来源于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 05:05:20