Loading...
 

Ben's Notes on Cross-compiler toolchain on Ubuntu

TOC
Ben's Notes on Cross-compiler toolchain on Ubuntu

How To Build GCC/G++ 4.8.2 ARM Cross-Compiler

Intro

In this How To we are going to build an ARM cross-compiler based upon GCC/G++ 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-g++-4.8.2/xtools/src
mkdir -pv ~/workbench/gcc-g++-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</pre>

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

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-g++-4.8.2/xtools/build export TARGETMACH=arm-none-linux-gnueabi export BUILDMACH=i686-pc-linux-gnu export INSTALLDIR=~/workbench/gcc-g++-4.8.2/arm export SYSROOTDIR=$INSTALLDIR/sysroot</pre>
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
<p>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.<br />  </p> <h2 id="toc11"><a name="How To Build GCC/G++ 4.8.2 ARM Cross-Compiler-Kernel Headers"></a>Kernel Headers</h2> <hr /> <p>I'm building this cross-compiler for the <a class="wiki_link_ext" href="http://pandaboard.org/" rel="nofollow" target="_blank">PandaBoard</a> thus for <span style="font-family: monospace;">ARCH</span> I'm using <span style="font-family: monospace;">arm omap2plus_defconfig</span>. Substitute your own board here. In any case, make sure you're specify the correct architecture, i.e. <span style="font-family: monospace;">arm</span>.</p> <pre class="text"> $ 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</pre> <p>Easy peasy. Next is our first go around with gcc.<br />  </p> <h2 id="toc12"><a name="How To Build GCC/G++ 4.8.2 ARM Cross-Compiler-Bootstrap gcc"></a>Bootstrap gcc</h2> <hr /> <pre class="text"> $ mkdir $BUILDDIR/bootstrap-gcc $ cd $BUILDDIR/bootstrap-gcc $ $GCC_SRC/configure <strike>build=$BUILDMACH </strike>host=$BUILDMACH <strike>target=$TARGETMACH </strike>prefix=$INSTALLDIR <strike>without-headers </strike>enable-boostrap <strike>enable-languages=&quot;c&quot; </strike>disable-threads <strike>enable-__cxa_atexit </strike>disable-libmudflap <strike>with-gnu-ld </strike>with-gnu-as <strike>disable-libssp </strike>disable-libgomp <strike>disable-nls </strike>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</pre> <p>Not too bad I hope :o)<br />  </p> <h2 id="toc13"><a name="How To Build GCC/G++ 4.8.2 ARM Cross-Compiler-glibc Headers - If binutils is not compatible with glibc this is where it will fail"></a>glibc Headers - If binutils is not compatible with glibc this is where it will fail</h2> <p><span style="color: #ff0000;">NOTE: Make sure you have gawk installed (else you get an error similar to <a class="wiki_link_ext" href="http://www.linuxquestions.org/questions/linux-from-scratch-13/urgent-help-on-glibc-make-error-with-clfs-590753/" rel="nofollow" target="_blank">this</a>).</span></p> <p>  <hr /></p> <pre class="text"> $ mkdir -pv $BUILDDIR/libc $ cd $BUILDDIR/libc $ echo &quot;libc_cv_forced_unwind=yes&quot; &gt; config.cache $ echo &quot;libc_cv_c_cleanup=yes&quot; &gt;&gt; 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 <strike>build=$BUILDMACH </strike>host=$TARGETMACH <strike>prefix=$SYSROOTDIR/usr </strike>with-headers=$SYSROOTDIR/usr/include <strike>config-cache </strike>enable-kernel=2.6.0 $ make -k install-headers cross_compiling=yes install_root=$SYSROOTDIR   </pre> <ul> <li> <ul> <li> <ul> <li>We need to move some files ***</li> </ul> </li> </ul> </li> </ul> <p>$ pushd $SYSROOTDIR/$INSTALLDIR/sysroot/usr/inlude $ 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</p> <h2 id="toc14"><a name="How To Build GCC/G++ 4.8.2 ARM Cross-Compiler-Building glibc"></a>Building glibc</h2> <hr /> <pre class="text"> $ rm -rf $BUILDDIR/libc $ mkdir -pv $BUILDDIR/libc $ cd $BUILDDIR/libc $ echo &quot;libc_cv_forced_unwind=yes&quot; &gt; config.cache $ echo &quot;libc_cv_c_cleanup=yes&quot; &gt;&gt; config.cache   </pre> <ul> <li> <ul> <li> <ul> <li>check to make sure these are still set, they should be ***</li> </ul> </li> </ul> </li> </ul> <p>$ echo $PATH $ echo $CROSS $ echo $CC   $ $GLIBC_SRC/configure <strike>build=$BUILDMACH </strike>host=$TARGETMACH <strike>prefix=/usr </strike>with-headers=$SYSROOTDIR/usr/include <strike>config-cache </strike>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</p> <h2 id="toc15"><a name="How To Build GCC/G++ 4.8.2 ARM Cross-Compiler-Building The Next gcc"></a>Building The Next gcc</h2> <hr /> <p><strong>NOTE: Here is where we would enable more languages, i.e. c++</strong></p> <p>  <pre class="text">
      • unset CC, LD, and AS. We do not want to xcompile the xcompiler <img alt=":-)" src="img/smiles/icon_smile.gif" title="smiling" /> ***
