Linux之crosstool-NG(1)生成交叉编译Toolchain
Author: Once Day Date: 2025年2月25日
一位热衷于Linux学习和开辟的菜鸟,试图谱写一场冒险之旅,也许尽头只是一场白日梦…
本文相干内容翻译自crosstool-NG官方文档。
漫漫长路,有人对你微笑过嘛…
全系列文章可参考专栏: buildroot编译框架_Once_day的博客-CSDN博客。
参考文章:
- Buildroot - Making Embedded Linux Easy
- crosstool-NG
- Documentation (crosstool-ng.github.io)
- crosstool-ng/crosstool-ng: A versatile (cross-)toolchain generator. (github.com)
- Yann E. MORIN - Re: Tutorial
1. 概述
1.1 简介
Crosstool-NG 是一款用于创建交叉编译器的开源工具。交叉编译器是一种特别类型的编译器,可以在一种类型的计算机上(称为“主机”)为另一种类型的计算机(称为“目标”)生成可执行代码。这对于嵌入式系统开辟者特别有效,他们需要在功能强盛的主机上为资源受限的目标装备(如 ARM 或 MIPS 微控制器)生成代码。
以下是 Crosstool-NG 的重要功能和作用:
- 自定义构建: Crosstool-NG 允许用户选择他们想要的特定版本的 GCC,glibc 和 binutils,以及其他的库和工具。这意味着你可以根据项目需求创建一个精细调整的工具链。
- 设置界面:Crosstool-NG 提供了一个基于菜单的设置界面,供用户选择各种选项,如工具链的组件版本、目标体系结构、硬件浮点设置等。
- 并行构建:Crosstool-NG 支持并行构建,这可以明显加快工具链的构建时间。
- 多平台支持:Crosstool-NG 支持多种目标体系结构,包括 ARM、MIPS、PowerPC、x86 和更多。
- 补丁系统:如果需要,可以通过补丁系统对源代码举行修改,以顺应特定的需求。
- 生成工具链:末了,Crosstool-NG 会生成一个可在主机上运行的交叉编译工具链,以生成目标装备的可执行代码。
总的来说,Crosstool-NG 是一个强盛的工具,它可以帮助开辟者创建、定制和管理交叉编译工具链,从而简化了嵌入式开辟流程。
1.2 背景
crosstool-NG旨在构建工具链。工具链是软件开辟项目中必不可少的组成部分。它将编译、组装和链接正在开辟的代码。工具链的某些部分终极会出现在生成的二进制文件中: 静态库只是一个例子。
因此,工具链是一个非常敏感的软件部分,因为其中一个组件或设置不当的组件中的任何错误都可能导致执行题目,包括性能不佳、应用程序不测结束、软件行为不当(通常很难检测到)、硬件损坏,甚至是人为风险(这非常令人遗憾)。
工具链是由差别的软件组成的,每个软件都非常复杂,需要特别设计的选项来构建和无缝地工作。这通常不那么轻易,纵然是在原生工具链的情况下。当涉及到交叉编译时,工作达到了更高的复杂性,这可能会成为一场噩梦……
互联网上存在一些跨工具链,可以用于一般开辟,但它们有许多限制:
- 它们可以是通用的,因为它们是为大多数人设置的。
- 没有针对特定目标举行优化。
- 它们可能是为特定的目标而准备的,因此不轻易使用,也不适合优化,甚至不支持你的目标。
- 他们常常使用老旧的组件(编译器、C库等),不支持你极新处置惩罚器的特别功能。
另一方面,这些工具链提供了一些上风:
- 他们已经准备好使用,很轻易安装和设置。
- 如果被广泛的社区使用,它们是经过验证的。
但是,一旦想要充分使用特定硬件,就需要构建本身的工具链。这就是crosstool-NG发挥作用的地方。还有许多工具可以为特定需求构建工具链,这些工具实际上是不可伸缩的。例子有:
- builroot,其重要目标是构建根文件系统,因此得名。但是,一旦拥有了带有buildroot的工具链,其中的一部分将安装在将来的根(sysroot)中,因此,如果想要构建一个全新的根(sysroot),要么必须将现有的根保存为模板并稍后规复它,要么从头开始重新启动,这不太方便。
- 对于其他项目(例如,openenembedded.org,Yocto Project),同样用于构建根文件系统。
crosstool-NG的真正目标是构建工具链,而且仅仅是工具链。然后你就可以按照你想要的方式使用它。
NG的意思是下一代(Next Generation),经过So Yann的整理,脚本,文件,和软件包都相应的更新过,并形成了当前使用的crosstool版本。
1.3 编译类型
参考文档:https://crosstool-ng.github.io/docs/toolchain-types/
你可能会遇到四种类型的工具链。起首,你必须相识以下内容:当涉及到编译器时,最多会涉及四台呆板:
- 设置工具链组件的呆板:设置呆板(config machine)。
- 构建工具链组件的呆板:构建呆板(build machine)。
- 运行工具链的呆板:主机(host machine)。
- 工具链为其生成代码的目标呆板:目标呆板(target machine)。
我们通常可以假设设置呆板和构建呆板是雷同的。大多数情况下,这是正确的。唯一的例外是,如果你使用分布式编译(如distcc)。为了简单起见,让我们暂时忽略这一点。
以是我们只剩下三台呆板:构建呆板(build),主机(host),目标呆板(target)。
任何工具链都会涉及这三台呆板。这一点你可以像确信"2加2等于4"一样确信。它们是这样发挥作用的:
- 构建呆板 == 主机 == 目标呆板 (“本地(native)”),这是一个普通的本地工具链,针对的是与构建它的呆板完全雷同的呆板,并再次在完全雷同的呆板上运行。当你想使用更新的组件时,好比更新的gcc,你必须构建这样一个工具链。
- 构建呆板 == 主机 != 目标呆板 (“交叉(cross)”),这是一个经典的交叉工具链,它盼望在编译它的同一台呆板上运行,并生成代码在第二台呆板(目标呆板)上运行。
- 构建呆板 != 主机 == 目标呆板 (“交叉-本地(cross-native)”),这样的工具链也是一个本地工具链,因为它的目标呆板与运行它的呆板雷同。但它是在另一台呆板上构建的。当移植到新的架构时,或者如果构建呆板比主机快得多时,你需要这样一个工具链。
- 构建呆板 != 主机 != 目标呆板 (“加拿大(canadian)”), 这个工具链被称为"加拿大交叉"工具链,很棘手。涉及的三台呆板都不雷同。如果你有一台快速的构建呆板,但用户将在另一台呆板上使用它,并且将生成代码在第三台呆板上运行,你可能需要这样一个工具链。
术语"加拿大交叉"的由来是因为其时在讨论所有这些题目时,加拿大有三个全国性的政党(根据维基百科)。
crosstool-NG可以构建所有这些类型的工具链,或者至少是朝这个方向努力的。不过,也有一些需要注意的地方。
在构建"本地"工具链时,crosstool-ng目前仍然会为目标呆板编译新版本的libc。目前还没有办法将系统libc和/或系统内核头文件作为工具链的一部分。如果你选择兼容的版本(即,用工具链编译的应用程序将加载系统libc),这可能会奏效。
可以将"交叉-本地"工具链构建为"加拿大"工具链的一个平常的案例。这并不理想,因为它会使crosstool-NG两次编译针对主机的工具(第一次,作为所有加拿大构建的先决条件的单独工具链;第二次,作为加拿大构建本身的一部分创建的临时工具链的一部分)。将来可能会对此举行改进。
要构建"加拿大"工具链,你必须先构建一个在构建呆板上运行并以主机为目标的工具链作为先决条件(即一个简单的交叉工具链)。然后,将这个先决条件的/bin目次添加到$PATH情况变量中,并设置加拿大工具链,将先决条件工具链的目标指定为新工具链的主机。
crosstool-NG附带了一些加拿大工具链的示例。加拿大示例的名称由两个逗号分隔的部分组成,即HOST,TARGET。它们需要HOST示例作为先决条件。例如:
- ct-ng x86_64-w64-mingw32
- ct-ng build
- PATH=~/x-tools/x86_64-w64-mingw32/bin:$PATH
- ct-ng x86_64-w64-mingw32,x86_64-pc-linux-gnu
- ct-ng build
复制代码 请注意,你将无法在构建呆板上运行加拿大工具链生成的二进制文件!你需要将它们转移到运行设置为主机的操作系统的呆板上。
1.4 交叉工具链的构建过程
参考文档:https://crosstool-ng.github.io/docs/toolchain-construction/
我想要一个交叉编译器!你说的这个工具链是什么?
交叉编译器实际上是一组精密协作的差别工具的聚集。这些工具分列成一种级联式的链,一个工具的输出成为另一个工具的输入,终极生成在呆板上运行的实际二进制代码。以是,我们称这种安排为"工具链"。当工具链旨在为与运行它的呆板差别的呆板生成代码时,这被称为交叉工具链。
那么,工具链中有哪些组件呢?
工具链中起作用的组件起首是编译器本身。编译器将源代码(C、C++等)转换为汇编代码。首选的编译器是GNU编译器聚集,众所周知的gcc。
汇编代码由汇编器解释,以生成目标代码。这是由二进制工具完成的,如GNU binutils。
一旦生成了差别的目标代码文件,它们就会被聚合在一起形成终极的可执行二进制文件。这称为链接,是通过使用链接器实现的。GNU binutils也附带了一个链接器。
到目前为止,我们得到了一个完整的工具链,能够将源代码转换为实际的可执行代码。根据在目标呆板上运行的操作系统或没有操作系统,我们还需要C库。C库提供了一个标准的抽象层,用于执行基本任务(如分配内存、在终端上打印输出、管理文件访问等)。有许多C库,每个都针对差别的系统。对于Linux桌面,有glibc、eglibc,甚至uClibc;对于嵌入式Linux,你可以选择eglibc或uClibc;而对于没有操作系统的系统,你可以使用newlib、dietlibc,甚至不使用任何库。还有一些其他的C库,但它们没有那么广泛使用,或针对非常特定的需求(例如,klibc是C库的一个非常小的子集,旨在构建受限的初始ramdisk)。
在Linux下,C库需要知道内核的API,以决定存在哪些功能,如果需要,为缺失的功能包含什么仿真。该API由内核头文件提供。注意:这是特定于Linux的(可能还有极少数其他系统),其他操作系统上的C库不需要内核头文件。
现在,所有这些组件是如何链接在一起的?
到目前为止,所有重要组件都已涵盖,但它们仍需要以特定的次序构建。这里我们看到了依赖关系,从我们终极要使用的编译器开始。我们称该编译器为终极编译器。
终极编译器(Final compiler)需要C库(C library),以知道如何使用它,但是:
构建C库需要编译器。
C library => Final compiler
A需要B,而B需要A。这是经典的先有鸡还是先有蛋的题目。办理方法是构建一个精简的编译器,它不需要C库,但能够构建C库。我们称之为bootstrap、初始或核心编译器。以是这里是新的依赖列表:
终极编译器需要C库(C library),以知道如何使用它,
构建C库需要核心编译器(Core compiler),但是:
核心编译器需要C库头文件(C library headers)和启动文件(start files),以知道如何使用C库。
C library headers + start files => Core compiler => C library => Final compiler
B需要C,而C需要B。又是先有鸡还是先有蛋。为了办理这个题目,我们需要构建一个C库,它只安装头文件和启动文件。启动文件(也称为"C运行时(C runtime)"或CRT)是gcc需要的极少数文件,用于在NPTL系统上启用线程本地存储(TLS)。以是现在我们有:
终极编译器需要C库(C library),以知道如何使用它,
构建C库(C library)需要核心编译器(Core compiler)
核心编译器需要C库头文件(C library headers)和启动文件(start files),以知道如何使用C库,但是:
构建启动文件(start files)需要编译器
???compiler => C library headers + start files => Core compiler => C library => Final compiler
天哪……C需要D,而D需要C,又来了。以是我们需要构建一个更简单的编译器,它不需要头文件,也不需要启动文件。这个编译器也是一个bootstrap、初始或核心编译器。为了区分这两个核心编译器,我们称前者为核心pass 2(core pass 2),称后者为核心pass 1(core pass 1)。依赖列表变为:
终极编译器需要C库(C library),以知道如何使用它,
构建C库(C library)需要编译器(Core compiler pass 2)
核心pass 2编译器(Core compiler pass 2)需要C库头文件(C library headers)和启动文件(start files),以知道如何使用C库
构建启动文件需要编译器(Core compiler pass 1)
我们需要一个核心pass 1编译器(Core compiler pass 1)
Core compiler pass 1=> C library headers + start files => Core compiler pass 2 => C library => Final compiler
正如我们前面所说,C库也需要内核头文件(Kernel headers)。内核头文件没有要求,以是在这种情况下就结束了:
终极编译器需要C库(C library),以知道如何使用它,
构建C库(C library)需要编译器(Core compiler pass 2)
核心pass 2编译器(Core compiler pass 2)需要C库头文件(C library headers)和启动文件(start files),以知道如何使用C库
构建启动文件需要编译器(Core compiler pass 1)和内核头文件(Kernel headers)
我们需要一个核心pass 1编译器(Core compiler pass 1)
Core compiler pass 1 + Kernel headers => C library headers + start files => Core compiler pass 2 => C library => Final compiler
我们需要添加一些新的要求。当我们为目标编译代码时,我们需要汇编器(Assembler)和链接器(linker)。这样的代码当然是从C库构建的,以是我们需要在C库启动文件之前构建binutils,以及完整的C库本身。别的,gcc中的一些代码也将在目标上运行。幸运的是,binutils没有要求。以是,我们的依赖链如下:
终极编译器需要C库(C library),以知道如何使用它,以及binutils ,
构建C库(C library)需要编译器(Core compiler pass 2)和binutils
核心pass 2编译器(Core compiler pass 2)需要C库头文件(C library headers)和启动文件(start files),以知道如何使用C库,以及binutils
构建启动文件需要编译器(Core compiler pass 1)和内核头文件(Kernel headers)和binutils
核心pass 1编译器(Core compiler pass 1)需要binutils
binutils => Core compiler pass 1 + Kernel headers => C library headers + start files => Core compiler pass 2 => C library => Final compiler
这转化为以下构建组件的次序:
binutils
核心pass 1编译器(Core compiler pass 1)
内核头文件(Kernel headers)
C库头文件和启动文件(C library headers + start files)
核心pass 2编译器(Core compiler pass 2)
完整的C库(C library)
终极编译器(Final compiler)
太棒了!但我们完成了吗?
事实上,还没有,仍然缺少依赖项。就工具本身而言,我们不需要其他任何东西。
但是gcc有一些先决条件。它依赖一些外部库来执行一些非平常的任务(例如在常量中处置惩罚复数)。有几个选项可以构建这些库。起首,人们可能会想依靠Linux发行版来提供这些库。唉,直到最近,它们还没有广泛提供。以是,如果发行版不是太新,我们很可能必须本身构建这些库(我们在下面构建)。受影响的库是:
- GNU多精度算术库,GMP;
- 用于具有正确舍入的多精度浮点计算的C库,MPFR;
- 用于复数算术的C库,MPC。
这些库的依赖关系是:
- MPC需要GMP和MPFR。
- MPFR需要GMP。
- GMP没有先决条件。
以是,构建次序变成:
GNU多精度算术库(GMP)
用于具有正确舍入的多精度浮点计算的C库(MPFR)
用于复数算术的C库(MPC)
binutils
核心pass 1编译器(Core compiler pass 1)
内核头文件(Kernel headers)
C库头文件和启动文件(C library headers + start files)
核心pass 2编译器(Core compiler pass 2)
完整的C库(C library)
终极编译器(Final compiler)
完成了!还是还有呢?
这现在足以构建一个功能性的工具链。以是如果你现在已经足够了,可以在这里停下来。或者如果你很好奇,可以继承阅读。
gcc还可以使用一些其他外部库。这些附加的可选库用于在gcc中启用高级特性,例如循环优化(GRAPHITE)和链接时优化(LTO)。如果你想使用这些功能,你还需要三个附加库:
要启用GRAPHITE,根据GCC版本,它可能需要以下一个或多个:
- Parma多面体库,PPL;
- 整数集库,ISL;
- 使用PPL后端的分块循环生成器,CLooG/PPL;
- 使用ISL后端的分块循环生成器,CLooG。
要启用LTO:
这些库的依赖关系是:
PPL需要GMP;
CLooG/PPL需要GMP和PPL或ISL之一;
ISL没有先决条件;
libelf没有先决条件。
现在的列表看起来像:
GNU多精度算术库(GMP)
用于具有正确舍入的多精度浮点计算的C库(MPFR)
用于复数算术的C库(MPC)
Parma多面体库(PPL,循环优化(GRAPHITE))
整数集库(ISL,循环优化(GRAPHITE))
分块循环生成器(CLooG,循环优化(GRAPHITE))
ELF目标文件访问库(ELF,链接时优化(LTO))
binutils
核心pass 1编译器(Core compiler pass 1)
内核头文件(Kernel headers)
C库头文件和启动文件(C library headers + start files)
核心pass 2编译器(Core compiler pass 2)
完整的C库(C library)
终极编译器(Final compiler)
这个列表现在完整了,哇哦,是吗?但是为什么crosstool-NG有更多步调?
从理论的角度来看,这十三个步调已经是必要的步调了。但实际上,还是有一些小的差异;crosstool-NG中额外步调有三个差别的缘故原由。
起首,GNU binutils不支持某些类型的输出。使用binutils无法生成平面二进制文件,以是我们必须使用另一个组件来添加这种支持:elf2flt。elf2flt还需要zlib压缩库——如果我们正在构建加拿大或交叉本地工具链,我们可能无法使用主机的zlib。
其次,在某些主机操作系统上,工具链的本地化需要额外的库:gettext和libiconv。
第三,crosstool-NG还可以构建一些额外的调试实用程序以在目标上运行。这就是我们构建的地方,例如,交叉gdb、gdbserver和本机gdb(后两个在目标上运行,第一个在与工具链雷同的呆板上运行)。其他的(strace、ltrace、DUMA和dmalloc)与工具链完全无关,但在开辟时可以提供很大帮助,以是作为额外的好东西包含进来(而且构建起来相称轻易,以是没题目;更复杂的东西不值得花力气包含在crosstool-NG中)。
2. 编译ARM64交叉编译工具链
2.1 创建host主机情况
下面文档里官方枚举了一些常见系统的运行情况搭建过程,包括Linux,Windows,FreeBSD,Macos:
- Setting up host OS (crosstool-ng.github.io)
Linux系统和其他装备不一样,官方默认Linux系统使用Docker来搭建编译情况,紧跟时代潮流,dockerfile也放在了源码目次下面,如下面所示:
- FROM ubuntu:22.04
- ARG CTNG_UID=1000
- ARG CTNG_GID=1000
- RUN groupadd -g $CTNG_GID ctng
- RUN useradd -d /home/ctng -m -g $CTNG_GID -u $CTNG_UID -s /bin/bash ctng
- # Non-interactive configuration of tzdata
- ENV DEBIAN_FRONTEND noninteractive
- ENV DEBCONF_NONINTERACTIVE_SEEN true
- RUN { echo 'tzdata tzdata/Areas select Etc'; echo 'tzdata tzdata/Zones/Etc select UTC'; } | debconf-set-selections
- RUN apt-get update
- RUN apt-get install -y gcc g++ gperf bison flex texinfo help2man make libncurses5-dev \
- python3-dev autoconf automake libtool libtool-bin gawk wget bzip2 xz-utils unzip \
- patch libstdc++6 rsync git meson ninja-build
- RUN wget -O /sbin/dumb-init https://github.com/Yelp/dumb-init/releases/download/v1.2.5/dumb-init_1.2.5_x86_64
- RUN chmod a+x /sbin/dumb-init
- RUN echo 'export PATH=/opt/ctng/bin:$PATH' >> /etc/profile
- ENTRYPOINT [ "/sbin/dumb-init", "--" ]
复制代码 这个是ubuntu 22.04的设置,其他系统和linux分发版设置请查看对应dockerfile,这里不多说了。
下面直接安装好这些软件,docker操作有些麻烦(重要是下载)。
2.2 安装crosstool-ng
crosstool-NG 是一个用于构建交叉编译工具链的工具,支持多种架构(如 ARM、MIPS、RISC-V 等)。以下是根据官方文档 https://crosstool-ng.github.io/docs/install/ 先容的 安装方法。
在安装 crosstool-NG 之前,需要先安装一些必备的软件包:
对于 Ubuntu/Debian:
- sudo apt update
- sudo apt install -y autoconf automake libtool libncurses-dev \
- flex bison gperf texinfo help2man gawk libtool-bin \
- libssl-dev bash patch gzip bzip2 perl tar cpio unzip rsync \
- file bc wget python3
复制代码 对于 CentOS/RHEL:
- sudo yum groupinstall -y "Development Tools"
- sudo yum install -y ncurses-devel flex bison gperf texinfo \
- help2man gawk libtool libtool-ltdl-devel \
- openssl-devel patch gzip bzip2 perl tar cpio unzip rsync \
- file bc wget python3
复制代码 对于 macOS(使用 Homebrew):
- brew install autoconf automake libtool gawk gnu-sed \
- bison flex texinfo help2man wget
复制代码 下载并安装 crosstool-NG:
方法 1:从官方 Git 仓库安装(保举)
- git clone https://github.com/crosstool-ng/crosstool-ng.git
复制代码 方法 2:安装已发布的稳固版
如果不想从 GitHub 克隆最新代码,可以下载稳固版:
- wget http://crosstool-ng.org/download/crosstool-ng/crosstool-ng-latest.tar.bz2
- tar -xjf crosstool-ng-latest.tar.bz2
复制代码 然后是进入crosstool-ng目次,设置和编译crosstool-ng文件,末了安装到系统目次下面(也可以不安装):
- cd crosstool-ng
- ./bootstrap # 用于生成 configure。
- ./configure --prefix=/ # --enable-local 允许在当前目录下执行 crosstool-ng,无需全局安装。
- make
- make install # 这一步安装到系统根目录下
复制代码 2.3 设置crosstool-ng
使用 Crosstool-NG 定制交叉工具链的第一步,是下载和解压源代码包。然后进入解压后的目次,运行 ./configure 脚本设置编译安装选项,如指定安装目次等。设置完成后,接着运行 make 编译 Crosstool-NG 自身,再运行 make install 将其安装到之前指定的目次中。
有了 Crosstool-NG 工具之后,就可以开始创建本身的工具链设置了。运行 ct-ng menuconfig 即可打开一个交互式的设置界面。在这里,起首设置一些全局的选项,如 Crosstool-NG 的安装路径、工作目次、源码包下载存放目次等。
接下来,就要针对目标平台,举行一系列细节的设置。在 Target options 菜单下,可以选择 CPU 架构、字长、是否有浮点处置惩罚器等。Toolchain options 菜单可以指定工具链的名称前缀和版本号、使用的 C 库等。如果是为 Linux 系统编译,则在 Operating System 下设置内核头文件和目标系统的一些参数。
别的,binutils、gcc、C 库是构成工具链的核心组件,也要分别到 Binary utilities、C compiler、C-library 等菜单项中选择它们的详细版本和设置。所有设置完成后,保存退出,就生成了一个名为 .config 的设置文件。
末了,在设置好的目次下执行 ct-ng build,Crosstool-NG 就会自动下载源码包并启动编译构建过程,直到工具链安装完成。在 <工作目次>/x-tools/<工具链名称> 下,就可以找到交叉编译好的工具链文件了。
通过对设置文件的差别组合,可以用 Crosstool-NG 在同一台主机上同时设置构建多套差别目标的交叉工具链。编译过程中,还可以运行 ct-ng clean 清理临时文件。日后要升级更新工具链,修改设置里的版本号,重新运行构建命令即可,非常机动方便。
实际设置时,需要注意静态编译和Plugin之间存在辩论,然后编译的时候,非必要二进制文件都不要编译,等工具链编译出来,可以慢慢再编译其他的软件包。
2.4 开始编译
起首需要下载软件包,好比下面这种(网络欠好会下载很慢,需要使用一点小本领):
- onceday->crosstool:# ll src/
- total 289940
- drwxrwxr-x 2 onceday onceday 4096 Feb 27 22:51 ./
- drwxrwxr-x 4 onceday onceday 4096 Feb 27 22:35 ../
- -rw-rw-r-- 1 onceday onceday 28174300 Feb 27 23:44 binutils-2.43.1.tar.xz
- -rw-rw-r-- 1 onceday onceday 460560 Feb 27 23:44 expat-2.5.0.tar.xz
- -rw-rw-r-- 1 onceday onceday 87909952 Feb 27 23:44 gcc-13.3.0.tar.xz
- -rw-rw-r-- 1 onceday onceday 24426680 Feb 27 23:44 gdb-16.2.tar.xz
- -rw-rw-r-- 1 onceday onceday 11038556 Feb 27 23:44 gettext-0.23.1.tar.xz
- -rw-rw-r-- 1 onceday onceday 18752204 Feb 27 23:44 glibc-2.40.tar.xz
- -rw-rw-r-- 1 onceday onceday 2094196 Feb 27 23:44 gmp-6.3.0.tar.xz
- -rw-rw-r-- 1 onceday onceday 2035560 Feb 27 23:44 isl-0.26.tar.xz
- -rw-rw-r-- 1 onceday onceday 5166734 Feb 27 23:44 libiconv-1.16.tar.gz
- -rw-rw-r-- 1 onceday onceday 104565100 Feb 27 23:44 linux-4.14.329.tar.xz
- -rw-rw-r-- 1 onceday onceday 773573 Feb 27 23:44 mpc-1.3.1.tar.gz
- -rw-rw-r-- 1 onceday onceday 1493608 Feb 27 23:44 mpfr-4.2.1.tar.xz
- -rw-rw-r-- 1 onceday onceday 3612591 Feb 27 23:44 ncurses-6.4.tar.gz
- -rw-rw-r-- 1 onceday onceday 2642452 Feb 27 23:44 strace-6.13.tar.xz
- -rw-rw-r-- 1 onceday onceday 1305740 Feb 27 23:44 zlib-1.3.1.tar.xz
- -rw-rw-r-- 1 onceday onceday 2406875 Feb 27 23:44 zstd-1.5.6.tar.gz
复制代码 然后启动ct-ng build即可,不过很轻易在GLIBC和GCC编译过程中堕落,以是最好是把crosstool-ng的调试打开,支持断点重试。
编译完成之后,可以将x-tools目次打包,作为工具链(GCC和LIBC聚集体)。
编译的Target根目次是x-tools/aarch64-onceday-linux-gnu/aarch64-onceday-linux-gnu/sysroot。
- onceday->gnu-tool:$ file ~/x-tools/aarch64-onceday-linux-gnu/aarch64-onceday-linux-gnu/sysroot/usr/bin/getent
- /home/onceday/x-tools/aarch64-onceday-linux-gnu/aarch64-onceday-linux-gnu/sysroot/usr/bin/getent: ELF 64-bit LSB executable, ARM aarch64, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux-aarch64.so.1, BuildID[sha1]=888828ba766ed708f46a25db39a8422bd1044afe, for GNU/Linux 4.14.255, with debug_info, not stripped
复制代码 这里面是预编译出来的二进制文件,可以在目标Linux系统直接运行:
- root@linux:~# ./getent -v
- ./getent: invalid option -- 'v'
- Try `getent --help' or `getent --usage' for more information.
复制代码 3. 附件(参考设置)

Once Day
也信尤物终作土,不堪幽梦太急遽......
如果这篇文章为您带来了帮助或启发,不妨点个赞 |