How To Build GCC 4.8.2 ARM Cross-Compiler

How To Build GCC 4.8.2 ARM Cross-Compiler


Intro


In this How To we are going to build an ARM cross-compiler based upon GCC 4.8.2. Before you begin you might want to take a look at my build machine specs to get an idea of what I'm running on compared to your machine. In the least please make sure you have enough memory. Do not expect a flawless build, especially if you are only running with 1 to 2 GB of memory 8P If you run into issues try to figure them out. Just for some perspective, the ~/workbench/gcc-4.8.2 directory on my machine is approx. 4 GB when all is done.

Tar Balls


Here is a list of source packages that we'll need for the build. You can either download them now or wait 'til later in the How To.
  • binutils-2.23.2.tar.bz2
  • glibc-2.18.tar.gz
  • gcc-4.8.2.tar.bz2
  • gmp-4.3.2.tar.bz2
  • mpfr-2.4.2.tar.bz2
  • mpc-0.8.1.tar.gz
  • linux-2.6.38.tar.bz2

Create a Workspace


I recommend creating a workspace under your /home/<your user>/ directory that is dedicated to this build. So let's fire up your terminal and run the following:
$ export SRCDIR=~/workbench/gcc-4.8.2/xtools/src
$ mkdir -pv ~/workbench/gcc-4.8.2/xtools
$ mkdir $SRCDIR
$ cd $SRCDIR

Gather the Sources


Now that we have a workspace created and we are currently in the src directory we can begin bringing down the sources and extracting them.

binutils

$ wget http://ftp.gnu.org/gnu/binutils/binutils-2.23.2.tar.bz2
$ tar -pxjf binutils-2.23.2.tar.bz2

glibc

$ wget http://ftp.gnu.org/gnu/glibc/glibc-2.18.tar.gz
$ tar -pxzf glibc-2.18.tar.gz
 

gcc

Refer to gcc-4.8.2/contrib/download_prerequisites for rcommended gmp, mpfr, and mpc
$ wget http://ftp.gnu.org/gnu/gcc/gcc-4.8.2/gcc-4.8.2.tar.bz2
$ wget http://ftp.gnu.org/gnu/gmp/gmp-4.3.2.tar.bz2
$ wget http://ftp.gnu.org/gnu/mpfr/mpfr-2.4.2.tar.bz2
$ wget ftp://gcc.gnu.org/pub/gcc/infrastructure/mpc-0.8.1.tar.gz
$ tar -pxjf gcc-4.8.2.tar.bz2
$ cd gcc-4.8.2/
$ tar -pxjf ../gmp-4.3.2.tar.bz2
$ tar -pxjf ../mpfr-2.4.2.tar.bz2
$ tar -pxzf ../mpc-0.8.1.tar.gz
$ mv gmp-4.3.2/ gmp
$ mv mpfr-2.4.2/ mpfr
$ mv mpc-0.8.1/ mpc
$ cd $SRCDIR

kernel

$ wget http://www.kernel.org/pub/linux/kernel/v2.6/linux-2.6.38.tar.bz2
$ tar -pxjf linux-2.6.38.tar.bz2

Build Environment


To make things a little smoother let's setup some environment variables:
$ export BINUTILS_SRC=$SRCDIR/binutils-2.23.2
$ export KERNEL_SRC=$SRCDIR/linux-2.6.38
$ export GCC_SRC=$SRCDIR/gcc-4.8.2
$ export GLIBC_SRC=$SRCDIR/glibc-2.18
$ export BUILDDIR=~/workbench/gcc-4.8.2/xtools/build
$ export TARGETMACH=arm-none-linux-gnueabi
$ export BUILDMACH=i686-pc-linux-gnu
$ export INSTALLDIR=~/workbench/gcc-4.8.2/arm
$ export SYSROOTDIR=$INSTALLDIR/sysroot
Next up is to begin building.

Build binutils


$ mkdir $BUILDDIR
$ mkdir $BUILDDIR/binutils
$ cd $BUILDDIR/binutils
$ $BINUTILS_SRC/configure --disable-werror --build=$BUILDMACH --target=$TARGETMACH --prefix=$INSTALLDIR --with-sysroot=$SYSROOTDIR
$ make
$ make install
Hopefully that went without any errors ;-) If not, try to figure them out. When you are ready to go and/or fixed any errors move to the next step.

Kernel Headers


