Skip to content

Building a Hard-float ARM Toolchain

Note: This article is probably out of date due to the latest crosstool-ng 1.15.0 release which includes a “Hard-Float” option.

The ARM architecture receives a huge performance advantage by using a hard-float tool-chain, however most distributions only provide a soft-float tool-chain.  CodeSourcery charges a fee for a hard-float tool-chain, but this post will show you how to build one using crosstool-NG.

I’ll specifically detail the process for a Cortex-A8, but the same principles apply for other ARM architectures.  My build environment is Ubuntu 11.10 with a Freescale i.MX53 Quick Start development board.

This is a post for advanced gcc/Linux/Toolchain developers.  Please do not proceed unless you fully understand concepts such as hard-float (vfp and neon), soft-float, ARM, Linux and gcc linking.

Firstly, download and install the latest crosstool-NG (This post uses 1.13.2)


tar -xvjf crosstool-ng-1.13.2.tar.bz2

cd crosstool-ng-1.13.2

./configure --prefix=$PWD


make install

Configure ct-ng:

./ct-ng menuconfig

Firstly, configure the paths and misc options.  This is mostly user dependent, but I thought I would show my settings:

Then go into Target Options:

You must configure for the vfpv3 floating point engine in this step and you must use -mfloat-abi=hard.  ARM processors will have different vfp options, such as vfpv3 or vfpv3-d16.  You can also use neon here if you want.  Choose the right one for your processor.  The cortex-a8 tuning is an optimization step and is CPU dependent.

For reference the following are the equivalents in the configuration file:
CT_TARGET_CFLAGS=”-mfloat-abi=hard -mfpu=vfpv3″

Then we configure the toolchain options.  Nothing really hard here, I have decided to give the toolchain a vendor string (cortex_a8) and an alias (arm-):

Next, we look at the target Operating System.  I have used Linux 3.0.4 as my target operating system.

Next we setup the binary utilities, nothing too exciting here:

Now we come to the interesting part, the C-compiler settings and C-library settings.  To overcome the performance penalty of a soft-float toolchain, we need to rebuild everything as hard-float.  This includes the gcc libraries and glibc.

Firstly the C-compiler settings:

You can setup any components of gcc that you require, but the important setup is Core gcc extra config and gcc extra config.  These must be set to –with-float=hard.

For reference they are these elements in the config file:


Next, we setup the C-library options.  We must build glibc (or equivalent C library) with the correct hard-float options.

In this case extra target CFLAGS and gcc extra flags must be set to -mfloat-abi=hard -mfpu=vfpv3.  These options are different to the C-compiler setup because in this case we are passing these options into the gcc to build glibc.  In the C-compiler setup, we were configuring gcc and gcc’s libraries (libgcc, libstdc++, etc).

For reference here are the equivalent parameters in the configuration file:

CT_LIBC_GLIBC_EXTRA_CFLAGS=”-U_FORTIFY_SOURCE -mfloat-abi=hard -mfpu=vfpv3″
CT_LIBC_EXTRA_CC_ARGS=”-mfloat-abi=hard -mfpu=vfpv3″


The next four configuration screens, Debug Facilities, Companion Libraries, Companian Tools and Test Suite, I will leave to the user to configure, but I will show the screen-shot of Companion Libraries in case you need it:

Ok, so the configuring is done. At this stage you may want to review the crosstool-NG instructions to make sure that your machine is setup correctly to build the toolchain.

Lets build the toolchain.  Firstly, create the tarballs directory we used in configure:

mkdir -p tarballs

Build the toolchain using ct-ng.  My example uses 8 cores, but you should adjust this for your build machine:

./ct-ng build.8

Well, the toolchain will probably take 30 minutes to build on an i7.   If all goes well you will end up with a build log like this:

