glibc交叉编译_Archlinux 搭建 arm64/AArch64 交叉编译环境

0. 系统环境

系统:

  • Archlinux

工具版本:

  1. Binutils: 2.34-1
  2. GCC: 9.2.1+20200130-2
  3. GNU Make: 4.3

1. 编译交叉编译工具链

此部分参考博客。

交叉编译工具链需要用到至少七个工具(库):

  1. Binutils
  2. GCC
  3. glibc
  4. Linux Kernel
  5. MPFR
  6. GMP
  7. MPC

同时我们还有两个用于优化的库:

  1. isl
  2. CLooG

这两个库是可选的。

搭建完成后我们会获得一系列编译、链接工具,包括我们熟知的 gccld 等。

1.1 准备工作

首先建立三个目录,分别存放源码、构建文件和编译结果(也即我们需要的交叉编译工具链)

mkdir -p /path/to/cross-compile-src/
mkdir -p /path/to/cross-compile-build/
mkdir -p /path/to/cross-compile-install/
export CROSS_COMPILE_SRC=/path/to/cross-compile-src/
export CROSS_COMPILE_BUILD=/path/to/cross-compile-build/
export CROSS_COMPILE_INSTALL=/path/to/cross-compile-install/

将安装目录内未来会生成的 bin 目录加入 PATH(我以为这一步只是为了省事,为了不把环境变量搞乱我第一次尝试没有加,结果编译失败)

export PATH=$CROSS_COMPILE_INSTALL/bin:$PATH

接下来下载相应的包,笔者选用的软件包版本分别为(均为成文时最新稳定)

  1. Binutils 2.34
  2. GCC 9.2.0
  3. glibc 2.31
  4. Linux Kernel 4.14.172
  5. MPFR 4.0.2
  6. GMP 6.2.0
  7. MPC 1.1.0
  8. isl 0.18
  9. CLooG 0.18.1

下载相应的包

cd $CROSS_COMPILE_SRC
export GNU_MIRROR_SITE=https://mirrors.tuna.tsinghua.edu.cn/gnu/
export KERNEL_MIRROR_SITE=https://mirrors.tuna.tsinghua.edu.cn/kernel/

wget $GNU_MIRROR_SITE/binutils/binutils-2.34.tar.xz                 # binutils
wget $GNU_MIRROR_SITE/gcc/gcc-9.2.0/gcc-9.2.0.tar.xz                # gcc
wget $GNU_MIRROR_SITE/glibc/glibc-2.31.tar.xz                       # glibc
wget $KERNEL_MIRROR_SITE/v4.x/linux-4.14.172.tar.xz                 # kernel
wget $GNU_MIRROR_SITE/mpfr/mpfr-4.0.2.tar.xz                        # mpfr
wget $GNU_MIRROR_SITE/gmp/gmp-6.2.0.tar.xz                          # gmp
wget $GNU_MIRROR_SITE/mpc/mpc-1.1.0.tar.gz                          # mpc

# optional
wget ftp://gcc.gnu.org/pub/gcc/infrastructure/isl-0.18.tar.bz2      # isl
wget ftp://gcc.gnu.org/pub/gcc/infrastructure/cloog-0.18.1.tar.gz   # cloog

解压

for f in *.tar.xz;  do tar -xJf $f; done
for f in *.tar.bz2; do tar -xjf $f; done
for f in *.tar.gz;  do tar -xzf $f; done

建立 GCC 依赖库们的软链接

ln -s ../mfpr-4.0.2 gcc-9.2.0/mfpr      # mfpr
ln -s ../gmp-6.2.0 gcc-9.2.0/gmp        # gmp
ln -s ../mpc-1.1.0 gcc-9.2.0/mpc        # mpc

# optional
ln -s ../isl-0.18 gcc-9.2.0/isl         # isl
ln -s ../cloog-0.18.1 gcc-9.2.0/cloog   # cloog

设定编译时使用的线程数

export NPROC=`nproc`    # use all processors

1.2. 编译安装 Binutils

这个工具包将会被安装在 /path/to/cross-compile-gcc/install/bin 内,包括了交叉汇编器、交叉链接器等工具。

cd $CROSS_COMPILE_BUILD
mkdir binutils
cd binutils
$CROSS_COMPILE_SRC/binutils-2.34/configure  
    --prefix=$CROSS_COMPILE_INSTALL         
    --target=aarch64-linux                  
    --disable-multilib
make -j$NPROC
make install

1.3. 安装 Linux Kernel 头文件

这一步会将 Linux Kernel 头文件安装咋 $CROSS_COMPILE_INSTALL/aarch64-install/include,这样交叉编译链编译出的软件可以在目标平台中使用 Linux 系统调用。