$ unset CC $ unset LD $ unset AS   </pre> </p> <ul> <li> <ul> <li> <ul> <li>delete gcc-x.x.x and re-install it ***</li> </ul> </li> </ul> </li> </ul> <p>$ 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 &quot;libc_cv_forced_unwind=yes&quot; &gt; config.cache $ echo &quot;libc_cv_c_cleanup=yes&quot; &gt;&gt; config.cache $ BUILD_CC=gcc $ $GCC_SRC/configure <strike>build=$BUILDMACH </strike>target=$TARGETMACH <strike>prefix=$INSTALLDIR </strike>with-sysroot=$SYSROOTDIR <strike>enable-languages=&quot;c,c++&quot; </strike>with-gnu-as <strike>with-gnu-ld </strike>disable-multilib <strike>with-float=soft </strike>disable-sjlj-exceptions <strike>disable-nls </strike>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 <img alt=":-D" src="img/smiles/icon_biggrin.gif" title="grinning" /><br />  </p> <h2 id="toc16"><a name="How To Build GCC/G++ 4.8.2 ARM Cross-Compiler-Building The Final gcc"></a>Building The Final gcc</h2> <hr /> <pre class="text">
      • make sure these are still unset ***
$ echo $CC $ echo $LD $ echo $AS   </pre> <ul> <li> <ul> <li> <ul> <li>delete gcc-x.x.x and re-install it ***</li> </ul> </li> </ul> </li> </ul> <p>$ 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 &quot;libc_cv_forced_unwind=yes&quot; &gt; config.cache $ echo &quot;libc_cv_c_cleanup=yes&quot; &gt;&gt; config.cache $ $GCC_SRC/configure <strike>build=$BUILDMACH </strike>target=$TARGETMACH <strike>prefix=$INSTALLDIR </strike>with-sysroot=$SYSROOTDIR <strike>enable-languages=&quot;c,c++&quot; </strike>with-gnu-as <strike>with-gnu-ld </strike>disable-multilib <strike>with-float=soft </strike>disable-sjlj-exceptions <strike>disable-nls </strike>enable-threads=posix <strike>disable-libmudflap </strike>disable-libssp <strike>enable-long-longx </strike>with-shared $ make $ make install Your done! <img alt=":-)" src="img/smiles/icon_smile.gif" title="smiling" /> Now go compile a test program with your new toy and see if it works. In a *new* terminal run:</p> <pre class="text"> $ export INSTALLDIR=~/workbench/gcc-g++-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 $ export CXX=${CROSS}-g++</pre> <p>Compile your test program:</p> <pre class="text"> $ $CC -Wall -Wextra &lt;your test&gt;.c -o &lt;your test&gt;</pre> <p>Check to see if your test program was successfully cross-compiled for ARM:</p> <pre class="text"> $ file &lt;your test&gt; bash: ELF 32-bit LSB executable, ARM, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.16, not stripped</pre> <p>If you see something similar to the output above, then you have successfully cross-compiled your test program.<br />  </p> <h2 id="toc17"><a name="How To Build GCC/G++ 4.8.2 ARM Cross-Compiler-Usage"></a>Usage</h2> <hr /> <p>To use the cross-compiler all you need to do is set the following in a new terminal/tab:</p> <pre class="text"> $ export INSTALLDIR=~/workbench/gcc-g++-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 $ export CXX=${CROSS}-g++</pre> <p>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.<br /> <br /> 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: <span style="font-family: monospace;">~/workbench/gcc-g++-4.8.2/arm/sysroot</span>.</p>