构建交叉编译器

参考文章:https://github.com/cfenollosa/os-tutorial/tree/master/11-kernel-crosscompiler

0. 环境说明

  • ubuntu 16.04
  • gcc 4.9源码编译

1. 将环境变量导入

我使用的是oh-my-zsh,所以需要修改~/.zshrc,在文件末尾添加以下语句.

1
2
3
4
5
6
export CC=/usr/bin/gcc-5
export LD=/usr/bin/gcc-5

export PREFIX="/usr/local/i386elfgcc"
export TARGET=i386-elf
export PATH="$PREFIX/bin:$PATH"

使用source ~/.zshrc来激活修改。

2. 建立binutils

1
2
3
4
5
6
7
8
mkdir /tmp/src
cd /tmp/src
curl -O http://ftp.gnu.org/gnu/binutils/binutils-2.24.tar.gz # If the link 404's, look for a more recent version
tar xf binutils-2.24.tar.gz
mkdir binutils-build
cd binutils-build
../binutils-2.24/configure --target=$TARGET --enable-interwork --enable-multilib --disable-nls --disable-werror --prefix=$PREFIX 2>&1 | tee configure.log
make all install 2>&1 | tee make.log

可能在执行make的过程中会出错,我的原因是因为此时的用户没有对/usr/local文件夹修改的权限,所以我的解决办法是切换到root权限,命令如下:

1
su - root
若一直登录不上,可能的原因是未激活root用户,按以下命令激活root用户:
1
sudo passwd root

3. 创建gcc交叉编译器

1
2
3
4
5
6
7
8
9
10
cd /tmp/src
curl -O https://ftp.gnu.org/gnu/gcc/gcc-4.9.1/gcc-4.9.1.tar.bz2
tar xf gcc-4.9.1.tar.bz2
mkdir gcc-build
cd gcc-build
../gcc-4.9.1/configure --target=$TARGET --prefix="$PREFIX" --disable-nls --disable-libssp --enable-languages=c --without-headers
make all-gcc
make all-target-libgcc
make install-gcc
make install-target-libgcc

如果不出意外的话,在configure的过程中会出错,简略的信息为configure: error: Building GCC requires GMP 4.2+, MPFR 2.4.0+ and MPC 0.8.0+.,原因是需要这三个库的支持,而我们的电脑上没有或未能识别到,因此我们需要通过源码安装这三个库。

你也可以通过以下方式解决:在gcc目录下运行:./contrib/download_prerequisites,如果可以解决问题,可以直接跳过源码安装过程。

以下内容参考http://www.voidcn.com/article/p-glfdwmcg-dr.html ## 3.1 下载源码 从ftp://gcc.gnu.org/pub/gcc/infrastructure/下载:gmp-4.3.2.tar.bz2mpfr-2.4.2.tar.bz2mpc-0.8.1.tar.gz这三个文件。注意安装顺序,因为依赖问题,所以首先安装GMP,然后是MPFR,然后是MPC,为了避免权限问题,以下操作我均使用超级用户root 。 ## 3.2 安装GMP4.3.2 创建安装路径

1
mkdir /opt/gmp-4.3.2
解压源码压缩包
1
tar -jxvf gmp-4.3.2.tar.bz2
进入解压缩路径,配置并安装
1
2
3
cd gmp-4.3.2
./configure --prefix=/opt/gmp-4.3.2
make && make install
tips:--prefix选项指定安装的路径

3.3 安装MPFR2.4.2

1
2
3
4
5
mkdir /opt/mpfr2.4.2
tar -jxvf mpfr2.4.2.tar.bz2
cd mpfr2.4.2
./configure --prefix=/opt/mpfr-2.4.2 --with-gmp=/opt/gmp-4.3.2 --disable-shared --with-pic
make && make install

安装过程与安装GMP4.3.2基本一致,不过有一些需要注意的点: - 因为包之间有依赖关系,所以需要指定--with-gmp=/opt/gmp-4.3.2 - 指定了--disable-shared --with-pic参数,否则会出现relocation R_X86_64_32 can not be used when making a shared object; recompile with -fPIC该错误。

3.4 安装MPC0.8.1

1
2
3
4
5
mkdir /opt/mpc-0.8.1
tar -zxvf mpc0.8.1.tar.gz
cd mpc0.8.1
./configure --prefix=/opt/mpc-0.8.1 --with-gmp=/opt/gmp-4.3.2 --with-mpfr=/opt/mpfr-2.4.2 --disable-shared --with-pic
make && make install

注意点: - 注意指定依赖的包gmpmpfr - 区分tar.gztar.bz2的解压缩方式

3.5 导入包路径到环境变量

若未将包导入,或路径有错(比如我的MPC0.8.1未在后面加上/lib),就会出现configure: error: cannot compute suffix of object files: cannot compile错误。下面是导入的步骤。 打开/etc/profile文件,在末尾添加

1
2
# necessary libs for building cross-compiler gcc.
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/opt/gmp-4.3.2/lib:/opt/mpfr-2.4.2/lib/:/opt/mpc-0.8.1/lib
保存修改,并激活:
1
source /etc/profile

3.6 重新配置并生成GCC

1
2
3
4
5
6
cd /tmp/src/gcc-build
../gcc-10.1.0/configure --target=$TARGET --prefix="$PREFIX" --disable-nls --disable-libssp --enable-languages=c --without-headers --with-gmp=/opt/gmp-4.3.2 --with-mpfr=/opt/mpfr-3.1.4 --with-mpc=/opt/mpc-0.8.1
make all-gcc
make all-target-libgcc
make install-gcc
make install-target-libgcc

4. 结尾

若没有其他意外,我们已经成功生成了交叉编译器。congratulation!