Cross-compiling from OS X to ARM with ELLCC

477 views Asked by At

I'm trying to cross-compile a C++(14) project from OS X to ARM to be run on a Cortex-M4 chip. The ELLCC project seems like it can be used for that, so here's what I did:

  1. Setup a simple test file (main.cpp) as follows:

    #include <cstddef>
    
    int main() { }
    
  2. Download the latest version of ELLCC for OS X from http://ellcc.org/releases. The download takes a while, but when it's done I unpack the resulting tarball and my sandbox looks like:

    sandbox/
        main.cpp
        ellcc/
            bin/
            examples/
            libecc/
    
  3. Use ecc++ to (try to) cross-compile:

    ./ellcc/bin/ecc++ -target arm-none-eabi main.cpp
    

Unfortunately, ecc++ is unable to find the cstddef header:

ldionne in ~/Desktop/ellcc-tests % ./ellcc/bin/ecc++ -v -target arm-none-eabi main.cpp
ecc 0.1.17 based on clang version 3.8.0 (trunk) (based on LLVM 3.8.0svn)
Target: arm-none--eabi
Thread model: posix
InstalledDir: /Users/ldionne/Desktop/ellcc-tests/./ellcc/bin
 "/Users/ldionne/Desktop/ellcc-tests/ellcc/bin/ecc" -cc1 -triple armv4t-none--eabi -emit-obj -mrelax-all -disable-free -main-file-name main.cpp -mrelocation-model static -mthread-model posix -mdisable-fp-elim -fmath-errno -masm-verbose -mconstructor-aliases -target-cpu arm7tdmi -target-feature +soft-float-abi -target-feature +strict-align -target-abi aapcs -mfloat-abi soft -target-linker-version 253.3.3 -v -dwarf-column-info -resource-dir /Users/ldionne/Desktop/ellcc-tests/ellcc/bin/../libecc -fdeprecated-macro -fdebug-compilation-dir /Users/ldionne/Desktop/ellcc-tests -ferror-limit 19 -fmessage-length 181 -fallow-half-arguments-and-returns -fno-signed-char -fobjc-runtime=gcc -fcxx-exceptions -fexceptions -fdiagnostics-show-option -fcolor-diagnostics -o /var/folders/hs/9ydnxpjd3plbjqsz34p9cxz00000gn/T/main-d365df.o -x c++ main.cpp
clang -cc1 version 3.8.0 based upon LLVM 3.8.0svn default target x86_64-apple-darwin14.5.0
#include "..." search starts here:
#include <...> search starts here:
 /usr/local/include
 /Users/ldionne/Desktop/ellcc-tests/ellcc/bin/../libecc/include
 /usr/include
End of search list.
main.cpp:1:10: fatal error: 'cstddef' file not found
#include <cstddef>
         ^
1 error generated.

First question: what am I missing? Shouldn't this work out-of-the-box?

Trying to workaround the missing header issue, I manually adjust the header search path of the compiler by adding -isystem ellcc/libecc/include/c++. ecc++ now finds <cstddef>, but it can't find bits/alltypes.h:

ldionne in ~/Desktop/ellcc-tests % ./ellcc/bin/ecc++ -v -target arm-none-eabi -isystem ${PWD}/ellcc/libecc/include/c++ main.cpp
[snip]
 "/Users/ldionne/Desktop/ellcc-tests/ellcc/bin/ecc" -cc1 -triple armv4t-none--eabi -emit-obj -mrelax-all -disable-free -main-file-name main.cpp -mrelocation-model static -mthread-model posix -mdisable-fp-elim -fmath-errno -masm-verbose -mconstructor-aliases -target-cpu arm7tdmi -target-feature +soft-float-abi -target-feature +strict-align -target-abi aapcs -mfloat-abi soft -target-linker-version 253.3.3 -v -dwarf-column-info -resource-dir /Users/ldionne/Desktop/ellcc-tests/ellcc/bin/../libecc -isystem /Users/ldionne/Desktop/ellcc-tests/ellcc/libecc/include/c++ -fdeprecated-macro -fdebug-compilation-dir /Users/ldionne/Desktop/ellcc-tests -ferror-limit 19 -fmessage-length 181 -fallow-half-arguments-and-returns -fno-signed-char -fobjc-runtime=gcc -fcxx-exceptions -fexceptions -fdiagnostics-show-option -fcolor-diagnostics -o /var/folders/hs/9ydnxpjd3plbjqsz34p9cxz00000gn/T/main-9cd9a7.o -x c++ main.cpp
[snip]
#include <...> search starts here:
 /Users/ldionne/Desktop/ellcc-tests/ellcc/libecc/include/c++
 /usr/local/include
 /Users/ldionne/Desktop/ellcc-tests/ellcc/bin/../libecc/include
 /usr/include
End of search list.
In file included from main.cpp:1:
In file included from /Users/ldionne/Desktop/ellcc-tests/ellcc/libecc/include/c++/cstddef:43:
/Users/ldionne/Desktop/ellcc-tests/ellcc/bin/../libecc/include/stddef.h:17:10: fatal error: 'bits/alltypes.h' file not found
#include <bits/alltypes.h>
         ^
1 error generated.

Not giving up, I manually adjust the header search path again by adding -isystem ellcc/libecc/include/arm. But now I get a link error:

./ellcc/bin/ecc++ -v -target arm-none-eabi -isystem ${PWD}/ellcc/libecc/include/c++ -isystem ${PWD}/ellcc/libecc/include/arm main.cpp
[snip]
/usr/local/Cellar/gcc-arm-none-eabi-49/20150609/bin/../lib/gcc/arm-none-eabi/4.9.3/../../../../arm-none-eabi/lib/libc.a(lib_a-exit.o): In function `exit':
exit.c:(.text.exit+0x2c): undefined reference to `_exit'
collect2: error: ld returned 1 exit status
ecc: error: linker (via gcc) command failed with exit code 1 (use -v to see invocation)

The output is pretty long, so I only included the relevant bit here. The full output is here.

Second question: Why doesn't it link?

Note that I have arm-none-eabi-gcc installed already, which I believe is why ecc++ uses it to link instead of a linker provided with ELLCC itself. I can't use arm-none-eabi-gcc as a frontend, because its support for C++14 is buggy and I'm doing some serious metaprogramming.

Thanks for any help.

1

There are 1 answers

0
Richard Pennington On BEST ANSWER

ELLCC is designed to be a cross compiler tool chain.The ultimate goal is to allow cross compiling from any host to multiple target environments. Currently cross compiling to Linux and Windows is supported out of the box with limited support for bare-metal systems.

Generally, one of the configurations in ellcc/libecc/config is used to tell the compiler where to find header files and libraries. Each of the files in ellcc/libecc/config is a text file and is read if it is mentioned in as the argument of an ecc(++) -target option. If you look at these files, you'll see how they set up include paths, etc. The thumb-linux-engeabi target will compile an linux application using the cortex-m3 (thumb) instruction set.

ELLCC has precompiled libraries for Linux and Windows targets and (very) limited support for bare-metal targets like the cortex-m4. Currently larger ARM chips (A8, A9, etc) have the most bare metal support. For example go to ellcc/examples/elk type

[~/ellcc/examples/elk] Richards-Mac-mini% make arm-elk-engeabi
cat: config: No such file or directory
rm -f *.o elk elk.bin elk.log elkconfig.ld
Preprocessing elkconfig.cfg
Compiling main.c
Compiling test_commands.c
Linking elk
[~/ellcc/examples/elk] Richards-Mac-mini%

This will build an executable for an A8. You can run it by:

[~/ellcc/examples/elk] Richards-Mac-mini% make run
Running elk
enter 'control-A x' to exit QEMU
elk started. Type "help" for a list of commands.
fragcnt = 1 size = 42 tx = 4608
got 'hello world
'
Try the command 'inetif'
elk % 

This is running under QEMU in system emulation mode with no OS. It is using the normal C and C++ standard libraries for ARM Linux, but emulating the Linux system calls instead of having Linux do it.

I want to have a similar capability for the cortex-m4 eventually, but I don't have it yet (interference of day job, family, etc.) I have done a little preliminary work for example see my post about compiling for the cortex-m3.

I know this doesn't really answer your question, but I hope it makes how ELLCC works a little clearer.