cd $CROSS_COMPILE_SRC/linux-4.14.172
make                                                        
    ARCH=arm64                                              
    INSTALL_HDR_PATH=$CROSS_COMPILE_INSTALL/aarch64-linux   
    headers_install

1.4. 编译安装 GCC 和 glibc

这是很长的一步,我们将要轮流编译属于两个库(GCC 和 glibc)的组件,并最终全部编译完成。编译顺序如下(图源为参考博客)

glibc交叉编译_Archlinux 搭建 arm64/AArch64 交叉编译环境_第1张图片

1.4.1. 编译器

这一步只会安装 C/C++ 交叉编译器本身,它们会被安装在 $CROSS_COMPILE_INSTALL/bin

cd $CROSS_COMPILE_BUILD
mkdir gcc
cd gcc
$CROSS_COMPILE_SRC/gcc-9.2.0/configure  
    --prefix=$CROSS_COMPILE_INSTALL     
    --target=aarch64-linux              
    --enable-language=c,c++             
    --disable-multilib
make -j$NPROC all-gcc
make install-gcc

这一步要编译个十分钟左右。

1.4.2. 标准 C 头文件和启动文件

这一步里我们将所有的标准 C 头文件安装在 $CROSS_COMPILE_INSTALL/aarch64-linux/include 内。同时我们还会编译一些启动文件并安装在 $CROSS_COMPILE_INSTALL/aarch64-linux/lib 内,这些文件将被下一步用到,并在下下步被替换。

注意: 如果前面没有把 $CROSS_COMPILE_INSTALL/bin 加入到 PATH 中的话这一步会报错。

cd $CROSS_COMPILE_BUILD
mkdir glibc
cd glibc
$CROSS_COMPILE_SRC/glibc-2.31/configure                         
    --prefix=$CROSS_COMPILE_INSTALL/aarch64-linux               
    --build=$MACHTYPE                                           
    --host=aarch64-linux                                        
    --target=aarch64-linux                                      
    --with-headers=$CROSS_COMPILE_INSTALL/aarch64-linux/include 
    --disable-multilib                                          
    libc_cv_forced_unwind=yes
make install-bootstrap-headers=yes install-headers
make -j$NPROC csu/subdir_lib
install csu/crt1.o csu/crti.o csu/crtn.o $CROSS_COMPILE_INSTALL/aarch64-linux/lib
aarch64-linux-gcc -nostdlib -nostartfiles -shared -x c /dev/null 
    -o $CROSS_COMPILE_INSTALL/aarch64-linux/lib/libc.so
touch $CROSS_COMPILE_INSTALL/aarch64-linux/include/gnu/stubs.h

1.4.3. 编译器支持库

这一步我们使用前面编译得到的交叉编译器来编译编译器支持库。

cd $CROSS_COMPILE_BUILD/gcc
make -j$NPORC all-target-libgcc
make install-target-libgcc

1.4.4. 编译标准 C 库

这一步我们可以完成 glibc 的编译安装。标准 C 库将被安装于 $CROSS_COMPILE_INSTALL/aarch64_linux/lib

cd $CROSS_COMPILE_BUILD/glibc
make -j$NPROC
make install

这一步依然要十来分钟。

1.4.5. 编译标准 C++ 库

这一步我们可以完成 GCC 的编译安装。标准 C++ 库将被安装于 $CROSS_COMPILE_INSTALL/aarch64_linux/lib64

cd $CROSS_COMPILE_BUILD/gcc
make -j$NPROC
make install

注意:这一步可能出现如下错误

error: ‘PATH_MAX’ was not declared in this scope
  216 |       char filename[PATH_MAX];
      |                     ^~~~~~~~

看了编译命令发现没有将我们导入的 Linux 头文件加入 include 范围,因此编译时 include 的头文件来自系统的 Linux 头文件。因为编译 GCC 使用的头文件不一定是 GCC 运行时使用的头文件,所以这个问题理论上不会影响交叉编译的结果。我们只需要简单地修改下源码,将

#ifndef PATH_MAX
#  define PATH_MAX 4096
#endif  // PATH_MAX

加入 $CROSS_COMPILE_SRC/gcc-9.2.0/libsanitizer/asan/asan_linux.cc 即可。(如果有更好的方法请一定告诉我)

这一步依然需要十分钟左右。

1.5. 测试交叉编译器

aarch64-linux-gcc helloworld.c -o a.out
aarch64-linux-objdump -d a.out

1.6. 吐槽

你问我为什么不用 community 源里的 aarch64-linux-gnu-*

因为我瞎我没看到(哭)。

2. 交叉编译内核

(未完待续)

3. 安装内核

(未完待续)

你可能感兴趣的:(glibc交叉编译)