当前位置: 首页 > news >正文

[ai] 交叉编译详解:以aarch64下busybox为例

前言:

近期想在路由器上装个nohup保证ssh的终端结束后程序还能继续运行,
选择自己编译busybox的nohup用。顺带用musl静态编译不处理依赖问题,还保持小的大小。
实际上就是装了个gcc,g++,最后git clone musl-cross-make,
编译一下,git clone busybox,装个ncursor,配置一下,只选择nohup,配置一些内容,包括静态编译。
下面是ai总结的。

意义不明的ai开头

当我们谈论“编译”时,通常只是执行make,但很少关注它实际执行了什么。make本质上只是根据Makefile去执行一系列命令,这些命令主要是gcc、ld、as等工具。下面以BusyBox为例,直接看交叉编译过程中真实执行的命令。

第一阶段:配置与预处理(没啥用)

编译前需要解决头文件问题。宿主机(x86)有自己的/usr/include,但目标平台(AArch64)需要另一套头文件,这些头文件在工具链的sysroot中。

执行make menuconfig会生成.config,Makefile会把其中的配置转换为编译参数。例如:

aarch64-linux-musl-gcc -E \-D__aarch64__ \-D__linux__ \-DCONFIG_LS=y \-DCONFIG_STATIC=y \-I./include \-I./arch/aarch64/include \-isystem /opt/musl-cross/lib/gcc/aarch64-linux-musl/9.2.0/include \-isystem /opt/musl-cross/aarch64-linux-musl/sysroot/usr/include \shell/ls.c -o shell/ls.i

这里主要有三点:

-D:把配置项变成宏,控制#ifdef分支
-I:项目头文件路径
-isystem:目标系统头文件路径(来自工具链)

如果不使用sysroot,而误用宿主机的/usr/include,会导致错误。例如:

#define __NR_open 2   // x86_64
#define __NR_open 5   // AArch64

系统调用号错误会导致程序运行异常。此外,不同架构的数据类型大小可能不同,结构体布局也会出错。因此必须使用工具链提供的头文件。

工具链命名

编译器名称aarch64-linux-musl-gcc包含目标信息:

aarch64:架构
linux:目标系统
musl:使用的C库

如果架构不匹配(例如32位设备使用aarch64工具链),程序无法运行。

第二阶段:编译(没啥用)

预处理后进入编译阶段。实际执行的核心命令类似:

aarch64-linux-musl-gcc -c -o libbb/trim.o libbb/trim.c

虽然可以拆分为:

gcc -S
as

但实际由gcc内部完成:

gcc├── 预处理├── 编译(cc1)└── 汇编(as)

你看到的完整命令中还包含大量优化和警告参数,这些不影响基本流程。

构建过程中还会执行:

scripts/basic/fixdep ...

这个工具用于处理依赖关系,与交叉编译本身无关。

为什么只需要替换gcc (最重要)

到这里为止,编译流程没有任何变化,唯一不同的是使用了:

aarch64-linux-musl-gcc

而不是:

gcc

原因在于gcc的查找路径是预先配置好的。gcc查找头文件和库的来源有三层:

命令行参数(-I、-L、--sysroot)
环境变量
编译时内置配置(最关键)

工具链在构建gcc时会指定:

--with-sysroot=/aarch64-linux-musl

因此:

#include <stdio.h>

实际查找路径是:

/aarch64-linux-musl/usr/include/stdio.h

库文件查找:

/aarch64-linux-musl/usr/lib/libc.so

系统默认gcc的sysroot是/,所以使用的是:

/usr/include
/usr/lib

即glibc。

而交叉工具链的sysroot指向自己的目录,因此使用的是musl。

此外,aarch64-linux-musl-gcc还会调用同一前缀的工具:

aarch64-linux-musl-as
aarch64-linux-musl-ld
aarch64-linux-musl-ar

这些路径在构建工具链时已经写入gcc(可以通过gcc -v查看)。

工具链的组成

一个工具链通常包含:

gcc
binutils(as / ld / ar)
libc(musl或glibc)
sysroot(头文件和库)

这些组件是一起构建并匹配的,避免版本不一致的问题。

http://www.jsqmd.com/news/625637/

相关文章:

  • 不用PID,我的Arduino四路循迹小车为什么也能跑?聊聊‘状态机’控制思路
  • Freertos堆管理算法解析:如何为STM32选择最优内存方案
  • 新手程序员必看:轻松掌握大模型技能,开启AI行动专家之路(收藏版)
  • 算法安全自评估报告怎么写?内容框架 + 难点解析 + 实战模板(直接照搬)
  • SITS2026测评结果首发,仅限首批技术决策者查阅:为什么83%的团队误判了AI工具ROI?
  • Flutter ClipRRect
  • 2025届学术党必备的十大降重复率方案实测分析
  • Unity发布京东小游戏汾
  • SDXL 1.0电影级绘图工坊功能体验:反向提示词使用详解
  • 保姆级避坑指南:在Ubuntu 20.04 + ROS Noetic下,用Livox Mid360雷达和PX4无人机做Gazebo仿真建图
  • 深入解析RS232串口通信:从单片机接收到发送的完整实践
  • 魔兽争霸3闪退修复终极指南:用WarcraftHelper轻松解决兼容性问题
  • CKKS 同态加密数学基础推导盟
  • OpenRocket火箭仿真软件:5步轻松设计你的第一枚模型火箭
  • Pixel Script Temple 解决编程错误:智能诊断与修复‘403 Forbidden’等常见问题
  • 深入解析扫描电子显微镜中的背散射电子探测器:原理、应用与电路设计
  • Spring教程-AOP
  • 软件行为驱动开发管理化的协作定义
  • SunnyUI中Pipe控件的动态数据可视化应用
  • 高性能FMC接口扩展卡详解:高速ADC/DAC设计、工程应用与参数对比
  • 云端隔断智慧工厂联系电话多少?2026年四川办公隔断源头工厂直供指南 - 精选优质企业推荐榜
  • Royal cove的实现(个人想法)
  • x86 - 64 架构下拆分锁性能测试:现状、挑战与未来
  • Nginx日志分割实战:如何用map指令按日期自动生成日志文件(附完整配置)
  • XUnity.AutoTranslator:如何为Unity游戏打造智能实时翻译系统
  • Java项目Loom升级实战:3步完成Spring WebFlux与虚拟线程深度整合(附压测对比数据)
  • 配电网电压与无功协调优化策略:降低运行成本、优化设备性能与场景对比分析
  • Qt 自定义控件动画深度解析:从 QPropertyAnimation 到源码内幕
  • 2026年四川成都办公玻璃隔断智能化方案深度横评:源头工厂直供与隐私保护的平衡之道 - 精选优质企业推荐榜
  • 音视频框架云原生应用