1
0
mirror of https://github.com/elua/elua.git synced 2025-01-08 20:56:17 +08:00
elua/doc/en/tc_arm.html
Dado Sutter eafb837414 Content added
Menu tree revised
Anchors refactored
Ongoing work
2009-02-15 22:24:34 +00:00

310 lines
10 KiB
HTML

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Strict//EN">
<html><head>
<meta http-equiv="content-type" content="text/html; charset=ISO-8859-1">
<meta http-equiv="Content-Language" content="en-us"><title>Product</title>
<link rel="stylesheet" type="text/css" href="../style.css"></head>
<body style="background-color: rgb(255, 255, 255);"><h3><a name="title" href="http://www.eluaproject.net/en/Building_GCC_for_ARM" class="local">Building GCC for ARM</a></h3>
<div class="content">
<p> This tutorial explains how you can create a GCC+Newlib toolchain
that can be used to compile programs for the ARM architecture, thus
making it possible to compile programs for the large number of ARM CPUs
out there. You'll need such a toolchain if you want to compile eLua for
ARM CPUs. This tutorial is similar to many others you'll find on the
Internet (particulary the one from <a href="http://www.gnuarm.com/">gnuarm</a>, on which it's based), but it's a bit more detailed and shows some "tricks" you can use when compiling Newlib.</p>
<p><strong>DISCLAIMER: I'm by no means a specialist in the
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
did is wrong, innacurate, or simply outrageously ugly, feel free to <a href="http://www.eluaproject.net/en/Contact">contact me</a> and I'll make the necessary corrections. And of course, this tutorial comes without any guarantees whatsoever.</strong></p>
<h2>Prerequisites</h2>
<p>To build your toolchain you'll need:</p>
<ul><li>a computer running Linux: I use Ubuntu 8.04, but any Linux
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
need to check your specific distribution.</li><li>GNU binutils: get it from <a href="http://ftp.gnu.org/gnu/binutils/">here</a>.
At the moment of writing this, the latest versions is 2.18, which for
some weird reason refuses to compile on my system, so I'm using 2.17
instead.</li><li>GCC: version 4.3.0 or newer is recommended. As
I'm writing this, the latest GCC version is 4.3.1 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><li>Newlib: as I'm writing this, the latest official Newlib version is 1.16.0. Download it from the <a href="ftp://sources.redhat.com/pub/newlib/index.html">Newlib FTP directory</a>.</li><li>Also,
the tutorial assumes that you're using bash as your shell. If you use
something else, you might need to adjust some shell-specific commands. </li></ul>
<p>Also, you need some support programs/libraries in order to compile the toolchain. To install them:</p>
<p><br></p>
<table class="table_cod">
<tbody><tr>
<th>$ sudo apt-get install flex bison libgmp3-dev libmpfr-dev autoconf texinfo</th>
</tr>
</tbody></table>
<p>Next, decide where you want to install your toolchain. They
generally go in /usr/local/, so I'm going to assume
/usr/local/cross-arm for this tutorial. To save yourself some typing,
set this path into a shell variable:</p>
<p><br></p>
<table class="table_cod">
<tbody><tr>
<th>$ export TOOLPATH=/usr/local/cross-arm</th>
</tr>
</tbody></table>
<h2>&#8250; Step 1: binutils</h2>
<p>This is the easiest step: unpack, configure, build.</p>
<p><br></p>
<table class="table_cod">
<tbody><tr>
<th>$ tar -xvjf binutils-2.17.tar.bz2</th>
</tr>
</tbody></table>
<table class="table_cod">
<tbody><tr>
<th>$ cd binutils-2.17</th>
</tr>
</tbody></table>
<table class="table_cod">
<tbody><tr>
<th>$ mkdir build</th>
</tr>
</tbody></table>
<table class="table_cod">
<tbody><tr>
<th>$ cd build</th>
</tr>
</tbody></table>
<table class="table_cod">
<tbody><tr>
<th style="text-align: left;">$ ../configure --target=arm-elf --prefix=$TOOLPATH --enable-interwork --enable-multilib--with-gnu-as --with-gnu-ld --disable-nls</th>
</tr>
</tbody></table>
<table class="table_cod">
<tbody><tr>
<th>$ make all</th>
</tr>
</tbody></table>
<table class="table_cod">
<tbody><tr>
<th>$ sudo make install</th>
</tr>
</tbody></table>
<table class="table_cod">
<tbody><tr>
<th>$ export PATH=${TOOLPATH}/bin:$PATH</th>
</tr>
</tbody></table>
<p>Now you have your ARM "binutils" (assembler, linker, disassembler ...) in your PATH.</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
our target). But first we need to make a slight modification in the
configuration files. Out of the box, the GCC 4.3.1/newlib combo won't
compile properly, giving a very weird "Link tests are not allowed after
GCC_NO_EXECUTABLES" error. After a bit of googling, I found the
solution for this:</p>
<p><br></p>
<table class="table_cod">
<tbody><tr>
<th>$ tar -xvjf gcc-4.3.1.tar.bz2</th>
</tr>
<tr>
<th>$ cd gcc-4.3.1/libstdc++-v3</th>
</tr>
<tr>
<th style="text-align: left;">$ joe configure.ac</th>
</tr>
</tbody></table>
<p> I'm using "joe" here as it's my favourite Linux text mode editor,
you can use any other text editor. Now find the line which says
"AC_LIBTOOL_DLOPEN" and comment it out by adding a "#" before it:</p>
<p><code># AC_LIBTOOL_DLOPEN</code></p>
<p>Save the modified file and exit the text editor</p>
<p><br> </p>
<table class="table_cod">
<tbody><tr>
<th>$ autoconf</th>
</tr>
<tr>
<th style="text-align: left;">$ cd ..</th>
</tr>
</tbody></table>
<p>Great, now we know it will compile, so let's do it:</p>
<p><br></p>
<table class="table_cod">
<tbody><tr align="left">
<th>$ mkdir build</th>
</tr>
<tr align="left">
<th>$ cd build</th>
</tr>
<tr align="left">
<th>$
../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</th>
</tr>
<tr align="left">
<th>$ make all-gcc</th>
</tr>
<tr align="left">
<th>$ sudo make install-gcc</th>
</tr>
</tbody></table>
<p>On my system, the last line above (sudo make install-gcc) terminated
with errors, because it was unable to find our newly compiled binutils.
If this happens for any kind of "make install" command, this is a quick
way to solve it:</p>
<p style="text-align: left;"><br></p><div style="text-align: left;">
</div><table class="table_cod">
<tbody><tr align="left">
<th>$ sudo -s -H</th>
</tr>
<tr align="left">
<th># export PATH=/usr/local/cross-arm/bin:$PATH</th>
</tr>
<tr align="left">
<th># make install-gcc</th>
</tr>
<tr>
<th style="text-align: left;"># exit</th>
</tr>
</tbody></table>
<h2>Step 3: Newlib</h2>
<p>Once again, Newlib is as easy as unpack, configure, build. But 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, so I added the "-ffunction-sections -fdata-sections" flags
to allow the linker to perform dead code stripping:</p>
<p><br></p>
<table class="table_cod">
<tbody><tr align="left">
<th>$ tar xvfz newlib-1.16.0.tar.gz</th>
</tr>
<tr align="left">
<th>$ cd newlib-1.16.0</th>
</tr>
<tr align="left">
<th>$ mkdir build</th>
</tr>
<tr align="left">
<th>$ cd build</th>
</tr>
<tr align="left">
<th>$
../configure --target=arm-elf --prefix=$TOOLPATH --enable-interwork
--disable-newlib-supplied-syscalls --with-gnu-ld --with-gnu-as
--disable-shared</th>
</tr>
<tr align="left">
<th>$ make
CFLAGS_FOR_TARGET="-ffunction-sections -fdata-sections
-DPREFER_SIZE_OVER_SPEED -D__OPTIMIZE_SIZE__ -Os -fomit-frame-pointer
-D__BUFSIZ__=256"</th>
</tr>
<tr align="left">
<th>$ sudo make install</th>
</tr>
</tbody></table>
<p>Some notes about the flags used in the above sequence:</p>
<ul><li><code>--disable-newlib-supplied-syscalls</code>: this deserves a page of its own, but I won't cover it here. For an explanation, see for example <a href="http://openhardware.net/Embedded_ARM/NewLib_Stubs/">this page</a></li><li><code>-DPREFER_SIZE_OVER_SPEED -D__OPTIMIZE_SIZE__</code>: compile Newlib for size, not for speed (these are Newlib specific).</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
files opened via fopen(). The default is 1024, which I find too much
for an eLua, so I'm using 256 here. Of course, you can change this
value.</li></ul>
<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:</p>
<p><br></p>
<table class="table_cod">
<tbody><tr align="left">
<th>$ cd gcc-4.3.1/build</th>
</tr>
<tr align="left">
<th>$ make all</th>
</tr> <tr align="left">
<th>$ sudo make install</th>
</tr>
</tbody></table>
<h2>Step 5: all done!</h2>
<p>Now you can finally enjoy your ARM toolchain, and compile eLua with it :)
If you need further clarification, or if the above instructions didn't work for you, feel free to <a href="http://www.eluaproject.net/en/Contact">contact me</a>.</p>
</div></body></html>