从源码编译 LoongArch GNU 工具链


1. 制作以 LoongArch 为目标的交叉工具链

1.1. 获取源码包

  • 下载页面:龙芯开源社区网站 - LoongArch GCC 8.3 交叉工具链 - 源码下载
  • 源码包名称如:loongarch-gcc8-linux-gnu-rc1.0-src-2022-04-22.tar

1.2. 展开源码包并校验完整性

展开源码包:

$ tar xvf loongarch-gcc8-linux-gnu-rc1.0-src-2022-04-22.tar

目录结构:

$ cd loongarch-gcc8-linux-gnu-rc1.0-src-2022-04-22
$ tree .
.
├── binutils-2.31-dc545ca87e.tar.xz
├── gcc-8.3.0-b4748c190d.tar.xz
├── glibc-2.28-310d27ffef.tar.xz
├── sha1sum
└── versions

0 directories, 5 files

使用 sha1sum 命令校验各文件完整性:

$ sha1sum -c < sha1sum
binutils-2.31-dc545ca87e.tar.xz: OK
gcc-8.3.0-b4748c190d.tar.xz: OK
glibc-2.28-310d27ffef.tar.xz: OK
versions: OK

各项目源码包列表:

  • binutils (基础版本 2.31)
  • gcc (基础版本 8.3.0)
  • glibc (基础版本 2.28)

1.3. 进行其他准备工作

以下步骤中,工具链安装根路径均表示为 <installation_prefix>

下载 GMP, MPFR, MPC, ISL 库源码

编译 GCC 依赖于以上四种库。用户在编译 GCC 之前,将它们的源码路径链接到 GCC 源码目录中即可识别。 这些库最终均静态链接到 GCC 二进制中。 用户可直接使用 GCC 源码中提供的 download_prerequisites 脚本,从上游网站下载它们的源码:

$ cd <gcc_srcdir>
$ contrib/download_prerequisites
gmp-6.1.0.tar.bz2: OK
mpfr-3.1.4.tar.bz2: OK
mpc-1.0.3.tar.gz: OK
isl-0.18.tar.bz2: OK
All prerequisites downloaded successfully.

$ ls -d gmp mpfr mpc isl
gmp  isl  mpc  mpfr

这些上游库源码中包含 GNU 架构名称处理脚本, 即 config.guessconfig.sub,目前需要手动更新为支持 LoongArch 的版本。

$ find gmp/ mpfr/ mpc/ isl/ -name config.guess -type f -exec sh -c 'chmod +w {}; cp -v config.guess {}' \;
'config.guess' -> 'gmp/config.guess'
'config.guess' -> 'mpfr/config.guess'
'config.guess' -> 'mpc/config.guess'
'config.guess' -> 'isl/config.guess'

$ find gmp/ mpfr/ mpc/ isl/ -name config.sub -type f -exec sh -c 'chmod +w {}; cp -v config.sub {}' \;
'config.sub' -> 'gmp/config.sub'
'config.sub' -> 'mpfr/config.sub'
'config.sub' -> 'mpc/config.sub'
'config.sub' -> 'isl/config.sub'

安装 Linux 内核头文件

编译 Glibc 库依赖于 Linux 内核头文件,目前可从 Loongnix deb 仓库 获得,包名为 linux-libc-dev,当前版本为 4.19.190-rc6.lnd.9

运行以下命令即可在安装路径 <installation_prefix> 下安装 Linux 内核头文件,供 Glibc 编译使用。

$ PKGNAME=linux-libc-dev_4.19.190-rc6.lnd.9_loongarch64.deb
$ wget http://pkg.loongnix.cn/loongnix/pool/main/l/linux/${PKGNAME}
$ ar x ${PKGNAME} data.tar.xz
$ mkdir -p <installation_prefix>/sysroot
$ tar -xvf data.tar.xz -C <installation_prefix>/sysroot
$ mv <installation_prefix>/sysroot/usr/include/{loongarch64-linux-gnu/,}asm
$ rmdir <installation_prefix>/sysroot/usr/include/loongarch64-linux-gnu

1.4. 交叉编译

编译 binutils

假设 binutils 源码目录为 <binutils_srcdir>,在空白构建目录下执行命令:

$ <binutils_srcdir>/configure --prefix=/ --target=loongarch64-linux-gnu --disable-werror
$ make -j `nproc` && make DESTDIR=<installation_prefix> install

此时 <installation_prefix> 目录的结构如下:

.
├── bin
├── loongarch64-linux-gnu
│   ├── bin
│   └── lib
├── share
│   ├── info
│   ├── locale
│   └── man
└── sysroot
    ├── lib
    └── usr

编译 GCC 第一遍 (pass 1)

编译第一遍 GCC 的目的仅在于编译 Glibc 库。 假设 GCC 源码目录为 <gcc_srcdir>,在空白构建目录下执行命令:

