2009-10-13 02:14:27 +00:00
$$HEADER$$
2009-03-25 23:29:27 +00:00
< h3 > Building GCC for Cortex< / h3 >
< p > This tutorial explains how you can create a GCC+Newlib toolchain
2009-02-15 22:24:34 +00:00
that can be used to compile programs for the Cortex (Thumb2)
architecture, thus making it possible to use GCC to compile programs
2009-10-13 02:14:27 +00:00
for the increasingly number of Cortex CPUs out there (< a href = "http://www.luminarymicro.com/" > Luminary Micro< / a > , i
< a href = "http://www.st.com/mcu/inchtml-pages-stm32.html" > ST< / a > , with new Cortex CPUs being announced by Atmel and other companies). I
2009-02-15 22:24:34 +00:00
am writing this tutorial because I needed to work on a Cortex CPU for
the eLua project and I couldn't find anywhere a complete set of
instructions for building GCC for this architecture. You'll need such a
2009-03-25 23:29:27 +00:00
toolchain if you want to compile < b > eLua< / b > for Cortex-M3 CPUs. Please note that you can also use a
pre-built toolchain to compile < b > eLua< / b > (see < a href = "toolchains.html" > toolchains< / a > for details) so building
one yourself is not strictly required.< / p >
2009-02-15 22:24:34 +00:00
2009-10-13 02:14:27 +00:00
< p > < span class = "warning" > DISCLAIMER< / span > : I'm by no means a specialist in the
2009-02-15 22:24:34 +00:00
GCC/newlib/binutils compilation process. I'm sure that there are better
ways to accomplish what I'm describing here, however I just wanted a
quick and dirty way to build a toolchain, I have no intention in
becoming too intimate with the build process. If you think that what I
2009-10-13 02:14:27 +00:00
did is wrong, inaccurate, or simply outrageously ugly, feel free to < a href = "overview.html#contacts" > contact us< / a > and I'll make the necessary corrections.
And of course, this tutorial comes without any guarantees whatsoever.< / p >
2009-02-15 22:24:34 +00:00
< h2 > Prerequisites< / h2 >
2009-10-13 02:14:27 +00:00
< p > To build your toolchain you'll need:< / p >
2009-02-15 22:24:34 +00:00
2009-03-25 23:29:27 +00:00
< ul > < li > < b > a computer running Linux< / b > : I use Ubuntu, but any Linux
2009-02-15 22:24:34 +00:00
will do as long as you know how to find the equivalent of "apt-get" for
your distribution. I won't be going into details about this, google it
and you'll sure find what you need. It is also assumed that the Linux
system already has a "basic" native toolchain installed (gcc/make and
related). This is true for Ubuntu after installation. Again, you might
2009-03-25 23:29:27 +00:00
need to check your specific distribution.< / li >
2009-10-13 02:14:27 +00:00
< li > < b > GNU binutils< / b > : get it from < a href = "http://ftp.gnu.org/gnu/binutils/" > here< / a > .
2009-03-25 23:29:27 +00:00
At the moment of writing this, the latest versions is 2.19.1, but it refuses to compile for ARM. Same goes for
2.19. In fact, the only newer version of Binutils that seems to work properly is
2009-10-13 02:14:27 +00:00
2.19.50, it can be downloaded from < a href = "ftp://sourceware.org/pub/binutils/snapshots/" > here< / a > .
2009-03-25 23:29:27 +00:00
This is the version that we are going to use in this tutorial.< / li >
< li > < b > GCC< / b > :as I'm writing this, the latest GCC version is
2009-10-13 02:14:27 +00:00
4.3.3, which I'll be using for this tutorial. Download it from < a href = "http://gcc.gnu.org/mirrors.html" > here< / a > after choosing a suitable mirror.< / li >
2009-03-25 23:29:27 +00:00
< li > < b > Newlib< / b > : as I'm writing this, the latest official Newlib version is 1.17.0, which I'll be using for this tutorial.
2009-10-13 02:14:27 +00:00
Download it from < a href = "ftp://sources.redhat.com/pub/newlib/index.html" > here< / a > .< / li >
2009-03-25 23:29:27 +00:00
< li > The tutorial assumes that you're using bash as your shell. If you use
2009-10-13 02:14:27 +00:00
something else, you might need to adjust some shell-specific commands. < / li > < / ul >
2009-03-25 23:29:27 +00:00
< p > You need some support programs/libraries in order to compile the toolchain. To install them:< / p >
2009-10-13 02:14:27 +00:00
< pre > < code > $ sudo apt-get install flex bison libgmp3-dev libmpfr-dev autoconf texinfo build-essential< / code > < / pre >
2009-02-15 22:24:34 +00:00
< p > Next, decide where you want to install your toolchain. They
2009-03-25 23:29:27 +00:00
generally go in < i > /usr/local/< / i > , so I'm going to assume
< i > /usr/local/cross-cortex< / i > for this tutorial. To save yourself some
2009-02-15 22:24:34 +00:00
typing, set this path into a shell variable:< / p >
2009-10-13 02:14:27 +00:00
< pre > < code > $ export TOOLPATH=/usr/local/cross-cortex< / code > < / pre >
2009-02-15 22:24:34 +00:00
< h2 > Step 1: binutils< / h2 >
< p > This is the easiest step: unpack, configure, build.< / p >
2009-10-13 02:14:27 +00:00
< pre > < code > $ tar -xvjf binutils-2.19.50.tar.bz2
2009-03-25 23:29:27 +00:00
$ cd binutils-2.19.50
$ mkdir build
$ cd build
$ ../configure --target=arm-elf --prefix=$TOOLPATH --enable-interwork --enable-multilib --with-gnu-as --with-gnu-ld --disable-nls
$ make all
$ sudo make install
$ export PATH=${TOOLPATH}/bin:$PATH
2009-10-13 02:14:27 +00:00
$ cd ../..< / code > < / pre >
2009-02-15 22:24:34 +00:00
< p > Now you have your ARM "binutils" (assembler, linker, disassembler ...) in your PATH. They are fully capable of handling Thumb2.< / p >
< h2 > Step 2: basic GCC< / h2 >
< p > In this step we build a "basic" GCC (that is, a GCC without any
support libs, which we'll use in order to build all the libraries for
2009-03-25 23:29:27 +00:00
our target). Let's compile it (and note that the install step is
2009-10-13 02:14:27 +00:00
a bit different from Newlib's):< / p >
2009-03-25 23:29:27 +00:00
2009-10-13 02:14:27 +00:00
< pre > < code > $ tar -xvjf gcc-4.3.3.tar.bz2
2009-03-25 23:29:27 +00:00
$ cd gcc-4.3.3
$ mkdir build
$ cd build
$ ../configure --target=arm-elf --prefix=$TOOLPATH --enable-interwork --enable-multilib --enable-languages="c,c++" --with-newlib --without-headers --disable-shared --with-gnu-as --with-gnu-ld
$ make all-gcc
$ sudo -s -H
# export PATH=/usr/local/cross-cortex/bin:$PATH
# make install-gcc
# exit
2009-10-13 02:14:27 +00:00
$ cd ../..< / code > < / pre >
2009-02-15 22:24:34 +00:00
< h2 > Step 3: Newlib< / h2 >
2009-03-25 23:29:27 +00:00
< p > Some modifications are in order before we start compiling. Namely, we need to tell Newlib to skip some of its
libraries when compiling (I'm using < b > vim< / b > to edit, feel free to use your editor of choice instead):< / p >
2009-02-15 22:24:34 +00:00
2009-10-13 02:14:27 +00:00
< pre > < code > $ tar -xvzf newlib-1.17.0.tar.gz
2009-03-25 23:29:27 +00:00
$ cd newlib-1.17.0
$ vim configure.ac
2009-02-15 22:24:34 +00:00
2009-03-25 23:29:27 +00:00
< b > Find this fragment of code:< / b >
arm-*-elf* | strongarm-*-elf* | xscale-*-elf* | arm*-*-eabi* )
noconfigdirs="$noconfigdirs target-libffi target-qthreads"
libgloss_dir=arm
;;
2009-02-15 22:24:34 +00:00
2009-03-25 23:29:27 +00:00
< b > And add "target-libgloss" to the "noconfigdirs" variable:< / b >
arm-*-elf* | strongarm-*-elf* | xscale-*-elf* | arm*-*-eabi* )
noconfigdirs="$noconfigdirs target-libffi target-qthreads < b > target-libgloss< / b > "
libgloss_dir=arm
;;
2009-02-15 22:24:34 +00:00
2009-03-25 23:29:27 +00:00
< b > Save the modified file and exit the text editor.< / b >
2009-02-15 22:24:34 +00:00
2009-03-25 23:29:27 +00:00
$ autoconf
2009-02-15 22:24:34 +00:00
2009-03-25 23:29:27 +00:00
< b > On one of the systems I ran the above sequence, it terminated with
2009-02-15 22:24:34 +00:00
errors, complaining that autoconf 2.59 was not found. I don't know why
that happens. 2.59 seems to be quite ancient, and the build ran equally
well with 2.61 (the version of autoconf on the system that gave the
2009-03-25 23:29:27 +00:00
error). If this happens to you, first execute < i > autoconf --version< / i > to
find the actual version of your autoconf, then do this:< / b >
2009-10-13 02:14:27 +00:00
$ vim config/override.m4
2009-02-15 22:24:34 +00:00
2009-03-25 23:29:27 +00:00
< b > Look for this line:< / b >
[m4_define([_GCC_AUTOCONF_VERSION], [2.59])])
2009-02-15 22:24:34 +00:00
2009-03-25 23:29:27 +00:00
< b > And replace [2.59] with your actual version ([2.61] in my case).
Save the modified file and exit the text editor.< / b >
2009-02-15 22:24:34 +00:00
2009-10-13 02:14:27 +00:00
$ autoconf< / code > < / pre >
2009-02-15 22:24:34 +00:00
< p > Once again, now we're ready to actually compile Newlib. But we need
to tell it to compile for Thumb2. As already specified, I'm not a
2009-10-13 02:14:27 +00:00
specialist when it comes to Newlib's build system, so I chose the
2009-02-15 22:24:34 +00:00
quick, dirty and not so elegant solution of providing the compilation
flags directly from the command line. Also, as I wanted my library to
be as small as possible (as opposed to as fast as possible) and I only
wanted to keep what's needed from it in the final executable, I added
the "-ffunction-sections -fdata-sections" flags to allow the linker to
perform dead code stripping:< / p >
2009-10-13 02:14:27 +00:00
< pre > < code > $ mkdir build
2009-03-25 23:29:27 +00:00
$ cd build
$ ../configure --target=arm-elf --prefix=$TOOLPATH --enable-interwork --disable-newlib-supplied-syscalls --with-gnu-ld --with-gnu-as --disable-shared
$ make CFLAGS_FOR_TARGET="-ffunction-sections -fdata-sections -DPREFER_SIZE_OVER_SPEED -D__OPTIMIZE_SIZE__ -Os -fomit-frame-pointer -mcpu=cortex-m3 -mthumb -D__thumb2__ -D__BUFSIZ__=256" CCASFLAGS="-mcpu=cortex-m3 -mthumb -D__thumb2__"
$ sudo -s -H
# export PATH=/usr/local/cross-cortex/bin:$PATH
# make install
# exit
2009-10-13 02:14:27 +00:00
$ cd ../..< / code > < / pre >
< p > Some notes about the flags used in the above sequence:< / p >
2009-03-25 23:29:27 +00:00
< ul > < li > < code > --disable-newlib-supplied-syscalls:< / code > this deserves a page of its own, but I won't cover it here.
2009-10-13 02:14:27 +00:00
For an explanation, see for example < a href = "http://openhardware.net/Embedded_ARM/NewLib_Stubs/" > this page< / a > .< / li >
2009-03-25 23:29:27 +00:00
< li > < code > -DPREFER_SIZE_OVER_SPEED -D__OPTIMIZE_SIZE__:< / code > compile Newlib for size, not for speed (these are Newlib specific).< / li >
< li > < code > -mcpu=cortex-m3 -mthumb:< / code > this tells GCC that you want to compile for Cortex. Note that you need both flags.< / li >
< li > < code > -D__thumb2__:< / code > again, this is Newlib specific, and seems to be required when compiling Newlib for Cortex.< / li >
< li > < code > -Os -fomit-frame-pointer:< / code > tell GCC to optimize for size, not for speed.< / li >
< li > < code > -D__BUFSIZ__=256:< / code > again Newlib specific, this is the buffer size allocated by default for
2009-02-15 22:24:34 +00:00
files opened via fopen(). The default is 1024, which I find too much
2009-10-13 02:14:27 +00:00
for < b > eLua< / b > , so I'm using 256 here. Of course, you can change this value.< / li > < / ul >
2009-02-15 22:24:34 +00:00
< h2 > Step 4: full GCC< / h2 >
< p > Finally, in the last step of our tutorial, we complete the GCC
build. In this stage, a number of compiler support libraries are built
(most notably libgcc.a). Fortunately this is simpler that the Newlib
compilation step, as long as you remember that we want to build our
compiler support libraries for the Cortex architecture:< / p >
2009-10-13 02:14:27 +00:00
< pre > < code > $ cd gcc-4.3.3/build
2009-03-25 23:29:27 +00:00
$ make CFLAGS="-mcpu=cortex-m3 -mthumb" CXXFLAGS="-mcpu=cortex-m3 -mthumb" LIBCXXFLAGS="-mcpu=cortex-m3 -mthumb" all
$ sudo make install
2009-10-13 02:14:27 +00:00
< / code > < / pre >
2009-02-15 22:24:34 +00:00
< h2 > All Done!< / h2 >
< p > Phew! That was quite a disturbing tutorial, with all that confusing
flags lurking in every single shell line :) But at this point you
2009-10-13 02:14:27 +00:00
should have a fully functional Cortex GCC toolchain, so enjoy it!
2009-02-15 22:24:34 +00:00
If you need further clarification, or if the above instructions didn't
2009-03-25 23:29:27 +00:00
work for you, feel free to < a href = "overview.html#contacts" > contact us< / a > .< / p >
2009-10-13 02:14:27 +00:00
$$FOOTER$$