一、简介
本文主要讲解gcc交叉编译工具链搭建的全过程,以本人实际的操作去讲述整个工具链的搭建,希望对大家有所帮助。
二、工具链的搭建流程
1、下载相关源码:包括binutils、kernel、gcc、glibc等; 2、搭建本地编译环境,安装本地编译依赖包; 3、设置环境变量; 4、编译binutils; 5、复制Linux内核头文件; 6、建立初始编译器; 7、编译glibc; 8、建立全套编译器(full gcc); 9、 编译其他工具 10、创建链接; 11、工具链验证;
三、过程搭建详细讲解
3.1 下载相关源码 3.1.1 首先下载本次交叉编译工具需要的源码包具体如下: 1、binutils; 2、mpc、mpfr、gmp; 3、kernel; 4、gcc; 5、glic;
3.1.2 相关源码下载网址参考:
[root@localhost /]# lftp ftp:
[root@localhost /]# lftp ftp:
[root@localhost /]# lftp ftp:
[root@localhost /]# lftp ftp:
[root@localhost /]# lftp ftp:
lftp ftp.gnu.org:/gnu/gmp> mget gmp-6.1.1.tar.xz
[root@localhost /]# wget https:
[root@localhost /]# wget http:
其他依赖包: wget ftp://gcc.gnu.org/pub/gcc/infrastructure/isl-0.15.tar.bz2 wget ftp://gcc.gnu.org/pub/gcc/infrastructure/cloog-0.18.1.tar.gz
注:在解开的内核源码中Documentation/Changes中写明了该版本内核所需要依赖的各个包的版本以及下载的路径,注意下载的mpc、mpfr、gmp都尽量下载最新版本。
3.2 搭建本地编译环境,安装本地编译依赖包
[root@localhost /]# apt-get install xz-utils
[root@localhost /]# apt-get install m4
[root@localhost /]# apt-get install libncurses-dev
[root@localhost /]# apt-get install g++
[root@localhost /]# apt-get install gawk
3.3 设置环境变量
export TARGET=arm-linux-gnueabi
export PREFIX=/opt/cross/gcc-4.8.7
export TARGET_PREFIX=$PREFIX/$TARGET
export PATH=$PATH:$PREFIX/bin
--prefix 编译好的文件重定位安装路径,如make install后相关的可执行文件都安装在prefix指定的路径下
--build – 本地编译机器的平台架构,如x86
--host – 需要交叉编译成的平台架构,如arm64
--target – 执行的可执行代码的目标平台
也可以将其加入到.bashrc文件中打开终端后可以自动执行
[root@localhost /]# vim ~/.bashrc
[root@localhost /]# source ~/.bashrc
3.4 编译binutils 此步骤构建并安装交叉汇编器、交叉链接器和其他工具。
[root@localhost /]# tar -xjvf binutils-2.7.tar.gz
[root@localhost binutils-2.7]# cd binutils-2.7/
[root@localhost binutils-2.7]# ./configure --prefix=$PREFIX --target=$TARGET --disable-multilib
[root@localhost binutils-2.7]# make
[root@localhost binutils-2.7]# make install
此时在$PREFIX/bin下会生成部分交叉编译工具,说明已经编译成功,可用于后续的gcc、glic编译:
arm-linux-gnueabi-addr2line:将地址转成文件和行号,如:arm-linux-gnueabi-addr2line 地址xx -e vmlinux -f
arm-linux-gnueabi-ar:产生、修改和解开一个存档文件
arm-linux-gnueabi-as:GNU的汇编器
arm-linux-gnueabi-gprof:GNU汇编器预编译器
arm-linux-gnueabi-ld:GNU的连接器
arm-linux-gnueabi-nm:列出目标文件的符号和对应的地址
arm-linux-gnueabi-objcopy:将某种格式的目标文件转化成另外格式的目标文件
arm-linux-gnueabi-objdump:显示目标文件的信息
arm-linux-gnueabi-ranlib:为一个存档文件产生一个索引,并将这个索引存入存档文件中
arm-linux-gnueabi-readelf:显示 elf 格式的目标文件的信息
arm-linux-gnueabi-size:显示目标文件各个节的大小和目标文件的大小
arm-linux-gnueabi-strings:打印出目标文件中可以打印的字符串,有个默认的长度,为4
arm-linux-gnueabi-strip:剥掉目标文件的所有的符号信息
注:–disable-multilib 意味着我们只希望我们的Binutils安装使用AArch64指令集的程序和库,而不是任何相关指令集,如AArch32。
3.5 复制Linux内核头文件 这个步骤将Linux内核头文件安装到/opt/cross/gcc-4.8.7/include下,这将最终允许使用我们的新工具链构建的程序在目标环境中对arm64内核进行系统调用。
[root@localhost /]# cd linux-3.10.40
[root@localhost linux-3.10.40]# make ARCH=arm64 INSTALL_HDR_PATH=$PREFIX headers_install
[root@localhost /]# ls /opt/cross/gcc-4.8.7/include
asm asm-generic drm linux misc mtd rdma scsi sound uapi video xen
[root@localhost /]# ls /opt/cross/gcc-4.8.7/include/generated/uapi/linux/version.h
3.6 建立初始编译器(不带glibc支持)
[root@localhost /]# tar -xjvf gcc-4.8.7.tar.bz2
[root@localhost /]# tar -xjvf gmp-5.1.3.tar.bz2
[root@localhost /]# mv gmp-5.1.3 gcc-4.8.7/gmp
[root@localhost /]# tar -xjvf mpfr-3.1.2.tar.bz2
[root@localhost /]# mv mpfr-3.1.2 gcc-4.8.7/mpfr
[root@localhost /]# tar -xzvf mpc-1.0.1.tar.gz
[root@localhost /]# mv mpc-1.0.1 gcc-4.8.7/mpc
[root@localhost /]# cd gcc-4.8.7
[root@localhost gcc-4.8.7]# ./configure --prefix=$PREFIX --target=$TARGET --with-headers=$TARGET_PREFIX/include --enable-languages=c --disable-threads --disable-decimal-float --with-newlib --disable-shared --disable-nls --disable-libmudflap --disable-libssp
[root@localhost gcc-4.8.7]# make all-gcc
[root@localhost gcc-4.8.7]# make install-gcc
[root@localhost gcc-4.8.7]# make all-target-libgcc
[root@localhost gcc-4.8.7]# make install-target-libgcc
--enable-language=c用来告诉配置脚本,需要产生的编译器支持何种语言,现在只需支持C语言。虽然配置为c,c++也可以的
--disable-threads 是因为threads需要libc的支持,也可以在gcc目录下下载并解压glibc-linuxthreads-2.5.tar.bz2,然后使能--enable-threads。
--disable-decimal-float,需要libc的支持,而我们在初步编译的时候尚未生成libc
--disable-shared,既然是第一次安装ARM交叉编译工具,那么本机的glibc支持的应该是本机的编译工具库,而不是ARM交叉编译工具库。
由于没有arm的glibc,需要使用--disable-libmudflap和--disable-libssp,禁止两个边界检查使用的库。
完成之后,$PREFIX/bin下又多了几个文件:
arm-linux-gnueabi-cpp:GNU的C的预编译器
arm-linux-gnueabi-gcc:GNU的C语言编译器
arm-linux-gnueabi-gcc-4.8.7:GNU的C语言编译器,其实和arm-linux-gcc是一样的
arm-linux-gnueabi-gcov:gcc 的辅助测试工具,用来分析和优化程序
在/opt/cross/lib/gcc/arm-linux/4.8.7/中安装了两个静态库libgcc.a 和 libgcc_eh.a。 共享库libgcc_s.so安装到/opt/cross/arm-linux/lib64。
3.7 编译glibc
[root@localhost /]# tar -xvf glibc-2.20.tar.xz
[root@localhost glibc-2.20]# cd glibc-2.20
[root@localhost glibc-2.20]# export CC=$TARGET-gcc
[root@localhost glibc-2.20]# export CFLAGS="-g -O2 -march=armv6"
[root@localhost glibc-2.20]# ln -s $PREFIX/lib/gcc/arm-linux-gnueabi/4.8.7/libgcc.a $PREFIX/lib/gcc/arm-linux-gnueabi/4.8.7/libgcc_eh.a
[root@localhost glibc-2.20]# vim config.cache
libc_cv_forced_unwind=yes
libc_cv_c_cleanup=yes
libc_cv_arm_tls=yes
[root@localhost glibc-2.20]# ./configure --host=$TARGET --target=$TARGET --prefix=$TARGET_PREFIX --enable-add-ons --disable-profile --cache-file=config.cache --with-binutils=$PREFIX/bin --with-headers=$TARGET_PREFIX/include
[root@localhost glibc-2.20]# make all
[root@localhost glibc-2.20]# make install
3.8 建立全套编译器(full gcc)
[root@localhost /]# unset CC
[root@localhost /]# unset CFLAGS
[root@localhost /]# cd gcc-4.8.7/
[root@localhost gcc-4.8.7]# ./configure --prefix=$PREFIX --target=$TARGET --enable-shared --enable-languages=c,c++
[root@localhost gcc-4.8.7]# make
[root@localhost gcc-4.8.7]# make install
完成之后,$PREFIX/bin下又多了几个文件:
arm-linux-gnueabi-g++:GNU的c++编译器
arm-linux-gnueabi-c++:等同于arm-linux-gnueabi-g++
标准C库并将其文件安装到 /opt/cross/arm-linux/lib/。静态库名为libc.a,共享库名为libc.so。
3.9 编译其他工具加入到gcc中:如gdb [root@localhost /]# tar -xvf gdb-8.3.tar.bz2 [root@localhost /]# cd gdb-8.3 [root@localhost gdb-8.3]# ./configure --prefix=
P
R
E
F
I
X
?
?
t
a
r
g
e
t
=
PREFIX --target=
PREFIX??target=TARGET [root@localhost gdb-8.3]# make [root@localhost gdb-8.3]# make install
3.10 创建链接
[root@localhost /]# cd $PREFIX/bin
[root@localhost bin]# ln -s arm-linux-gnueabi-addr2line arm-linux-addr2line
[root@localhost bin]# ln -s arm-linux-gnueabi-ar arm-linux-ar
[root@localhost bin]# ln -s arm-linux-gnueabi-as arm-linux-as
[root@localhost bin]# ln -s arm-linux-gnueabi-c++ arm-linux-c++
[root@localhost bin]# ln -s arm-linux-gnueabi-c++filt arm-linux-c++filt
[root@localhost bin]# ln -s arm-linux-gnueabi-cpp arm-linux-cpp
[root@localhost bin]# ln -s arm-linux-gnueabi-elfedit arm-linux-elfedit
[root@localhost bin]# ln -s arm-linux-gnueabi-g++ arm-linux-g++
[root@localhost bin]# ln -s arm-linux-gnueabi-gcc arm-linux-gcc
[root@localhost bin]# ln -s arm-linux-gnueabi-gcc-4.8.2 arm-linux-gcc-4.8.2
[root@localhost bin]# ln -s arm-linux-gnueabi-gcov arm-linux-gcov
[root@localhost bin]# ln -s arm-linux-gnueabi-gdb arm-linux-gdb
[root@localhost bin]# ln -s arm-linux-gnueabi-gdbtui arm-linux-gdbtui
[root@localhost bin]# ln -s arm-linux-gnueabi-gprof arm-linux-gprof
[root@localhost bin]# ln -s arm-linux-gnueabi-ld arm-linux-ld
[root@localhost bin]# ln -s arm-linux-gnueabi-ld.bfd arm-linux-ld.bfd
[root@localhost bin]# ln -s arm-linux-gnueabi-nm arm-linux-nm
[root@localhost bin]# ln -s arm-linux-gnueabi-objcopy arm-linux-objcopy
[root@localhost bin]# ln -s arm-linux-gnueabi-objdump arm-linux-objdump
[root@localhost bin]# ln -s arm-linux-gnueabi-ranlib arm-linux-ranlib
[root@localhost bin]# ln -s arm-linux-gnueabi-readelf arm-linux-readelf
[root@localhost bin]# ln -s arm-linux-gnueabi-run arm-linux-run
[root@localhost bin]# ln -s arm-linux-gnueabi-size arm-linux-size
[root@localhost bin]# ln -s arm-linux-gnueabi-strings arm-linux-strings
[root@localhost bin]# ln -s arm-linux-gnueabi-strip arm-linux-strip
3.11 工具链验证 下面编写一个简单的C程序,使用建立的工具链。
[root@localhost /]# vi hello.c
#include<stdio.h>
int main(void)
{
printf("hellolinux/n");
return0;
}
[root@localhost /]# arm-linux-gcc hello.c -o hello –static (制作静态可执行文件)
[root@localhost /]# file hello
hello: ELF 32-bit LSB executable, ARM, version 1, statically linked, for GNU/Linux 2.0.0, not stripped
有如上输出表示编译ARM版本程序成功。 制作的可执行文件hello可以直接在目标机上运行。
|