$ export PATH=<installation_prefix>/bin:$PATH
$ <gcc_srcdir>/configure --prefix=<installation_prefix> --target=loongarch64-linux-gnu --with-sysroot=<installation_prefix>/sysroot --disable-nls --disable-shared --without-headers --with-newlib --disable-libatomic --disable-threads --enable-languages=c
$ make all-gcc all-target-libgcc -j `nproc`
$ make install-gcc install-target-libgcc

此时 <installation_prefix> 目录的结构如下:

.
├── bin
├── include
├── lib
│   └── gcc
├── libexec
│   └── gcc
├── loongarch64-linux-gnu
│   ├── bin
│   └── lib
├── share
│   ├── info
│   ├── locale
│   └── man
└── sysroot
    ├── lib
    └── usr

编译 Glibc 库

假设 Glibc 源码目录为 <glibc_srcdir>,在空白构建目录下执行命令:

$ export PATH=<installation_prefix>/bin:$PATH
$ <glibc_srcdir>/configure --prefix=/usr --host=loongarch64-linux-gnu --with-headers=<installation_prefix>/sysroot/usr/include
$ mkdir <installation_prefix>/sysroot/usr/lib64 && ln -sf usr/lib64 <installation_prefix>/sysroot/lib64
$ mkdir <installation_prefix>/sysroot/usr/lib && ln -sf usr/lib <installation_prefix>/sysroot/lib
$ make -j `nproc`
$ make install_root=<installation_prefix>/sysroot MAKEINFO=: install

此时 <installation_prefix>/sysroot 目录的结构如下:

sysroot
├── etc
├── lib -> usr/lib
├── lib64 -> usr/lib64
├── sbin
├── usr
│   ├── bin
│   ├── include
│   ├── lib
│   ├── lib64
│   ├── libexec
│   ├── sbin
│   └── share
└── var
    └── db

需要注意的是,此处的 lib | sysroot/lib 路径不可省略。 原因是 LoongArch GCC 支持多库 (multilib) 机制,允许根据编译选项采用不同的库搜索路径, 以适应多种不同的传参返回规范,而每个多库搜索路径都包括一个固定的参考路径(即 lib)和后续叠加的相对路径 (由 GCC 编译选项动态确定)。多库搜索路径可正确访问的必要条件是固定参考路径存在。 对于在操作系统发行版上的本地编译器,该路径由发行版负责创建。

编译 GCC 第二遍 (pass 2)

假设 GCC 源码目录为 <gcc_srcdir>,在空白构建目录下执行命令:

# --target --with-sysroot --with-build-sysroot 选项需要保留,其余功能选择部分可自行定义
$ <gcc_srcdir>/configure --target=loongarch64-linux-gnu --prefix=<installation_prefix> --with-sysroot=<installation_prefix>/sysroot --with-build-sysroot=<installation_prefix>/sysroot --enable-languages=c,c++,fortran --enable-checking=release
$ make -j `nproc`
$ make install

此时 目录的结构如下:

.
├── bin
├── include
├── lib
│   └── gcc
├── lib64
├── libexec
│   └── gcc
├── loongarch64-linux-gnu
│   ├── bin
│   ├── include
│   ├── lib
│   └── lib64
├── share
│   ├── gcc-8.3.0
│   ├── info
│   ├── locale
│   └── man
└── sysroot
    ├── etc
    ├── lib -> usr/lib
    ├── lib64 -> usr/lib64
    ├── sbin
    ├── usr
    └── var

安装完毕执行以下命令:

$ loongarch64-linux-gnu-gcc -v
Using built-in specs.
COLLECT_GCC=......
COLLECT_LTO_WRAPPER=......
Target: loongarch64-linux-gnu
Configured with: ../gcc-8.3.0/configure --target=loongarch64-linux-gnu ......
Thread model: posix
gcc version 8.3.0 (GCC)

说明 GNU 交叉编译工具链安装成功。

2. 制作 LoongArch 本地工具链

  • 本地编译器 build,host,target 架构均一致,运行 GCC configure 脚本时可省略相关选项。
  • 用户可选择让工具链直接使用系统 glibc 库链接应用程序,或使用自行编译的 glibc 库。

2.1. 使用系统 glibc 库链接应用程序

依次编译 binutils 和 gcc 即可:

# Binutils
$ cd <binutils_builddir>
$ <binutils_srcdir>/configure --prefix=/ --disable-werror
$ make -j `nproc`
$ make install DESTDIR=<installation_prefix>

# GCC
$ cd <gcc_builddir>
$ <gcc_srcdir>/configure --prefix=/ --enable-languages=c,c++,fortran,lto --enable-checking=release --disable-bootstrap
$ make -j `nproc`
$ make install DESTDIR=<installation_prefix>

2.2. 自行编译 glibc 库

步骤与交叉编译相同,但运行 GCC configure 脚本时可省略 --target 选项。

©龙芯开源社区 all right reserved,powered by Gitbook文档更新时间: 2023-05-19 06:33:51

results matching ""

    No results matching ""

    results matching ""

      No results matching ""