linux装交叉编译过程,交叉编译环境的概念以及建⽴步骤
什么是交叉编译?
交叉编译(cross-compilation)是指,在某个主机平台上(⽐如PC上)⽤交叉编译器编译出可在其他平台上(⽐如ARM上)运⾏的代码的过程。
具体:
交叉编译这个概念的出现和流⾏是和嵌⼊式系统的⼴泛发展同步的。我们常⽤的计算机软件,都需要通过编译的⽅式,把使⽤⾼级计算机语⾔编写的代码(⽐如 C代码)编译(compile)成计算机可以识别和执⾏的⼆进制代码。⽐如,我们在 Windows 平台上,可使⽤ Visual C++开发环境,编写程序并编译成可执⾏程序。这种⽅式下,我们使⽤ PC 平台上的 Windows ⼯具开发针对 Windows 本⾝的可执⾏程序,这种编译过程称为 native compilation,中⽂可理解为本机编译。然⽽,在进⾏嵌⼊式系统的开发时,运⾏程序的⽬标平台通常具有有限的存储空间和运算能⼒,⽐如常见的 ARM 平台,其⼀般的静态存储空间⼤概是 16 到 32 MB,⽽ CPU 的主频⼤概在 100MHz 到 500MHz 之间。这种情况下,在 ARM 平台上进⾏本机编译就不太可能了,这是因为⼀般的编译⼯具链(compilation tool chain)需要很⼤的存储空间,并需要很强的 CPU 运算能⼒。为了解决这个问题,交叉编译⼯具就应运⽽⽣了。通过交叉编译⼯具,我们就可以在 CPU 能⼒很强、存储控件⾜够的主机平台上(⽐如 PC 上)编译出针对其他平台的可执⾏程
序。
要进⾏交叉编译,我们需要在主机平台上安装对应的交叉编译⼯具链(cross compilation tool chain),然后⽤这个交叉编译⼯具链编译我们的源代码,最终⽣成可在⽬标平台上运⾏的代码。常见的交叉编译例⼦如下:
在 Windows PC 上,利⽤ ADS(ARM 开发环境),使⽤ armcc 编译器,则可编译出针对 ARM CPU 的可执⾏代码。
在 Linux PC 上,利⽤ arm-linux-gcc 编译器,可编译出针对 Linux ARM 平台的可执⾏代码。
在 Windows PC 上,利⽤ cygwin 环境,运⾏ arm-elf-gcc 编译器,可编译出针对 ARM CPU 的可执⾏代码。
另外,在业界⼴泛使⽤嵌⼊式 Linux 操作系统的今天,⼤多数交叉编译过程都是在 Linux PC 平台上完成。这时,程序员会在某个运⾏Linux 操作系统的 PC 上安装交叉编译⼯具链,并使⽤ GNU 提供的开发⼯具⽅便地开发和调试嵌⼊式应⽤软件。
⼀步⼀步的制作arm-linux交叉编译环境
我们使⽤以下版本的⽂件为例⼦建⽴ arm-linux 交叉编译环境:
编译环境 redhat 7.2 或 8.0
binutils-2.-core-2.95.-g++2.95.libc-2.2.libc-linuxthreads-2.2.linux-
2.4.patch-2. # linux kernel patch for arm我们在 bash 下⼯作,先设定⼀些变量:
$ export VBINUTILS=2.14
$ export VGCC=2.95.3
$ export VGLIBC=2.2.4
$ export VLINUX=2.4.21
$ export VLINUX_PATCH=rmk1
$
$ export PREFIX=/armtools
$ export TARGET=arm-linux
你可以把它们加到 .bashrc 中。如果你这么做了,你需要 logout 再 login 才能⽣效。
否则在 bash 的命令⾏上输⼊它们并⽴即⽣效,但你 logout 再 login 时它就⽆效了。
我们的⼯作路径是:
...../ ----- ~ -- tars -------- SourceDir
............|................|---- BuildDir
............|--- armtools
$ cd ~
$ mkdir -p tars/SourceDir
$ mkdir tars/BuildDir
$ mkdir arm_tools
$ su
# mv arm_tools $PREFIX
# exit
$
tars --------------- 在这⾥放我们的下载来的 . ⽂件
SourceDir ------ 这个临时⽬录放我们解压缩后的源⽂件
BuildDir --------- 我们在这⾥编译
armtools -------- 把arm-linux 交叉编译环境的安装在这⾥
linux下gcc编译的四个步骤1.安装linux 的头⽂件
当你为不同类型的ARM编译gcc,或编译不同版本的kernel,或交叉编译gcc 时都需要⼀套不同的linux头⽂件。
1.1解压缩,打补丁
$ cd ~/tars/SourceDir
$ tar -zxf ../linux-$
$ cd linux
$ zcat ../../patch- $VLINUX-$ | patch -p1
1.2清理⼀下
$ make mrproper
1.3修改 Makefile
将Makefile中ARCH := $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ -e s/arm.*/arm/ -e s/sa110/arm/) 这⼀⾏注释掉,并加⼀⾏ ARCH=arm。修改后象这样:
ARCH=arm
# ARCH := $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ -e s/arm.*/arm/ -e s/sa110/arm/)
如果你的系统⾥的 sed 程序⽀持⽤ '\' 续⾏(通常都⽀持),你可以⽤这个 script 去修改 Makefile
#!/bin/sh
mv ig
sed 's/ARCH := $(shell uname -m/ARCH=arm# ARCH := $(shell uname -m/' < ig > Makefile
#end of script
注意:
这个 script ⾥的 # ARCH := 是上⼀⾏的续⾏,不是 shell ⾥的注释,它也是要输⼊的。
如果你从浏览器(IE, netscape, etc)上 copy-paste 这个 script 到你的 bash console,它很有可能不⼯作;但你在 bash console ⾥⼿⼯输⼊就可以⼯作。
因为有时 copy 过来后,是 'ARCH=arm\r\n',⽽能⼯作的是 'ARCH=arm\n'。
1.4建⽴连接
1.4.1如果是LART板⼦
$ make lart_config
$ yes "" | make oldconfig
$ make include/linux/version.h
或:
$ make lart_config
$ make menuconfig 选择
⽹上有的⽂章⽤的是:
$ make symlinks include/linux/version.h
那是不完全的。make symlinks 的作⽤相当于:
$ cd include/asm-arm
$ rm -f arch proc
$ ln -s arch-sa1100 arch
$ ln -s proc-armv proc
$ cd ../../
它并没有产⽣⼀个很重要的⽂件 include/linux/autoconf.h。
⽽ yes "" | make oldconfig 不仅是 make symlinks,
还产⽣了 include/linux/autoconf.h。但它也没有产⽣
include/linux/version.h。
1.4.2如果是clps711x的CPU
连接应该为:
$ cd include/asm-arm
$ rm -f arch proc
$ ln -s arch-clps711x arch
$ ln -s proc-armv proc
$ cd ../../
为你⾃⼰的系统定制:
$ make menuconfig
在这⾥你只需要选你使⽤的 CPU 或选则有你使⽤的 CPU 的板⼦即可,
当然进⾏更详细的配置更好。
注:
include/asm-arm/proc-armo 是26位ARM
include/asm-arm/proc-armv 是32位ARM
注:背景知识
在ARM1中实现26位地址空间,但没有被商⽤。
在ARM2,2a 中还有26位地址空间,现在已经废弃。
在ARM3中扩展到32位地址空间,但是还反向兼容26位。
在ARM4中是32位地址空间,停⽌兼容26位地址空间。在 T 系列中加⼊ Thumb 指令。
在ARM5中是32位地址空间,在所有系列中均⽀持 16 位的 Thumb 指令。
1.5拷贝头⽂件
$ mkdir -p $PREFIX/$TARGET/include
$ cp -dR include/linux $PREFIX/$TARGET/include
$ cp -dR include/asm-arm $PREFIX/$TARGET/include/asm
1.6为 gcc 建⽴⼀个 linux kernel 头⽂件的连接
编译gcc时,它需要 linux kernel 的头⽂件,你可以⽤ --with-headers=$PREFIX/$TARGET/include 来指定头⽂件的位置,gcc 把它拷贝到 $PREFIX/$TARGET/sys-include。我们可以建⽴个 sys-include 连接,就不⽤ --with-headers 了。
$ cd $PREFIX/$TARGET
$ ln -s include sys-include
2编译安inutils
这⾥⽤不到前⾯准备的 linux 头⽂件
2.1解压缩
$ cd ~/tars/SourceDir
$ tar -zxf ../binutils-$
2.2编译
$ cd ~/tars/BuildDir
$ mkdir binutils
$ cd binutils
$ ../../SourceDir/binutils-$VBINUTILS/configure --target=$TARGET --prefix=$PREFIX
$ make all install
2.3输出 binutils 的路径到环境变量中
你可以把它加到 .bashrc 中。如果你这么做了,你需要 logout 再 login 才能⽣效。
否则在 bash 的命令⾏上输⼊它并⽴即⽣效,但你 logout 再 login 时它就⽆效了。
export PATH=$PREFIX/bin:$PATH
3.编译安装gcc 的c 编译器
3.1解压缩
$ cd ~/tars/SourceDir
$ tar -zxf ../gcc-core-$
注意:为什么不⽤ all-in-one 的 gcc-$ 呢?
all-in-one 的 gcc 包⾥⾯有 chill, fortran, java 等语⾔的编译器,虽然在下⾯ configure 时指定 -enable-languages=c,但编译时还是把所有的都编译⼀便,这不是我们需要的,⽽且它也总会有错误。因此我们只编译 C 语⾔的编译器。后⾯第⼆次编译的时候也是这个问题,我们只编译 C 和 C++ 的编译器。
3.2修改 gcc 的 t-linux ⽂件
在 t-linux ⽂件中的 TARGET_LIBGCC2_CFLAGS 上加上 __gthr_posix_h 和 inhibit_libc
$ cd gcc-$VGCC/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-orig > t-
linux-core
$ cp ./t-linux-core ./t-linux
3.4编译
$ cd ~/tars/BuildDir
$ mkdir gcc-core
$ cd gcc-core
$ ../../SourceDir/gcc-$VGCC/configure --target=$TARGET --prefix=$PREFIX --enable-languages=c --disable-shared --disable-threads
$ make all install
4.编译安装 glibc
4.1解压缩
$ cd ~/tars/SourceDir
$ tar -zxf ../glibc-$
$ cd glibc-$VGLIBC
$ tar -zxf ../../glibc-linuxthreads-$
4.2编译
$ cd ~/tars/BuildDir
$ mkdir glibc
$ cd glibc
$ CC=$TARGET-gcc AR=$TARGET-ar RANLIB=$TARGET-ranlib ../../SourceDir/glibc-$VGLIBC/configure $TARGET --
prefix=$PREFIX/$TARGET --enable-add-ons
$ make all install
5.编译安装gcc 的c, c++ 编译器
5.1恢复t-linux ⽂件

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