I'm building this cross-compiler for the PandaBoard thus for ARCH I'm using arm omap2plus_defconfig. Substitute your own board here. In any case, make sure you're specify the correct architecture, i.e. arm.
$ cd $KERNEL_SRC
$ make mrproper
$ make ARCH=arm omap2plus_defconfig
$ mkdir -pv $INSTALLDIR/sysroot/usr
$ make ARCH=arm headers_check
$ make ARCH=arm INSTALL_HDR_PATH=$INSTALLDIR/sysroot/usr headers_install
$ cd $SRCDIR
Easy peasy. Next is our first go around with gcc.

Bootstrap gcc


$ mkdir $BUILDDIR/bootstrap-gcc
$ cd $BUILDDIR/bootstrap-gcc
$ $GCC_SRC/configure --build=$BUILDMACH --host=$BUILDMACH --target=$TARGETMACH --prefix=$INSTALLDIR --without-headers --enable-boostrap --enable-languages="c" --disable-threads --enable-__cxa_atexit --disable-libmudflap --with-gnu-ld --with-gnu-as --disable-libssp --disable-libgomp --disable-nls --disable-shared
$ make all-gcc install-gcc
$ make all-target-libgcc install-target-libgcc
$ ln -s $INSTALLDIR/lib/gcc/arm-none-linux-gnueabi/4.8.2/libgcc.a $INSTALLDIR/lib/gcc/arm-none-linux-gnueabi/4.8.2/libgcc_sh.a
Not too bad I hope :o)

glibc Headers - If binutils is not compatible with glibc this is where it will fail

NOTE: Make sure you have gawk installed (else you get an error similar tothis).

$ mkdir -pv $BUILDDIR/libc
$ cd $BUILDDIR/libc
$ echo "libc_cv_forced_unwind=yes" > config.cache
$ echo "libc_cv_c_cleanup=yes" >> config.cache
$ export PATH=$INSTALLDIR/bin:$PATH
$ export CROSS=arm-none-linux-gnueabi
$ export CC=${CROSS}-gcc
$ export LD=${CROSS}-ld
$ export AS=${CROSS}-as
$ $GLIBC_SRC/configure --build=$BUILDMACH --host=$TARGETMACH --prefix=$SYSROOTDIR/usr --with-headers=$SYSROOTDIR/usr/include --config-cache --enable-kernel=2.6.0
$ make -k install-headers cross_compiling=yes install_root=$SYSROOTDIR
 
*** We need to move some files ***
$ pushd $SYSROOTDIR/$INSTALLDIR/sysroot/usr/include
$ cp -rv * $SYSROOTDIR/usr/include/
$ popd
 
$ ln -s $INSTALLDIR/lib/gcc/arm-none-linux-gnueabi/4.8.2/libgcc.a $INSTALLDIR/lib/gcc/arm-none-linux-gnueabi/4.8.2/libgcc_eh.a
$ cd $SRCDIR

Building glibc


$ rm -rf $BUILDDIR/libc
$ mkdir -pv $BUILDDIR/libc
$ cd $BUILDDIR/libc
$ echo "libc_cv_forced_unwind=yes" > config.cache
$ echo "libc_cv_c_cleanup=yes" >> config.cache
 
*** check to make sure these are still set, they should be ***
$ echo $PATH
$ echo $CROSS
$ echo $CC
 
$ $GLIBC_SRC/configure --build=$BUILDMACH --host=$TARGETMACH --prefix=/usr --with-headers=$SYSROOTDIR/usr/include --config-cache --enable-kernel=2.6.0
$ make -k install-headers cross_compiling=yes install_root=$SYSROOTDIR
$ ln -s $INSTALLDIR/lib/gcc/arm-none-linux-gnueabi/4.8.2/libgcc.a $INSTALLDIR/lib/gcc/arm-none-linux-gnueabi/4.8.2/libgcc_s.a
$ make
$ make install_root=$SYSROOTDIR install

Building The Next gcc


NOTE: Here is where we would enable more languages, i.e. c++
*** unset CC, LD, and AS. We do not want to xcompile the xcompiler :-) ***
$ unset CC
$ unset LD
$ unset AS
 
