The ELLCC tool chain can now completely build itself. Currently the build has been tested only on Linux systems. The steps I’ll use here are:
- Build ELLCC using the system compiler (bootstrap build)
- Build it again with itself (sanity build)
- Cross build it for another target machine (show off build)
ELLCC supports several target processors:
- arm – little endian ARM
- armeb – big endian ARM
- i366 – x86 in 32 bit mode
- microblaze – the Xilinx soft-core processor for FPGAs
- mips – big endian Mips
- mipsel – little endian Mips
- ppc – the Power PC in 32 bit mode
- x86_64 – x86 in 64 bit mode
The compiler we’ll be building can target all of them.
Go into a directory and get the latest ELLCC top of tree (TOT):
[~] dev% svn checkout http://ellcc.org/svn/ellcc/trunk ellcc
I checkout into a directory called ellcc, but the name isn’t important.
In this example. I checked out the files in my home directory. Now we can do the initial bootstrap build:
[~] dev% cd ellcc [~/ellcc] dev% ./build
The build takes quite a while because it is building ecc, the clang/LLVM based C/C++ compiler, GNU binutils for the assemblers, linker, and utilities, GDB for debugging, and QEMU for all the target processors for testing purposes. It also builds a compete set of run-time libraries:
- libc++ for the C++ standard library
- libc++ABI for C++ run-time suport
- libunwind for C++ exception handling
- musl for the C standard library
- compiler-rt for low-level support routines
- ncurses for terminal support
- zlib for compression/decompression
All of these libraries are built for all the supported target processors.
When the bootstrap build is finished, you’ll get a message like this:
Please run the build script again to bootstrap ecc. This may be done a few times: 1. ecc is built with itself (compiled with gcc) and libecc. 2. ecc is built with itself (compiled with itself) and libecc.
Run build again. This will build the ELLCC tools with themselves to complete the bootstrap.
Just run the same build command again:
[~/ellcc] dev% ./build
This time you won’t get the message above, since ELLCC has been completely bootstrapped.
Now for the fun part, a Canadian cross build.
In this step, we’ll use our newly built compiler to build a compiler that will run on a different target system. In this case, the ELLCC build rules don’t bother with compiling QEMU, since it is only used for ELLCC development. In addition, we can skip building the libraries, since they have already been built. I’ll do a build for an ARM target:
[~/ellcc] dev%de>[~/ellcc] dev% ./build arm
When this build completes, we’ll have a new directory populated with the ARM executables, bin-arm-linux:
[~/ellcc] dev% ls bin-arm-linux/ arm-elf-as* ecc-gdb* i386-elf-as* llvm-extract* macho-dump* bugpoint* ecc-gprof* llc* llvm-link* microblaze-elf-as* clang-check* ecc-ld* lli* llvm-mc* mips-elf-as* clang-format* ecc-ld.bfd* lli-child-target* llvm-mcmarkup* not* clang-tblgen* ecc-nm* llvm-ar* llvm-nm* opt* ecc* ecc-objcopy* llvm-as* llvm-objdump* ppc64-elf-as* ecc++@ ecc-objdump* llvm-bcanalyzer* llvm-ranlib@ ppc-elf-as* ecc-addr2line* ecc-ranlib* llvm-config* llvm-readobj* sparc-elf-as* ecc-ar* ecc-readelf* llvm-config-host* llvm-rtdyld* x86_64-elf-as* ecc-as* ecc-size* llvm-cov* llvm-size* ecc-c++filt* ecc-strings* llvm-diff* llvm-stress* ecc-elfedit* ecc-strip* llvm-dis* llvm-symbolizer* ecc-embedspu* FileCheck* llvm-dwarfdump* llvm-tblgen* [~/ellcc] dev% ~/ellcc[~/ellcc] dev% file bin-arm-linux/ecc bin-arm-linux/ecc: ELF 32-bit LSB executable, ARM, version 1, statically linked, BuildID[sha1]=0x9ff616a316ab010b46062f7fc1dff554ee7a6db8, not stripped /bin/qemu-arm bin-arm-linux/ecc -v clang version 3.4 (trunk) Target: arm-unknown-linux-gnu Thread model: posix Selected GCC installation: [~/ellcc] dev