cross-gcc
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseCross-GCC
GCC交叉编译
Purpose
用途
Guide agents through setting up and using cross-compilation GCC toolchains: triplets, sysroots, pkg-config, QEMU-based testing, and common failure modes.
指导Agent完成交叉编译GCC工具链的搭建与使用:包括交叉编译三元组、sysroot、pkg-config、基于QEMU的测试,以及常见问题排查。
Triggers
触发场景
- "How do I compile for ARM on my x86 machine?"
- "I'm getting 'wrong ELF class' or 'cannot execute binary file'"
- "How do I set up a sysroot for cross-compilation?"
- "pkg-config returns host libraries in my cross build"
- "How do I debug a cross-compiled binary with QEMU + GDB?"
- "如何在x86机器上为ARM架构编译代码?"
- "我遇到了'wrong ELF class'或'cannot execute binary file'错误"
- "如何为交叉编译配置sysroot?"
- "交叉编译时pkg-config返回主机库路径"
- "如何使用QEMU + GDB调试交叉编译的二进制文件?"
Workflow
工作流程
1. Understand the triplet
1. 理解交叉编译三元组
A GNU triplet has the form (often 3 or 4 parts):
<arch>-<vendor>-<os>-<abi>| Triplet | Target |
|---|---|
| 64-bit ARM Linux (glibc) |
| 32-bit ARM Linux hard-float |
| Bare-metal ARM (no OS) |
| 64-bit RISC-V Linux |
| Windows (MinGW) from Linux |
| Little-endian MIPS Linux |
GNU交叉编译三元组的格式为(通常为3或4个部分):
<arch>-<vendor>-<os>-<abi>| 三元组 | 目标架构 |
|---|---|
| 64位ARM Linux(glibc) |
| 32位ARM Linux硬浮点 |
| 裸机ARM(无操作系统) |
| 64位RISC-V Linux |
| 从Linux编译Windows(MinGW) |
| 小端MIPS Linux |
2. Install the toolchain
2. 安装工具链
bash
undefinedbash
undefinedDebian/Ubuntu
Debian/Ubuntu
sudo apt install gcc-aarch64-linux-gnu g++-aarch64-linux-gnu binutils-aarch64-linux-gnu
sudo apt install gcc-aarch64-linux-gnu g++-aarch64-linux-gnu binutils-aarch64-linux-gnu
For bare-metal ARM (Cortex-M)
针对裸机ARM(Cortex-M)
sudo apt install gcc-arm-none-eabi binutils-arm-none-eabi
sudo apt install gcc-arm-none-eabi binutils-arm-none-eabi
Verify
验证
aarch64-linux-gnu-gcc --version
undefinedaarch64-linux-gnu-gcc --version
undefined3. Basic cross-compilation
3. 基础交叉编译
bash
undefinedbash
undefinedC
C语言
aarch64-linux-gnu-gcc -O2 -o hello hello.c
aarch64-linux-gnu-gcc -O2 -o hello hello.c
C++
C++语言
aarch64-linux-gnu-g++ -O2 -std=c++17 -o hello hello.cpp
aarch64-linux-gnu-g++ -O2 -std=c++17 -o hello hello.cpp
Bare-metal (no stdlib, no OS)
裸机环境(无标准库、无操作系统)
arm-none-eabi-gcc -mcpu=cortex-m4 -mthumb -mfloat-abi=hard -mfpu=fpv4-sp-d16
-ffreestanding -nostdlib -T linker.ld -o firmware.elf startup.s main.c
-ffreestanding -nostdlib -T linker.ld -o firmware.elf startup.s main.c
undefinedarm-none-eabi-gcc -mcpu=cortex-m4 -mthumb -mfloat-abi=hard -mfpu=fpv4-sp-d16
-ffreestanding -nostdlib -T linker.ld -o firmware.elf startup.s main.c
-ffreestanding -nostdlib -T linker.ld -o firmware.elf startup.s main.c
undefined4. Sysroot
4. Sysroot配置
A sysroot is a directory containing the target's headers and libraries. Required when your code links against target-specific libraries.
bash
undefinedSysroot是包含目标架构头文件和库的目录,当代码需要链接目标架构专属库时必须配置。
bash
undefinedUse a sysroot
使用sysroot
aarch64-linux-gnu-gcc --sysroot=/path/to/aarch64-sysroot -O2 -o prog main.c
aarch64-linux-gnu-gcc --sysroot=/path/to/aarch64-sysroot -O2 -o prog main.c
Common sysroot sources:
常见sysroot来源:
- Raspberry Pi: download from raspbian/raspios
- 树莓派:从raspbian/raspios下载
- Debian multiarch: debootstrap --arch arm64 bullseye /tmp/sysroot
- Debian多架构:debootstrap --arch arm64 bullseye /tmp/sysroot
- Yocto/Buildroot: generated automatically in build output
- Yocto/Buildroot:在构建输出中自动生成
Verify the sysroot is correct:
```bash
aarch64-linux-gnu-gcc --sysroot=/path/to/sysroot -v -E - < /dev/null 2>&1 | grep sysroot
验证sysroot配置是否正确:
```bash
aarch64-linux-gnu-gcc --sysroot=/path/to/sysroot -v -E - < /dev/null 2>&1 | grep sysroot5. pkg-config for cross builds
5. 交叉编译中的pkg-config配置
pkg-configbash
export PKG_CONFIG_SYSROOT_DIR=/path/to/sysroot
export PKG_CONFIG_LIBDIR=${PKG_CONFIG_SYSROOT_DIR}/usr/lib/aarch64-linux-gnu/pkgconfig:${PKG_CONFIG_SYSROOT_DIR}/usr/share/pkgconfig
export PKG_CONFIG_PATH= # clear host path
pkg-config --libs libssl # now returns target paths默认情况下会返回主机库路径,需通过以下方式覆盖:
pkg-configbash
export PKG_CONFIG_SYSROOT_DIR=/path/to/sysroot
export PKG_CONFIG_LIBDIR=${PKG_CONFIG_SYSROOT_DIR}/usr/lib/aarch64-linux-gnu/pkgconfig:${PKG_CONFIG_SYSROOT_DIR}/usr/share/pkgconfig
export PKG_CONFIG_PATH= # 清空主机路径
pkg-config --libs libssl # 现在返回目标架构路径6. CMake cross-compilation
6. CMake交叉编译
Create a toolchain file :
aarch64.cmakecmake
set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_SYSTEM_PROCESSOR aarch64)
set(CMAKE_C_COMPILER aarch64-linux-gnu-gcc)
set(CMAKE_CXX_COMPILER aarch64-linux-gnu-g++)
set(CMAKE_SYSROOT /path/to/aarch64-sysroot)
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)bash
cmake -S . -B build -DCMAKE_TOOLCHAIN_FILE=aarch64.cmake
cmake --build build创建工具链文件:
aarch64.cmakecmake
set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_SYSTEM_PROCESSOR aarch64)
set(CMAKE_C_COMPILER aarch64-linux-gnu-gcc)
set(CMAKE_CXX_COMPILER aarch64-linux-gnu-g++)
set(CMAKE_SYSROOT /path/to/aarch64-sysroot)
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)bash
cmake -S . -B build -DCMAKE_TOOLCHAIN_FILE=aarch64.cmake
cmake --build build7. Test with QEMU
7. 使用QEMU测试
bash
undefinedbash
undefinedUser-mode emulation (Linux binaries, no full OS)
用户模式仿真(Linux二进制文件,无需完整操作系统)
sudo apt install qemu-user-static
qemu-aarch64-static ./hello
sudo apt install qemu-user-static
qemu-aarch64-static ./hello
Or set binfmt_misc for transparent execution:
或设置binfmt_misc实现透明执行:
Then just: ./hello
之后直接运行:./hello
GDB remote debug via QEMU
通过QEMU进行GDB远程调试
qemu-aarch64-static -g 1234 ./hello &
aarch64-linux-gnu-gdb -ex "target remote :1234" ./hello
undefinedqemu-aarch64-static -g 1234 ./hello &
aarch64-linux-gnu-gdb -ex "target remote :1234" ./hello
undefined8. Common errors
8. 常见错误
| Error | Cause | Fix |
|---|---|---|
| Running target binary on host without QEMU | Use |
| Wrong-architecture object linked | Check triplet; ensure all objects use same toolchain |
| Host library path used for cross-link | Set |
| Missing ARM ABI runtime | Link with |
| Distance too large | Use |
| Wrong | Set correct CPU flags for target |
| 错误信息 | 原因 | 解决方法 |
|---|---|---|
| 未通过QEMU直接在主机运行目标架构二进制文件 | 使用 |
| 链接了架构不兼容的对象文件 | 检查交叉编译三元组;确保所有对象文件使用同一工具链 |
| 交叉链接时使用了主机库路径 | 设置 |
| 缺少ARM ABI运行时库 | 添加链接参数 |
| 代码距离过大 | 使用 |
| | 为目标架构设置正确的CPU标志 |
9. Environment variables
9. 环境变量配置
bash
undefinedbash
undefinedTell build systems to use cross-compiler
告知构建系统使用交叉编译器
export CC=aarch64-linux-gnu-gcc
export CXX=aarch64-linux-gnu-g++
export AR=aarch64-linux-gnu-ar
export STRIP=aarch64-linux-gnu-strip
export OBJDUMP=aarch64-linux-gnu-objdump
export CC=aarch64-linux-gnu-gcc
export CXX=aarch64-linux-gnu-g++
export AR=aarch64-linux-gnu-ar
export STRIP=aarch64-linux-gnu-strip
export OBJDUMP=aarch64-linux-gnu-objdump
For autoconf projects
针对autoconf项目
./configure --host=aarch64-linux-gnu --prefix=/usr
For a reference on ARM-specific GCC flags, see [references/arm-flags.md](references/arm-flags.md)../configure --host=aarch64-linux-gnu --prefix=/usr
关于ARM专属GCC标志的参考文档,请查看[references/arm-flags.md](references/arm-flags.md)。Related skills
相关技能
- Use for GCC flag details
skills/compilers/gcc - Use for remote debugging with
skills/debuggers/gdbgdbserver - Use for AArch64 assembly specifics
skills/low-level-programming/assembly-arm - Use for toolchain file setup
skills/build-systems/cmake
- 若需了解GCC标志细节,请使用
skills/compilers/gcc - 若需了解gdbserver远程调试,请使用
skills/debuggers/gdb - 若需了解AArch64汇编细节,请使用
skills/low-level-programming/assembly-arm - 若需了解工具链文件设置,请使用
skills/build-systems/cmake