Tuesday, December 16, 2008

Using code sourcery to build a toolchain

Though it looks quite primising, it was very tough trying to build a cross toolchain using code-sourcery.

They provide prebuilt binary toolchains, but I none with the gcj compiler, so I had to use their build scripts to build my own toolchain.

The script they provide wasn't designed to run on any machine. In fact, it does not run on a machine different to the author's one. There are many hardwired directories and custom build is very tough. Though I tried to understand it, at the end some unexplainable errors appeared.

In conclusion, code sourcery for custom toolchains is not an option nowadays.

Testing the MIKA JVM

Downloading mika requires subversion as there seem to be no tarballs available for download.
Subversion requires port 3690, plus other tools.

Mika's repository is :
http://www.k-embedded-java.com/mika/trac/wiki/DownloadMikaNew

The dependencies are: jikes and jam.

Jikes is a java compiler from IBM. It is available as an rpm for FC4. No problems installing it.

Jam is a set of Ant scripts for building java applications. Just run configure, make, and make install. However, my FC4 has some broken links: /etc/alternatives/java_sdk_exports.
I had to edit the link to point to the installed JDK: /usr/lib/jvm/java-1.4.2-gcj

To build mika, I had to edit the Configuration/cpu/arm file, where the toolchain executables are defined. It wrongly assumes that the compiler was arm-linux-gcc, ignoring the CC variable.

To run the build process, type:
ant -DPLATFORM=default -DJAM.PLATFORM=arm-linux

Results are similar to the Skelmir's VM but with a different balance: setVisible is 3 times faster, but the screen creation is 3 times slower. The net performance is more or less the same.


Mika looks quite lightweight in terms of the flash footprint required.

Using crosstool-ng

The objective is to build a valid toolchain for ARM that supports gcj with the GTK peer classes.
The latest gcc is required (version 4.3) which has the latest GNU classpath version, and still evolving.

I tried several options to build a toolchain: crosstool, code-sourcery, etc, but crosstool-ng is the only one that was able to build a 4.3 toolchain without problems. The original crosstool was able to build a toolchain up to gcc 4.1.1/glibc 2.3.2. Newer versions of gcc or glibc did not compile.

Building and installing crosstool is very straightforward. Create a temporary directory, untar the tarball (crosstool-1.3.0) and run:

mkdir /usr/crosstool-ng (as root)
chown /usr/crosstool-ng

./configure --prefix=/usr/crosstool-ng
make
make install

and then add /usr/crosstool-ng/bin to the PATH variable.

The toolchain to be built is configured by running:
ct-ng menuconfig

There are some important hints:

1. The build tuple must be:
CT_BUILD=i686-pc-linux-gnu
which does not mean that the links i686-pc-linux-gcc -> gcc must be created. Crosstool-ng already creates its own wrapper scripts for this.

2. EABI
Defines how code is generated according to some specific conventions. gcc 4.3 is able to generate EABI-compliant code. All the user-space code must be compiled with the same EABI version, and the kernel must be compiled with EABI support if the user-space code is also EABI.
A toolchain may be created with EABI support, but this does not necessarily mean that the code generated is EABI. Some gcc flags control this. The glibc library was compiled using EABI, therefore the kernel must be compiled with EABI support, otherwise the 'init' program would not be loaded by the kernel.

3. Kernel headers
If we are using a new kernel (i.e. 2.6.1 or greater) then the best option is to use the sanitized kernel headers provided by the kernel's makefile. Crosstool-ng automatically invokes this makefile to generate the sanitized header set. By the way, using the latest 4.3 gcc, requires a late glibc (2.6 or 2.7), which in turn, requires a 2.6 kernel.

4. glibc ports
If the option "use glibc ports" is not enabled, the glibc compilation may return an error like "target arm is not supported". As of glibc 2.5, the architecture-dependent stubs of glibc are distributed as separate tarballs.

5. Dependencies
gcc 4.3 requires mrfp library version 2.3.2 or greater, which requires automake > 1.10 and autoconf > 2.60. There are no rpms for these versions for FC4, so I had to download the sources and install them manually

6. Enabling gcj/java support
Must enable the java language.
Also, the specific java/gtk support must be enabled in the gcc build flags:

CT_CC_EXTRA_CONFIG=

--enable-java-awt=gtk --enable-gtk-cairo --disable-gtktest
--x-libraries=/lib --x-includes=/include/X11

note that the GTK peer classes provided by GNU classpath require some X libraries, though the GTK compiled uses the Directfb frontend, not the X-lib frontend. It seems that it still uses some X libraries for rendering functionality or something like that. Hopefully, these libraries are not required in the target system. In particular, it requires the libXtst, libart, libXrender and libXrandr libraries.

It is important to set the pkg-config variables, so that the configure scripts of gcc and its subprojects are able to find the GTK libraries:

export PKG_CONFIG_PATH=/usr/lib/pkgconfig
export PKG_CONFIG_LIBDIR=/usr/lib/pkgconfig

the pkgconfig files (.pc) must be placed in these directories. Note that the 'prefix' keys in these files must be set to the location of the installed GTK files /usr.

there are GTK include files in different locations, such as: usr/lib/glib-2.0/include.

7. Restarting crosstool-ng
Crosstool has a nice feature that allows the process to be restarted at some specific stage, thus speeding up the trial and error build process. However, this functionality must be enabled in the menuconfig, and this functionality has some limitations:
1. changing some configuration items (i.e. gcc build flags) take no effect if the process is restarted. The entirre build process must be started from the beginning.
2. Do not break crosstool-ng while downloading the tarballs. If so, clean the tarballs directory as some files may be corrupted.

8. X libraries
Some GTK peer classes cannot be compiled because they require a GTK library compiled with xlib support. For instance, the cairo-xlib.h and gdk/gdkx.h include files are required.

After all these steps were solved, a toolchain with gcj/gtk support was built without errors.