Success!
After putting this aside for a while I finally came back to it and I have GCC 4.8.0 compiled on my mac and the resulting binaries working on the teensy3. The resulting GCC supports the following mutlilibs:
Code:
> arm-none-eabi-gcc -print-multi-lib
.;
thumb/arm7tdmi-s;@mthumb@mcpu=arm7tdmi-s
thumb/cortex-m0;@mthumb@mcpu=cortex-m0
thumb/cortex-m3;@mthumb@mcpu=cortex-m3
thumb/cortex-m4;@mthumb@mcpu=cortex-m4
thumb/cortex-m4/float-abi-hard/fpuv4-sp-d16;@mthumb@mcpu=cortex-m4@mfloat-abi=hard@mfpu=fpv4-sp-d16
I basically followed the instructions
here and
here, but I'll summarize the steps below.
The
absolute key was finding the right contents of the
gcc/config/arm/t-arm-elf file. Taken from
here, they are:
Code:
# We have to build 'arm' and 'thumb' libraries, it seems.
MULTILIB_OPTIONS = marm/mthumb
MULTILIB_DIRNAMES = arm thumb
# Only we don't actually want any ARM libraries. Or
# vanilla thumb libraries.
MULTILIB_EXCEPTIONS = marm* mthumb
# Build with any one of arm7tdmi, M0, M3 or M4 support.
MULTILIB_OPTIONS += mcpu=arm7tdmi-s/mcpu=cortex-m0/mcpu=cortex-m3/mcpu=cortex-m4
MULTILIB_DIRNAMES += arm7tdmi-s cortex-m0 cortex-m3 cortex-m4
# These don't make any sense without thumb, because GCC likes to
# tell you that you have to supply another commandline argument
# rather than just setting it itself.
MULTILIB_EXCEPTIONS += mcpu=arm7tdmi-s* mcpu=cortex-m0* mcpu=cortex-m3* mcpu=cortex-m4*
# All this just to get mfloat-abi=hard mfpu=fpv4-sp-d16 only specified for the M4
MULTILIB_OPTIONS += mfloat-abi=hard mfpu=fpv4-sp-d16
MULTILIB_DIRNAMES += float-abi-hard fpuv4-sp-d16
MULTILIB_EXCEPTIONS += mfloat* mthumb/mfloat*
MULTILIB_EXCEPTIONS += mfpu* mthumb/mfpu*
MULTILIB_EXCEPTIONS += mthumb/mcpu=cortex-m4/mfloat-abi=hard
MULTILIB_EXCEPTIONS += mthumb/mcpu=cortex-m4/mfpu=fpv4-sp-d16
MULTILIB_EXCEPTIONS += *arm7tdmi-s*mfloat-abi* *arm7tdmi-s*mfpu*
MULTILIB_EXCEPTIONS += *cortex-m3*mfloat-abi* *cortex-m3*mfpu*
MULTILIB_EXCEPTIONS += *cortex-m0*mfloat-abi* *cortex-m0*mfpu*
A couple things I learned:
arm-eabi seems to require you include both arm and thumb libraries even if you only care about thumb. This is really annoying. Also, the multilib config is atrocious, mostly because the combinatorial expansion produces lots of invalid configurations that you have to exclude, and you have to wait a until a fair amount of the build has happened before you can see your error. Why can't I just list the multlibs I care about?
I'll briefly summarize the steps because I've yet to see one single source that identifies all the bits needed:
Prereqs:
Install latest versions of:
All of these get compiled for the "host" architecture (where you're actually running the compiler), so PC, Mac, raspberry, etc. These all were a pretty simple
Code:
./configure --prefix=/usr/local/teensy && make install
so I won't go into detail.
Binutils:
Install latest version of
binutils (2.23.1) for the target architecture of arm-none-eabi:
Code:
./configure --target=arm-none-eabi --prefix=/usr/local/teensy --with-sysroot=/usr/local/teensy/arm-none-eabi
sudo make install
Make sure you use sysroot.
GCC:
I'm using the trunk GCC because I wanted to test out some C++11 features like alignas(). You may want to use a less recent release version like 4.7.2. My experience with bleeding edge GCCs has usually ended up making me regret it. 4.8 release seems relatively close on the horizon though. So, YMMV.
Download gcc or use the trunk:
Code:
svn co svn://gcc.gnu.org/svn/gcc/trunk gcc-trunk
Edit the file gcc-trunk/gcc/config/arm/t-arm-elf to match the contents above.
Bootstrap gcc with:
Code:
mkdir arm-none-eabi
cd arm-non-eabi
../gcc-trunk/configure
--build=i686-apple-darwin10 \
--host=i686-apple-darwin10 \
--target=arm-none-eabi \
--prefix=/usr/local/teensy \
--enable-languages=c,c++ \
--disable-decimal-float \
--disable-libffi \
--disable-libgomp \
--disable-libmudflap \
--disable-libquadmath \
--disable-libssp \
--disable-libstdcxx-pch \
--disable-lto \
--disable-nls \
--disable-shared \
--disable-threads \
--disable-tls \
--with-float=soft \
--with-gnu-as \
--with-gnu-ld \
--with-newlib \
--with-headers=../newlib-1.20.0/newlib/libc/include/ \
--with-sysroot=/usr/local/teensy/arm-none-eabi \
--with-gmp=/usr/local/teensy \
--with-mpfr=/usr/local/teensy \
--with-mpc=/usr/local/teensy \
--with-ppl=/usr/local/teensy \
--with-cloog=/usr/local/teensy
make all-gcc
Grab a coffee. This will take at least a half hour.
After it finishes, you can test to make sure the multilib setup worked with:
Code:
gcc/xgcc -print-multi-lib
The output should match that above. Install:
Newlib:
Download latest
newlib (I'm using 1.20.0). I had a number of problems with newlib failing to compile for some variations of the architectures. Use this patch:
View attachment newlib.diff.txt (taken mostly from
here).
Code:
./configure --target=arm-none-eabi --prefix=/usr/local/teensy --enable-multilib --disable-libssp --disable-nls
sudo make install
Then back in
gcc:
make all
sudo make install
I had some trouble with the default linker script producing errors about missing __bss_start__. Use this patch:
View attachment gcc-8-mk20dx128.ld.diff.txt.
Can anyone suggest a reasonable way to test this compiler for correctness?
-c