linux4.12交叉编译链,交叉编译⼯具链(很详细)
了解到有crosstools可以⽅便的编译⼯具链,甚⾄还有编译好的下载,但是鉴于本⼈初学,什么都不懂,决定还是⾃⼰⼀步⼀步编译,权当熟 悉linux,熟悉⼀下编译流程了。花了⼀个多星期终于搞好了,其实第⼀次编译成功⽤了不到⼀个星期,为了写这篇⽂章和搞清楚其中的⼀些不明所以的地⽅, ⼜重新编译了两次,现在基本搞清楚了,发上来与⼤家共享。其实还有⼀些不明所以的地⽅,以后再说吧,实在不想再编译了。
中基是基于sa1110芯⽚的,主要部分和assabet开发板⼀样。以下linux头⽂件是基于这样的系统产⽣的,不过我想也能⽤于其他型号的芯⽚。
先说说我的编译环境,⼀台384M内存的p4电脑,win2000系统,开vmware虚拟机,装了⼀个puppy linux 3.01,这个linux以⼩巧见称。可想⽽知有多慢了。
个⼈感觉,编译这个很考⼈品,⼈品不好总会碰到⼀些稀奇古怪的问题。呵呵,我估计是那个⼈品最差的。
虽然我已经很⼩⼼,最后⼀遍命令都是粘贴上去执⾏的,后⾯⼜进⾏了⼀些修改,主要是安装⽬录,但⽂中难免有错漏,发现了请指出。
初学者可以尝试⾃⼰编译⼯具链,能够学到⼀下东西。
所有⽤到的软件都是最新版的。
好了,闲话少说,开⼲。
1.下载
ftp:///gnu/binutils/binutils-2.
ftp:///gnu/gcc/gcc-4.3.2/gcc-4.3.
ftp:///gnu/gdb/gdb-6.
ftp:///gnu/glibc/glibc-2.
ftp:///gnu/glibc/glibc-ports-2.
ftp:///pub/linux/kernel/v2.6/linux-2.6.
ftp:///pub/gmp-4.2.
2.建⽴⼯作⽬录
我的⼯作⽬录放在⼀个单独的盘上,/mnt/hdc1。你可以任选⼀个⽬录做⼯作⽬录,例如~/work。将下载的⽂件全部放到⼯作⽬录下。
⼯作⽬录中建⽴⽬录build,⽤来放解压后的源码和build时产⽣的⽂件,最终产⽣的⼯具放到/usr/armtools下。
3.设置环境变量
在etc/f中加上⼀⾏/usr/local/lib,⽤来设置动态库的搜索⽬录,已经有的话就不⽤加了,因为gmp和mpfr会装到这⾥,不加以后的编译通不过。
开⼀个终端窗⼝
export TARGET=arm-linux
export PREFIX=/usr/armtools
export PATH=$PATH:/usr/armtools/bin
export BUILD_DIR=/mnt/hdc1/build
4.安装gmp和mpfr库,这两个库是gcc需要的,⽼版本如果不⽤fortan77的话不需要,但新版本只编译c也需要。有的话就不⽤装了。
cd /mnt/hdc1 进⼊⼯作⽬录
cd buildlinux下gcc编译的四个步骤
tar -zxvf ../gmp-4.2. 这⾥有个技巧,打完gm后直接按tab键⽂件名会⾃动补全。后⾯需要输⼊⽬录的地⽅都可以这么⽤。cd gmp-4.2.4
./configure
make
make check ⽂档⾥说这个⾮常重要。
make install
cd ..
rm -rf gmp-4.2.4 装完源⽬录没⽤了,删掉,节省空间。
ldconfig /usr/local/bin
tar -zxvf ../mpfr-2.3. 这⾥有个技巧,打完gm后直接按tab键⽂件名会⾃动补全。后⾯需要输⼊⽬录的地⽅都可以这么⽤。cd mpfr-2.3.2
./configure
make
make check ⽂档⾥说这个⾮常重要。
make install
cd ..
rm -rf mpfr-2.3.2 装完源⽬录没⽤了,删掉,节省空间。
ldconfig /usr/local/bin 更新⼀下缓存
完成,这⼀步⼀般不会出问题。
5.编译binutils
tar -zxvf ../binutils-2.
mkdir binutils-2.18-build
cd binutils-2.18-build
../binutils-2.18/configure --target=$TARGET --prefix=$PREFIX
make
make install
cd ..
rm -rf binutils-2.18
rm -rf binutils-2.18-build
ok,这⼀步也很简单,完成后armtools⾥会有很多⽂件。
6.编译bootstrap gcc
tar -zxvf ../gcc-4.3.
mkdir gcc-4.3.2-build
cd gcc-4.3.2-build
../gcc-4.3.2/configure --target=$TARGET --prefix=$PREFIX --enable-languages=c --with-local-prefix=$PREFIX/arm-linux --without-headers --with-newlib --disable-shared --disable-threads --disable-libmudflap --disable-libssp
这⼀步参数⽐较多,⼤概说⼀下
--target=$TARGET ⽬标,arm-linux,就是要产⽣linux下编译arm程序的编译器
--prefix=$PREFIX 安装⽬录
--enable-languages=c 只产⽣c编译器
--with-local-prefix=$PREFIX/arm-linux 不知道有啥⽤,实在不想再编译⼀遍试验了,谁有空可以试试
不加⾏不⾏。
--without-headers 不使⽤头⽂件,因为还没有glibc
--with-newlib 这个不太明⽩,似乎是编译⼀个⾃带的库
--disable-shared 不编译共享库
--disable-threads 不编译线程⽀持
--disable-libmudflap 禁⽌mudflap库,这个库需要glibc⽀持
--disable-libssp 禁⽌ssp库,这个库需要glibc⽀持
make all-gcc 编译安装gcc
make install-gcc
make all-target-libgcc 编译安装库,不做的话编译glibc时不到库
make install-target-libgcc
cd ..
rm -rf gcc-4.3.2-build
7.建⽴linux头⽂件
tar -zxvf ../linux-2.6.
cd linux-2.6.27
make ARCH=arm menuconfig
菜单最下⾯选择load⼀个arm板⼦的config⽂件,我load的arch/arm/configs/assabet_defconfig,然后保存为.config。退出
make ARCH=arm CROSS_COMPILE=$PREFIX/bin/arm-linux- 出现CC什么的时候就可以停⽌了。
cd ..
2.6.27版和2.6.26.5版⽐⽬录结构发⽣了变化,所以编译glibc时要改路径,否则不到头⽂件。编译glibc时候⽤到了特定arm芯⽚(例如我⽤的sa1100)的头⽂件,难道编译出来的glibc只能⽤在特定的芯
⽚上吗,有知道的说⼀下。
8.编译glibc
tar -zxvf ../glibc-2.
cd glibc-2.7
tar -zxvf ../../glibc-ports-2. glibc本⾝是不⽀持arm等的,需要加这个port。
mv glibc-ports-2.7 ports
打补丁,sed -i 's/aaa/bbb/' file 就是把file⾥的aaa替换成bbb,bbb⾥⾯的&代表 aaa,\t代表tab,\n代表换⾏。你也可以⽤⽂本编辑器来做,⽤sed做要注意不要打错任何⼀个字符,空格啦,⼤⼩写啦都要注意。
sed -i 's/-nostdinc -isystem $ccheaders /-nostdinc -isystem $ccheaders -isystem $ccheaders-fixed /' configure.in
sed -i 's/-isystem $cxxheaders /-isystem $cxxheaders -isystem $cxxheaders-fixed /' configure.in
sed -i 's/# define UNDOCARGS_5\tUNDOCARGS_4/&\n\n# define DOCARGS_6\tUNDOCARGS_5\n# define
UNDOCARGS_6\tUNDOCARGS_5/' ports/sysdeps/unix/sysv/linux/arm/nptl/sysdep-cancel.h
sed -i 's/#include /&\n#include /' ports/sysdeps/unix/sysv/linux/arm/nptl/lowlevellock.h
sed -i 's/__deprecated/__attribute__((deprecated))/' ../linux-2.6.27/arch/arm/include/asm/memory.h
patch -p1 < ../../glibc-2.7-libgcc_eh-1.patch cd .. mkdir glibc-2.7-build cd glibc-2.7-build CC=arm-linux-gcc AR=arm-linux-ar RANLIB=arm-linux-ranlib ../glibc-2.7/configure --host=$TARGET --prefix=$PREFIX/$TARGET --enable-add-ons --with-headers=$BUILD_DIR/linux-2.6.27/include:$BUILD_DIR/linux-2.6.27/arch/arm/include:$BUILD_DIR/linux-
2.6.27/arch/arm/mach-sa1100/include libc_cv_forced_unwind=yes libc_cv_c_cleanup=yes cross_compiling=yes
build_alias=i386-linux-gnu 上⾯这句⾥的cross_compiling=yes build_alias=i386-linux-gnu不是必需的,我第⼀遍编 译时没加也通过了,但后来不知道为什么就不⾏了,如果出错或者make出错可以加上试试,主要是因为configure⾃动判定交叉编译判断错误,把交叉编译出来的⽂件在本地执⾏,当然
执⾏不了啦。 make make install cd .. rm -rf glibc-2.7-build rm -rf glibc-2.7 9.拷贝linux头⽂件 cp -r linux-2.6.27/include/linux $PREFIX/$TARGET/include cp -r linux-2.6.27/arch/arm/include/asm
$PREFIX/$TARGET/include mv $PREFIX/$TARGET/include/asm $PREFIX/$TARGET/include/asm-arm cp -r -f linux-
2.6.27/include/asm-arm $PREFIX/$TARGET/include cp -r linux-2.6.27/include/asm $PREFIX/$TARGET/include cp -r linux-2.6.27/include/asm-generic $PREFIX/$TARGET/include cp -r linux-2.6.27/arch/arm/mach-sa1100
$PREFIX/$TARGET/include mv $PREFIX/$TARGET/include/mach-sa1100 $PREFIX/$TARGET/include/mach 这些⽂件不但编译glibc gcc时有⽤,⽽且似乎在以后编译应⽤程序的时候也可能有⽤,因为glibc库的头⽂件⾥有包含他们,所以我把他们拷贝到安装⽬录⾥。 10.编译gcc mkdir gcc-4.3.2-build cd gcc-4.3.2-build ../gcc-4.3.2/configure --target=$TARGET --prefix=$PREFIX --enable-languages=c,c++ --with-local-prefix=$PREFIX/$TARGET make make install cd ../.. rm -rf build 到此,⼯具链就算装好了,可以写个hello world程序来试验⼀下了。 然后把我前⾯的艰⾟历程贴出来,如果⼤家编译的时候发⽣什么问题,可以在⾥⾯⼀下有没有我碰到过的。格式嘛,我就不排版了,⼤家凑活看吧。 1. 安装linux 的头⽂件,可以在编译glibc之前再做 * 个
⼈认为这⼀步得到的头⽂件应该只和arm有关,和arm什么板⼦,什么型号没多⼤关系 * 解压缩,打补丁 cd ~/tars/SourceDir tar -zxf ../linux-2.4. cd linux zcat ../../patch-2. | patch -p1 打补丁不知道为什么出错,先不打了。原来是patch-2.6.26.5.bz2是给linux-2.6.26打补丁的,不是给2.6.26.5打补丁的 * 修改 Makefile 建议先删除 .config ⽂件, 否这以后会遇到⿇烦。没⽤ * 将Makefile中ARCH := ......改为:ARCH=arm #。似乎没⽤ * 执⾏⼀下 make clean。⼀开始不需要 * 我的做法:make ARCH=arm menuconfig * 选择load⼀个arm板⼦的config⽂件,我load的ARCH/arm/configs/assabet_defconfig,然后保存为.config。退出 * make ARCH=arm dep * 加上ARCH=arm是因为不加的话会有好多提问,像是否⽀持多cpu等,后⾯的dep不知道什么意思,待查。 * 产⽣了
include/linux/autoconf.h,但是没有version.h。不知道是不是现在的版本不需要。 * ⽹上查的make dep的意思,不过还是不太明⽩ * dependence 依赖。 make dep的意思就是说:如果你使⽤程序A(⽐如⽀持特殊设备),⽽A需⽤到B(⽐如B是A的⼀ 个模块/⼦程序)。 ⽽你在做make config的时候将⼀个设备的驱动 由内核⽀持改为module,或取消⽀持,这将可能影响到B的⼀个参数 的设置,需重新编译B,重新编译或连接A....如果程序数量⾮常多, 你是很难⼿⼯完全做好此⼯作的。 所以,你要make dep。如果你make menu或make config 或make xconfig后,直接reboot,会更快。 只是你的内核根本没有任何改变。^=^ make xconfig; make dep; make clean; make bzImage; make modules; make mo
dules_install * ⼜作了⼀次,发现make dep现在不起作⽤,要⽤make ARCH=arm来建⽴头⽂件。* 要⽤make ARCH=arm CROSS_COMPILE=/mnt/home/arm/armtools/bin/arm-linux-来编译,必须先编译好bootstrap gcc后才能这样⽤ * 拷贝头⽂件,感觉不需要拷贝,编译glibc的时候加上路径就好了。 cp -dR include/linux ~/armtools/arm-linux/include cp -dR include/asm-arm ~/armtools/arm-linux/include/asm 1. 编译安inutils  * 解压缩 cd ~/tars/SourceDir tar -zxf
../ * 编译 cd ~/tars/BuildDir mkdir binutils cd binutils ../../SourceDir/binutils-2.11/configure --target=arm-linux --prefix=~/armtools make all install * 这⼀步没什么问题,很顺利 2. 编译安装gcc 的c 编译器  * 解压缩 cd ~/tars/SourceDir tar -zxf ../gcc-2.95. * 修改gcc 的t-linux ⽂件在t-linux⽂件中的TARGET_LIBGCC2_CFLAGS上加上__gthr_posix_h
inhibit_libc cd gcc-2.95.3/ gcc/config/arm mv t-linux t-linux-orig sed 's/TARGET_LIBGCC2_CFLAGS
=/TARGET_LIBGCC2_CFLAGS = -D__gthr_posix_h -Dinhibit_libc/' <> t-linux-core
cp ./t-linux-core ./t-linux
*
编译
cd ~/tars/BuildDir
mkdir gcc-core
cd gcc-core
../../SourceDir/gcc-2.95.3/configure \
--target=arm-linux \
--prefix=~/armtools \
--enable-languages=c \
--with-local-prefix=~/armtools/arm-linux \
--without-headers \
--with-newlib \
--disable-shared
make all install
* ./configure 时需要gmp和mpfr库⽀持,下载,安装,顺利,已做成pet包。换了⼀台机重新编译的时候,发现编译mpfr的时候会出错,不到库,还是要加上下⾯那个路径。
* ./configure 通过
* make 出错,查看arm-linux/libgcc/config.log,说不到libmpfr.so.1,估 计是做的pet包没有将ld搜索路径加上,先加上环境变量试下,回头再修改pet包。 export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib
* 加上后上个问题没有了,⼜有新问题。
* config.log says:
* configure:2747: checking for /mnt/hdc1/build/gcc-core/./gcc/xgcc -B/mnt/hdc1/build/gcc-core/./gcc/ -
B/mnt/hdc1/armtools/arm-linux/bin/ -B/mnt/hdc1/armtools/arm-linux/lib/ -isystem /mnt/hdc1/armtools/arm-
linux/include -isystem /mnt/hdc1/armtools/arm-linux/sys-include option to accept ANSI C
configure:2817: /mnt/hdc1/build/gcc-core/./gcc/xgcc -B/mnt/hdc1/build/gcc-core/./gcc/ -B/mnt/hdc1/armtools/arm-linux/bin/ -B/mnt/hdc1/armtools/arm-linux/lib/ -isystem /mnt/hdc1/armtools/arm-linux/include -isystem
/mnt/hdc1/armtools/arm-linux/sys-include -c -O2 -g -g -O2 conftest.c >&5
conftest.c:10:19: error: stdio.h: No such file or directory
conftest.c:11:23: error: sys/types.h: No such file or directory
conftest.c:12:22: error: sys/stat.h: No such file or directory
conftest.c:15: error: expected '=', ',', ';', 'asm' or '__attribute__' before '*' token
conftest.c:44: error: expected declaration specifiers or '...' before 'FILE'
configure:2823: $? = 1
* try to add --disable-libiberty and make it
* 上⾯的没⽤,改--disable-shared为--disable-threads,似乎这个错误过去了
* 发现修改t-linux⾥的-D__gthr_posix_h这个现在已经没⽤了。-Dinhibit_libc这个参数似乎可以⽤--with-newlib代替。
* 然后⼜出不到crti.o的错误。重新加上--disable-shared,搞定
* 然后⼜出问题,c编译器不能建⽴可执⾏⽂件。不到crt1.o。查看发现gcc编译完后进⾏了编译测试,但这时候还没有这些启动⽂件,据说这些是编译glibc产⽣的。
* configure时加上--disable-libmudflap,不加似乎也⾏,不要理会错误,直接make install就可以把gcc装上了。似乎有问题,make glibc的时候不到头⽂件。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。