[INFO ]  Performing some trivial sanity checks
[INFO ]  Build started 20111204.164331
[INFO ]  Building environment variables
[EXTRA]  Preparing working directories
[EXTRA]  Installing user-supplied crosstool-NG configuration
[EXTRA]  =================================================================
[EXTRA]  Dumping internal crosstool-NG configuration
[EXTRA]    Building a toolchain for:
[EXTRA]      build  = x86_64-unknown-linux-gnu
[EXTRA]      host   = x86_64-unknown-linux-gnu
[EXTRA]      target = arm-cortex_a8-linux-gnueabi
[EXTRA]  Dumping internal crosstool-NG configuration: done in 0.10s (at 00:02)
[INFO ]  =================================================================
[INFO ]  Retrieving needed toolchain components' tarballs
[INFO ]  Retrieving needed toolchain components' tarballs: done in 0.16s (at 00:02)
[INFO ]  =================================================================
[INFO ]  Extracting and patching toolchain components
[INFO ]  Extracting and patching toolchain components: done in 3.87s (at 00:06)
[INFO ]  =================================================================
[INFO ]  Installing GMP
[EXTRA]    Configuring GMP
[EXTRA]    Building GMP
[EXTRA]    Installing GMP
[INFO ]  Installing GMP: done in 43.53s (at 00:50)
[INFO ]  =================================================================
[INFO ]  Installing MPFR
[EXTRA]    Configuring MPFR
[EXTRA]    Building MPFR
[EXTRA]    Installing MPFR
[INFO ]  Installing MPFR: done in 16.18s (at 01:06)
[INFO ]  =================================================================
[INFO ]  Installing PPL
[EXTRA]    Configuring PPL
[EXTRA]    Building PPL
[EXTRA]    Installing PPL
[INFO ]  Installing PPL: done in 165.04s (at 03:51)
[INFO ]  =================================================================
[INFO ]  Installing CLooG/ppl
[EXTRA]    Configuring CLooG/ppl
[EXTRA]    Building CLooG/ppl
[EXTRA]    Installing CLooG/ppl
[INFO ]  Installing CLooG/ppl: done in 7.06s (at 03:58)
[INFO ]  =================================================================
[INFO ]  Installing MPC
[EXTRA]    Configuring MPC
[EXTRA]    Building MPC
[EXTRA]    Installing MPC
[INFO ]  Installing MPC: done in 9.58s (at 04:08)
[INFO ]  =================================================================
[INFO ]  Installing binutils
[EXTRA]    Configuring binutils
[EXTRA]    Building binutils
[EXTRA]    Installing binutils
[INFO ]  Installing binutils: done in 39.71s (at 04:47)
[INFO ]  =================================================================
[INFO ]  Installing static core C compiler
[EXTRA]    Configuring static core C compiler
[EXTRA]    Building static core C compiler
[EXTRA]    Installing static core C compiler
[INFO ]  Installing static core C compiler: done in 146.93s (at 07:14)
[INFO ]  =================================================================
[INFO ]  Installing kernel headers
[EXTRA]    Installing kernel headers
[EXTRA]    Checking installed headers
[INFO ]  Installing kernel headers: done in 8.98s (at 07:23)
[INFO ]  =================================================================
[INFO ]  Installing C library headers & start files
[EXTRA]    Configuring C library
[EXTRA]    Installing C library headers
[EXTRA]    Installing C library start files
[INFO ]  Installing C library headers & start files: done in 45.50s (at 08:09)
[INFO ]  =================================================================
[INFO ]  Installing shared core C compiler
[EXTRA]    Configuring shared core C compiler
[EXTRA]    Building shared core C compiler
[EXTRA]    Installing shared core C compiler
[INFO ]  Installing shared core C compiler: done in 163.11s (at 10:52)
[INFO ]  =================================================================
[INFO ]  Installing C library
[EXTRA]    Configuring C library
[EXTRA]    Building C library
[EXTRA]    Installing C library
[INFO ]  Installing C library: done in 483.20s (at 18:55)
[INFO ]  =================================================================
[INFO ]  Installing final compiler
[EXTRA]    Configuring final compiler
[EXTRA]    Building final compiler
[EXTRA]    Installing final compiler
[INFO ]  Installing final compiler: done in 257.40s (at 23:13)
[INFO ]  =================================================================
[INFO ]  Installing binutils for target
[EXTRA]    Configuring binutils for target
[EXTRA]    Building binutils' libraries (libiberty bfd) for target
[EXTRA]    Installing binutils' libraries (libiberty bfd) for target
[INFO ]  Installing binutils for target: done in 74.09s (at 24:27)
[INFO ]  =================================================================
[INFO ]  Installing native gdb
[EXTRA]    Building static target ncurses
[EXTRA]    Building static target expat
[EXTRA]    Configuring native gdb
[EXTRA]    Building native gdb
[EXTRA]    Installing native gdb
[EXTRA]    Cleaning up ncurses
[INFO ]  Installing native gdb: done in 241.59s (at 28:28)
[INFO ]  =================================================================
[INFO ]  Installing gdbserver
[EXTRA]    Configuring gdbserver
[EXTRA]    Building gdbserver
[EXTRA]    Installing gdbserver
[INFO ]  Installing gdbserver: done in 14.77s (at 28:43)
[INFO ]  =================================================================
[INFO ]  Installing GCC test suite
[INFO ]  Installing GCC test suite: done in 34.60s (at 29:18)
[INFO ]  =================================================================
[INFO ]  Cleaning-up the toolchain's directory
[EXTRA]    Installing the populate helper
[EXTRA]    Installing a cross-ldd helper
[EXTRA]    Creating toolchain aliases
[EXTRA]    Removing access to the build system tools
[EXTRA]    Removing installed documentation
[INFO ]  Cleaning-up the toolchain's directory: done in 0.79s (at 29:19)
[INFO ]  Build completed at 20111204.171250
[INFO ]  (elapsed: 29:18.74)
[INFO ]  Finishing installation (may take a few seconds)...

