fig

GCC Cross-Compiler with Newlib for Microcontrollers

August 1, 2014 - Linguagem C / Microcontroladores / Programação

The following recipe illustrates how to build GCC and binutils from source code as a cross-compiler for generating code for microcontrollers like ARM-Cortex (STM32), MIPS (PIC32) or M68K (Coldfire). Once there is not a target operating system, the library Newlib will be employed. Newlib is an optimized version of libc specially designed for embedded processor systems.

This can be done in any Unix-based operating system (Linux and MacOS X) or in Windows, over MinGW. In the case of MacOS, I suggest installing an external version of GCC using a packet manager (like macports) instead of using Apple’s XCode.

Step 1 – Intall GCC and auxiliary libraries

Usually, it is enough a command like the following for doing that:

The development packages GMPMPFR e MPC are needed for compiling GCC. If your packet management system cannot install their binaries, you will need to compile them, one by one.

Step 2 – Download Sources

Download and unpack binutils, GCC and Newlib source-code files. You shall try the most recent versions of each piece of software, but perhaps it will be necessary to try a previous version in case of compatibility issues.

GNU Binutils - http://ftp.gnu.org/gnu/binutils/

GNU GCC - http://ftp.gnu.org/gnu/gcc/

Redhat Newlib - ftp://sourceware.org/pub/newlib/index.html

Create a new directory for each source-code and inside it a sub-directory /build or /make for the generated object files, thus preventing messing with source-code files.

Step 3 – Compile!

Get the target processor/system defined, as well as the installation base directory, in two environment variables, as every compilation will need them,

The installation path is arbitrary, but prefer using the standard location /usr/local, as it avoids having to add new search paths to your environment variables; you can compile several GCC versions, for a number of CPUs: there won’t be any name clashing because the compiled programs will have different names like mips-none-elf-as ou arm-none-eabi-gcc, that won’t conflict with your native gcc either.

Compiling binutils for the desired CPU is quite easy, get into your source-code directory and  /build directory and do the usual configure/make/make install,

If the compilation ends successfully, the installation will be done and a command like

will return the corresponding version information.

For the C compiler, the process is somewhat more complex. The first thing you will need is a “startup” compiler, the one that will be used to compile newlib the first time:

Step 4 – Make newlib and the complete C Compiler

Once you have the startup compiler for your CPU, lets use it to build newlib. We shall include the option SMALL_MEMORY for embedded processors.

Finally, now that we have libc, we can terminate the build process for the C Compiler. Get back to GCC source-code directory and build it all,

After completion, the compiler will be built and installed. Test the toolkit, for exemple, for MIPS:

this will show a machine language object-code generated for a small C test program.

A Windows note: it is common when compiling GCC with MinGW an out-of-memory error repeatedly occurs. In such a case, simply repeat the original make command multiple times; once the building process is incremental, after a number of tries the desired result will be finally achieved.

Optional – Compile the Debugger (GDB)

Although it is not essential, when working with a cross-compiler it is very useful to have a cross-debugger to emulate the execution of the target CPU in your system. To build the debugger, download the sources at:

http://ftp.gnu.org/gnu/gdb/

and you will need to install the libtinfo library as well:

Just like the other packages, build gdb with the equivalent commands,

Have fun!

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code class="" title="" data-url=""> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre class="" title="" data-url=""> <span class="" title="" data-url="">