ELLCC is a project aiming at creating a multi-target cross compilation environment for embedded systems. which makes use of Clang and the LLVM compiler infrastructure. QEMU is used for cross-platform testing.
The project goals are to implement the following key features:
- A functional C/C++ compiler based on Clang (ecc)
- Multi-target support: ARM, i386, Microblaze, Mips, Nios2, PowerPC, PowerPC64, Sparc and X86_64
- Multi-OS support: Linux, Standalone, …
- A complete test environment that allows automatic unit and integration testing of the run-time environment and complete executables.
- Support of a wide variety of target processors from armv4 to armv7, several mips cores, i386, and more.
The project is still being developed, and ELLCC is in a pre-release state.
ELLCC is composed of the following components:
- ecc – The ELLCC C/C++ compiler, a single executable with gcc compatible options.
- binutils – The GNU binutils package.
- libecc – The C standard library based on the musl standard C library and the LLVM project’s compiler-rt, using the BSD License.
- GDB debugger.
- QEMU emulator – To provide a test execution environment for multiple targets.
That seems like a massive undertaking (Also see target matrix), but let’s try with a simple hello world C program with i386, arm, mips and ppc architectures. I’ll use a build machine running Ubuntu 12.04.
Installing ELLCC
First install some dependencies, and get the code from the svn repository:
1 2 |
sudo apt-get install subversion texinfo build-essential svn co http://ellcc.org/svn/ellcc/trunk ellcc |
There’s a lot of code so it may take a while.
The build will fail is you use dash, so reconfigure your shell to bash
1 |
sudo dkpg-reconfigure dash |
and select “No”
Then build and install ellcc:
1 2 3 4 |
cd ellcc ./configure make make install |
Notice you don’t need sudo for make install, because it won’t install ecc in /usr/bin or /usr/local/bin, but just in the build directory in /bin and /lib directories.
Build Hello World for i386, ARM, MIPS and PPC
Now let’s write a highly sophisticated program in a file called hello.c:
1 2 3 4 5 6 |
#include <stdio.h> int main () { printf("Hello World!\n"); return 0; } |
Let’s build it for i386 (native build):
1 2 3 |
./bin/ecc hello.c -o hellox86 ./hellox86 Hello World! |
for ARM:
1 2 3 4 |
./bin/ecc -target arm-ellcc-linux hello.c -o helloarm /home/jaufranc/edev/playground/ellcc/./bin/ecc-ld: error: Source object /home/jaufranc/edev/playground/ellcc/bin/../libecc/lib/arm/linux/crtend.o has EABI version 0, but target helloarm has EABI version 5 /home/jaufranc/edev/playground/ellcc/./bin/ecc-ld: failed to merge target specific data of file /home/jaufranc/edev/playground/ellcc/bin/../libecc/lib/arm/linux/crtend.o ecc: error: linker command failed with exit code 1 (use -v to see invocation) |
Oups, it failed. But let’s try with other targets.
for MIPS:
1 2 3 |
./bin/ecc -target mips-ellcc-linux hello.c -o hellomips ./bin/qemu-mips ./hellomips Hello World! |
and for PPC:
1 2 3 |
./bin/ecc -target ppc-ellcc-linux hello.c -o helloppc ./bin/qemu-ppc ./helloppc Hello World! |
Great! So it works for MIPS and PPC. For ARM, I’ve checked with the maintainer (Richard Pennington), and there have been a few build script changes this week-end, which may explain why it fails. The latest SVN version should work. If you try it, you can update Bug 65 whether it works or not.
configure script, make and ellcc
Now let’s try something a bit more complicated, using the usual ./configure, make, make install procedure. Let’s build dropbear for MIPS.
First download and uncompress the source code:
1 2 |
wget https://matt.ucc.asn.au/dropbear/releases/dropbear-2012.55.tar.bz2 tar xjvf dropbear-2012.55.tar.bz2 |
then configure the build to use ecc:
1 2 3 4 5 6 7 |
cd dropbear-2012.55 CC="/home/jaufranc/edev/playground/ellcc/bin/ecc -target mips-ellcc-linux" \ LD="/home/jaufranc/edev/playground/ellcc/bin/ecc-ld -target mips-ellcc-linux" \ RANLIB="/home/jaufranc/edev/playground/ellcc/bin/ecc-ranlib" \ AR="/home/jaufranc/edev/playground/ellcc/bin/ecc-ar" \ STRIP="/home/jaufranc/edev/playground/ellcc/bin/ecc-strip" \ ./configure --target=mips-linux --host=mips-linux --disable-zlib |
and run make to build dropbear. This good thing is that you’ve got the explicit warning messages from clang, but the bad thing is that the build does not complete:
1 2 3 4 5 6 7 8 9 10 11 |
./dbutil.h:73:36: note: passing argument to parameter 'cmd' here void run_shell_command(const char* cmd, unsigned int maxfd, char* usershell); ^ svr-chansession.c:974:19: error: variable has incomplete type 'struct sigaction' struct sigaction sa_chld; ^ svr-chansession.c:974:9: note: forward declaration of 'struct sigaction' struct sigaction sa_chld; ^ svr-chansession.c:983:21: error: use of undeclared identifier 'SA_NOCLDSTOP' sa_chld.sa_flags = SA_NOCLDSTOP; |
I’ve tried with ecc native build (32-bit x86), and it works, so it’s possible some header files are missing or incomplete for mips target.
ELLCC is still being developed, and it might not be a good idea to use it on commercial projects at this stage, but it’s a very interesting tool, and I’ll certainly give another try to the release version. More information is available on ELLCC project page, and you could also follow ELLCC blog where Richard provides examples for ellcc (compilation, debugging…).
Jean-Luc started CNX Software in 2010 as a part-time endeavor, before quitting his job as a software engineering manager, and starting to write daily news, and reviews full time later in 2011.
Support CNX Software! Donate via cryptocurrencies, become a Patron on Patreon, or purchase goods on Amazon or Aliexpress