One final word of note: This is a hard-float toolchain and you cannot link any soft-float code to it.  You will have to rebuild all of your software with this toolchain and use the following options:

-mfloat-abi=hard -mfpu=vfpv3 -march=armv7-a -mtune=cortex-a8

Otherwise you will get linker errors like this:

/home/paulg/hmccore-arm/bin/../lib/gcc/arm-cortex_a8-linux-gnueabi/4.6.2/../../../../arm-cortex_a8-linux-gnueabi/bin/ld: error: hello uses VFP register arguments, test does not /home/paulg/hmccore-arm/bin/../lib/gcc/arm-cortex_a8-linux-gnueabi/4.6.2/../../../../arm-cortex_a8-linux-gnueabi/bin/ld: failed to merge target specific data of file hello collect2: ld returned 1 exit status
Specifically note the "xxxx uses VFP register arguments, yyyy does not" error.



  1. manu says:


    After the below log the build is stuck. Please help.

    manu@nadham:~/installs/crosstool-ng-1.13.2$ ./ct-ng build.2
    [INFO ] Performing some trivial sanity checks
    [INFO ] Build started 20120211.014729
    [INFO ] Building environment variables
    [INFO ] =================================================================
    [INFO ] Retrieving needed toolchain components’ tarballs
    [00:44] /


  2. Jack Glau says:

    Confused about the kernel and header options… what will happen if I try and build a 3.2.x kernel whilst having the target set to linux 3.0.x?

    • Paul Gibson says:

      When building the linux kernel itself, I don’t think it uses much of the functionality from the toolchain (headers, glibc). It certainly shouldn’t use the kernel headers in the toolchain, because the kernel you are building should have it already. So I think that is ok.

      The kernel headers are mainly needed for glibc as I understand it. This is why userspace should be built with a toolchain built for the same version of linux as it is deployed on. Sometimes there is an incompatibility.

  3. wanxs says:

    When i build in Debian 7.0 or 6.0,I have a error like “checking for suffix of object files… configure: error: cannot compute suffix of object files: cannot compile”.What happened?
    Can u give me a config file that you build success,thanks.

  4. Andreas Pokorny says:

    Since you are building for IMX53. Are there any hard float gpu drivers for the AMD/Imageon gpus available?

  5. Cleiton says:

    Hi Paul,
    I’m encountering the following problem:

    [INFO ] Installing pass-2 core C compiler
    [EXTRA] Configuring core C compiler
    [EXTRA] Building core C compiler
    [ERROR] make[2]: *** [cc1-dummy] Error 1
    [ERROR] make[1]: *** [all-gcc] Error 2
    [ERROR] >>
    [ERROR] >> Build failed in step ‘Installing pass-2 core C compiler’
    [ERROR] >> called in step ‘(top-level)’
    [ERROR] >>
    [ERROR] >> Error happened in: CT_DoExecLog[scripts/functions@172]
    [ERROR] >> called from: do_cc_core_backend[scripts/build/cc/]
    [ERROR] >> called from: do_cc_core_pass_2[scripts/build/cc/]
    [ERROR] >> called from: main[scripts/]
    [ERROR] >>
    [ERROR] >> For more info on this error, look at the file: ‘build.log’
    [ERROR] >> There is a list of known issues, some with workarounds, in:
    [ERROR] >> ‘docs/B – Known issues.txt’
    [ERROR] (elapsed: 26:57.51)
    [26:58] / make: ** [build] Erro 2

    See if you can help-me.


  6. Cleiton says:


    This code snippet is taken from build.log, is the only information I have the error.


  7. ike says:

    It seems some of the images where you are showing the options selected in the article are missing. Could you please update the article with the images. Thanks

    • Paul Gibson says:

      Hi thanks for the message. The images are fixed now. FYI, this article is really out of date. The latest crosstool-ng automatically supports hard float toolchains without needing to do everything I mention in the article.


      • ike says:

        Thanks for the info. I will try and see if it works for me. I am actually looking to build a toolchain for arm920t based Samsung SOC. I have already spent a few hours now but face some or the other error to get my toolchain. Lets see how it goes if I don’t specify the hard float specific paramters. Thanks anyways :)

      • GusBricker says:

        Just out of curiosity, what do you mean by it automatically supports hard float?

        I can’t find any information on it doing this and the sample for cortex-a8 in v1.19 of crosstool-ng doesn’t enable hard float support.

        • Paul Gibson says:

          Hi GusBricker,

          I meant that it automatically supports hard-float if you set the “Floating Point” setting in “Target Options” to “Hardware FPU” and set the “Use specific FPU” to “neon” or “vfp*”

          I think I could have been a lot clearer about that – thanks for pointing it out. I hope those settings work for you.


Leave a Reply