Linux基础——构建工具链

来源:互联网 发布:苹果mac怎么更新不了 编辑:程序博客网 时间:2024/06/15 18:56

基础

Linux的编译分为4个阶段:编译预处理,编译,汇编和链接。

每个阶段都使用若干的工具,大部分情况下我们使用GNU提供的工具,包括Binutils,GCC和Glibc。

本文的目的就是用来生成这些工具。

本文以《深度探索Linux操作系统》为基础(下文以“参考书”为称),使用的操作系统是Ubuntu 14.04。



准备工作

1. 某些情况下需要我们所在的普通用户执行一些超级用户才有权限使用的命令,因此要设置普通用户为sudoer,在/etc/sudoers.d目录下添加一个文件,如下:



之后执行带sudo前缀的命令就不需要输入密码了。

2. 创建生成工具时需要的目录:


3. 设定环境变量:


unset LANGexport HOST=x86_64-pc-linux-gnuexport BUILD=$HOSTexport TARGET=x86_64-none-linux-gnuexport CROSS_TOOL=/home/jw/Linux/cross-toolexport CROSS_GCC_TMP=/home/jw/Linux/cross-gcc-tmpexport SYSROOT=/home/jw/Linux/sysrootPATH=$CROSS_TOOL/bin:$CROSS_GCC_TMP/bin:/sbin:/usr/sbin:$PATH
这些环境变量设置在普通用户(jw)的.bashrc文件中。需要通过source .bashrc使之生效。

这里的unset LANG根据参考书中的说明是为了防止在中文环境下的一些麻烦。

HOST,BUILD和TARGET是为了对应Binutils,GCC和Glibc的配置文件中会使用的参数,它们的只来自MACHTYPE这个环境变量,TARGET中的值包含none,这么做是为了构建交叉编译环境,所以需要跟HOST不同。


构建Binutils

1. 进入build目录。

2. 通过命令tar xvf xxx来压缩binutils源代码到build目录,本文使用的源代码xxx是binutils-2.23.1.tar.bz2。

3. 创建新的目录binutils-build。

4. 进入binutils-build目录,运行configure:

../binutils-2.23.1/configure --prefix=$CROSS_TOOL --target=$TARGET --with-sysroot=$SYSROOT --disable-werror
这里就用到了之前定义的环境变量,最后一个--disable-werror是为了防止编译使用。

5. make,确保没有报错。

6. make install,确保没有报错。

完成之后生成的工具如下:


除此之外还有链接脚本:


以上就是Binutils的构建。


构建freestanding的交叉编译器

freestanding的意思是不依赖于外部的c库。

1. 解压gcc源文件,文本使用的是gcc-4.7.3.tar.bz2。

2. 此外还需要一些库:gmp-5.0.5.tar.bz2,mpfr-3.1.1.tar.bz2和mpc-1.0.1.tar.gz,将它们压缩到gcc目录下的gmp/mpfr/mpc目录下。

3. 在build目录下创建gcc-build目录,进入该目录,准备configure。

4. configure命令如下:

../gcc-4.7.3/configure --prefix=$CROSS_GCC_TMP --target=$TARGET --with-sysroot=$SYSROOT --with-newlib --enable-languages=c --with-mpfr-include=/home/jw/Linux/build/gcc-4.7.3/mpfr/src --with-mpfr-libs=/home/jw/Linux/build/gcc-build/mpfr/src/.libs --disable-shared --disable-threads --disable-decimal-float --disable-libquadmath --disable-libmudflap --disable-libgomp --disable-nls --disable-libssp --disable-werror
5. 之后就是make加make install。

过程中报了一些错误,虽然前面已经制定了gmp,mpfr,但是编译时还是会报错,通过安装libgmp-dev和libmpfr-dev可以解决,但是感觉还是有点不对,暂且不管。

编译安装完成够可以在以下目录找到:


这里使用的目录是cross-gcc-tmp,实际上这个并不是最终的交叉编译器。这个编译器的作用就是为了后面构建Glibc,因此disable掉了很多不需要的功能。

还有最后的一步,前面configure的时候使用了--disable-shared,因此编译的时候没有生成libgcc_eh.a,而之后编译的Glibc的时候需要用到它,因此这里使用将创建libgcc.a的符号链接libgcc_eh.a来解决:



构建Glibc

构建之前的工作:

1. 编译器准备,就是前面一节的内容。

2. 安装内核头文件,这里使用的内核是linux-3.7.4.tar.xz。

下面先介绍头文件的安装:

1. 首先解压缩Linux源代码,并运行make mrproper清理内核:


2. 头文件合法化检查:


3. 安装:



安装完头文件之后,就可以开始编译Glibc。

但是在此之前需要先安装gawk,根据参考书上的说法是因为Ubuntu上的mawk与Glibc中awk脚本的兼容性问题。

下面是编译Glibc的步骤:

1. 解压Glibc源文件,这里使用的是glibc-2.15.tar.xz。

2. 进入源代码目录,打上patch:

patch -p1 < ../../../Sources/glibc-2.15-cpuid.patch patch -p1 < ../../../Sources/glibc-2.15-s_frexp.patch 
3. 创建单独的编译目录并进入该目录
4. configure:

../glibc-2.15/configure --prefix=/usr --host=$TARGET --enable-kernel=3.7.4 --enable-add-ons --with-headers=$SYSROOT/usr/include libc_cv_forced_unwind=yes libc_cv_c_cleanup=yes libc_cv_ctors_header=yes

5. 运行make。

6. make成功之后就是安装,命令如下:

make install_root=$SYSROOT install
这样Glibc就安装到了sysroot目录下了,如下图所示:


Glibc主要安装了如下的内容:

1. 基本的C库,主要在lib64和usr/lib64中;

2. 动态链接器,这里就是lib64/ld-2.15.so;

3. 头文件,它们在usr/include目录下;

4. 一些工具,在sbin,usr/bin和usr/sbin里面;

5. 启动文件,如图所示:


构建完整的交叉编译器

与之前构建freestanding编译器并没有实际的区别,只不过在configure的时候参数有变化:

1. 删除原先gcc-build中的内容。

2. 使用configure命令,具体如下:

../gcc-4.7.3/configure --prefix=$CROSS_TOOL --target=$TARGET --with-sysroot=$SYSROOT --with-mpfr-include=/home/jw/Linux/build/gcc-4.7.3/mpfr/src --with-mpfr-lib=/home/jw/Linux/build/gcc-build/mpfr/src/.libs --enable-languages=c,c++ --enable-threads=posix

3. 之后还是运行make以及make install。

这里在make的时候出现了问题,显示没有stubs-32.h文件,通过configure的时候添加--disable-multilib可以解决这个问题,但是在链接时又出现了其它问题:

/home/jw/Linux/cross-tool/x86_64-none-linux-gnu/bin/ld: cannot find crti.o: No such file or directory
(之所以之前编译freestanding版本的时候没有出这问题是因为参数--disable-shared)

但是实际上是有这些文件的:


所以怀疑可能跟目录有关,ld没有到这个目录下寻找?另外是不是跟--disable-multilib有关?

实际上将上图中的lib64复制一份改名位lib后,就可以正常编程和安装。(不确定是否可以这么做......)

安装完成后在cross-tool中就可以找到相关的文件:



安装完成之后可以查看刚生成的gcc:


并且可以用它来编译文件:


编译出来的a.out也可以正常使用。


0 0
原创粉丝点击