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

使用CMake交叉编译grpc至aarch64时出现链接错误的求助

问题描述

当前使用gRPC v1.67.0,主机系统为Ubuntu 22.04,主机端protoc与grpc_cpp_plugin编译正常。采用aarch64-none-linux-gnu交叉编译工具链(gcc版本12.3.1 20230626),toolchain.cmake配置如下:

SET(CMAKE_SYSTEM_NAME Linux)
SET(CMAKE_SYSTEM_PROCESSOR aarch64)
set(CMAKE_STAGING_PREFIX /tmp/stage)
set(CMAKE_C_COMPILER /home/lenli/he01/arm-gnu-toolchain-12.3.rel1-x86_64-aarch64-none-linux-gnu/bin/aarch64-none-linux-gnu-gcc)
set(CMAKE_CXX_COMPILER /home/lenli/he01/arm-gnu-toolchain-12.3.rel1-x86_64-aarch64-none-linux-gnu/bin/aarch64-none-linux-gnu-g++)
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)

执行的CMake配置命令:

cmake -DCMAKE_TOOLCHAIN_FILE=/tmp/toolchain.cmake \
      -DCMAKE_BUILD_TYPE=Release \
      -DCMAKE_INSTALL_PREFIX=/tmp/install \
      ../..

CMake配置执行成功,但执行make -j4 install时,编译进度到约30%时出现大量类似如下的未定义引用错误:

re2_arg_test.cc:(.text+0x30): undefined reference to `std::ios_base::ios_base()'

regexp_test.cc:(.text+0x8c): undefined reference to `operator delete(void*, unsigned long)'

undefined reference to `vtable for std::__cxx11::basic_ostringstream<char, std::char_traits<char>, std::allocator<char> >'

原因分析

这类未定义引用错误属于C标准库符号缺失,核心原因是交叉编译环境下CMake未正确关联aarch64目标架构的C标准库,或编译过程中混用了主机系统的标准库文件,具体包括:

  • 工具链配置未明确指定C++标准库搜索路径,CMake误使用主机Ubuntu 22.04的x86_64架构标准库
  • gRPC默认启用的RE2等依赖库,交叉编译时未用对应工具链编译,导致链接阶段调用主机版本符号
  • 交叉工具链的C++标准库路径未被CMake识别,链接时无法找到对应架构的标准库符号

解决步骤

1. 完善toolchain.cmake配置

在原配置中添加以下内容,强制CMake使用交叉工具链自带的C++标准库:

# 指定C++标准版本(匹配gRPC要求,至少C++17)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

# 显式指定交叉工具链的sysroot路径
set(CMAKE_SYSROOT /home/lenli/he01/arm-gnu-toolchain-12.3.rel1-x86_64-aarch64-none-linux-gnu/aarch64-none-linux-gnu/libc)
set(CMAKE_FIND_ROOT_PATH ${CMAKE_SYSROOT})

# 配置链接参数,指定标准库搜索路径
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -L${CMAKE_SYSROOT}/lib -L${CMAKE_SYSROOT}/usr/lib")
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -L${CMAKE_SYSROOT}/lib -L${CMAKE_SYSROOT}/usr/lib")

2. 禁用测试用例编译(推荐)

交叉编译无需构建gRPC及依赖的测试代码,可在CMake配置时添加参数跳过:

cmake -DCMAKE_TOOLCHAIN_FILE=/tmp/toolchain.cmake \
      -DCMAKE_BUILD_TYPE=Release \
      -DCMAKE_INSTALL_PREFIX=/tmp/install \
      -DgRPC_BUILD_TESTS=OFF \
      -DRE2_BUILD_TESTING=OFF \
      ../..

3. 清理缓存后重新编译

# 进入编译目录
cd <你的build目录路径>
# 清理原有CMake缓存
rm -rf CMakeCache.txt CMakeFiles/
# 重新执行配置
cmake -DCMAKE_TOOLCHAIN_FILE=/tmp/toolchain.cmake \
      -DCMAKE_BUILD_TYPE=Release \
      -DCMAKE_INSTALL_PREFIX=/tmp/install \
      -DgRPC_BUILD_TESTS=OFF \
      -DRE2_BUILD_TESTING=OFF \
      ../..
# 重新编译安装
make -j4 install

4. 验证链接参数(排查用)

若仍有错误,检查编译时的链接命令,确认使用的是交叉工具链的aarch64-none-linux-gnu-g++,且链接路径指向交叉工具链的标准库目录。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 16:19:57