*** delete gcc-x.x.x and re-install it ***
$ cd $SRCDIR
$ rm -rf gcc-4.8.2
$ tar -pxjf gcc-4.8.2.tar.bz2
$ cd gcc-4.8.2/
$ tar -pxjf ../gmp-4.3.2.tar.bz2
$ tar -pxjf ../mpfr-2.4.2.tar.bz2
$ tar -pxzf ../mpc-0.8.1.tar.gz
$ mv gmp-4.3.2/ gmp
$ mv mpfr-2.4.2/ mpfr
$ mv mpc-0.8.1/ mpc
$ mkdir -pv $BUILDDIR/final-gcc
$ cd $BUILDDIR/final-gcc
$ echo "libc_cv_forced_unwind=yes" > config.cache
$ echo "libc_cv_c_cleanup=yes" >> config.cache
$ BUILD_CC=gcc
$ $GCC_SRC/configure --build=$BUILDMACH --target=$TARGETMACH --prefix=$INSTALLDIR --with-sysroot=$SYSROOTDIR --enable-languages="c" --with-gnu-as --with-gnu-ld --disable-multilib --with-float=soft --disable-sjlj-exceptions --disable-nls --enable-threads=posix --enable-long-longx
$ make all-gcc
$ make install-gcc
If you made it this far, take a break and give yourself an attaboy :-D

Building The Final gcc


*** make sure these are still unset ***
$ echo $CC
$ echo $LD
$ echo $AS
 
*** delete gcc-x.x.x and re-install it ***
$ cd $SRCDIR
$ rm -rf gcc-4.8.2
$ tar -pxjf gcc-4.8.2.tar.bz2
$ cd gcc-4.8.2/
$ tar -pxjf ../gmp-4.3.2.tar.bz2
$ tar -pxjf ../mpfr-2.4.2.tar.bz2
$ tar -pxzf ../mpc-0.8.1.tar.gz
$ mv gmp-4.3.2/ gmp
$ mv mpfr-2.4.2/ mpfr
$ mv mpc-0.8.1/ mpc
$ mkdir -pv $BUILDDIR/final-gcc-2
$ cd $BUILDDIR/final-gcc-2
$ echo "libc_cv_forced_unwind=yes" > config.cache
$ echo "libc_cv_c_cleanup=yes" >> config.cache
$ $GCC_SRC/configure --build=$BUILDMACH --target=$TARGETMACH --prefix=$INSTALLDIR --with-sysroot=$SYSROOTDIR --enable-languages="c" --with-gnu-as --with-gnu-ld --disable-multilib --with-float=soft --disable-sjlj-exceptions --disable-nls --enable-threads=posix --disable-libmudflap --disable-libssp --enable-long-longx --with-shared
$ make
$ make install
Your done! :) Now go compile a test program with your new toy and see if it works. In a *new* terminal run:
$ export INSTALLDIR=~/workbench/gcc-4.8.2/arm
$ export PATH=$INSTALLDIR/bin:$PATH
$ export TARGETMACH=arm-none-linux-gnueabi
$ export BUILDMACH=i686-pc-linux-gnu
$ export CROSS=arm-none-linux-gnueabi
$ export CC=${CROSS}-gcc
$ export LD=${CROSS}-ld
$ export AS=${CROSS}-as
Now compile your test program:
$ $CC -Wall -Wextra <your test>.c -o <your test>
Check to see if your test program was successfully cross-compiled for ARM:
$ file <your test>
bash: ELF 32-bit LSB executable, ARM, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.16, not stripped
If you see something similar to the output above, then you have successfully cross-compiled your test program.

Usage


To use the cross-compiler all you need to do is set the following in a new terminal/tab:
$ export INSTALLDIR=~/workbench/gcc-4.8.2/arm
$ export PATH=$INSTALLDIR/bin:$PATH
$ export TARGETMACH=arm-none-linux-gnueabi
$ export BUILDMACH=i686-pc-linux-gnu
$ export CROSS=arm-none-linux-gnueabi
$ export CC=${CROSS}-gcc
$ export LD=${CROSS}-ld
$ export AS=${CROSS}-as
It may be cumbersome but I highly recommend doing the above for *every* build. That is to say, each time you cross-compile software for ARM do it in a new terminal/tab and begin by setting the environment variables above. In doing so you ensure that your build starts clean. I have had many occasions where my build would fail at odd times and some of the times I was able to fix it by closing the terminal/tab and starting fresh.

To run the programs that have been compiled with this cross-compiler you'll need to move some of the libraries and binaries to the file system on your dev board or your custom Linux file system. These are located in sysroot:~/workbench/gcc-4.8.2/arm/sysroot.

如何为嵌入式开发建立交叉编译环境

在进行嵌入式开发之前,首先要建立一个交叉编译环境,这是一套编译器、连接器和libc库等组成的开发环境。文章通过一个具体的例子说明了这些嵌入式交叉编译开发工具的制作过程。


https://www.ibm.com/developerworks/cn/linux/l-embcmpl/
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值