Archlinux 搭建 arm64/AArch64 交叉編譯環境


Archlinux 搭建 arm64/AArch64 交叉編譯環境

0. 系統環境

系統:

  • Archlinux: 成文時間最新

工具版本:

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

1. 編譯交叉編譯工具鏈

此部分參考博客

交叉編譯工具鏈需要用到至少七個工具(庫):

同時我們還有兩個用於優化的庫:

這兩個庫是可選的。

搭建完成后我們會獲得一系列編譯、鏈接工具,包括我們熟知的 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

接下來下載相應的包,筆者選用的軟件包版本分別為(除 Linux Kernel 外均為成文時最新穩定)

軟件名 版本
Binutils 2.34
GCC 9.2.0
glibc 2.31
Linux Kernel 4.14.172
MPFR 4.0.2
GMP 6.2.0
MPC 1.1.0
isl 0.18
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)的組件,並最終全部編譯完成。編譯順序如下(圖源為參考博客)

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. 安裝內核

(未完待續)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM