Tuesday, December 16, 2008

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.

2 comments:

pela-suros said...

Note: in newer version of crosstool-ng (1.5.3) CT_BUILD should not be set and must be left emoty (read the HELP in the menuconfig).

Chao said...

Hey,

Great blog.

I have a problem with crosstool. How to add gtk support to it? (not java/gtk).

my arm-linux-gcc gave me the following error. I thought it could be a cflags problem or the gtk support is not added.

setup@jujube:~/beagle/gtk$ arm-linux-gcc hello.c `pkg-config --cflags --libs gtk+-2.0`/usr/local/xtools/lib/gcc/arm-unknown-linux-uclibcgnueabi/4.4.0/../../../../arm-unknown-linux-uclibcgnueabi/bin/ld: cannot find -lgtk-x11-2.0

Thanks a lot.

Chao