Install Instructions for ZGCC: GNU compiler collection on Zaurus

First draft, February 15th, 2002
Updated March 15, 2003
Completely Revised for Release 2, November 4, 2003
Corrected with symbolic links for libc, libm Nov. 21, 2004 (thanks to respondent Uwe Koch)

Distribution version: 2.0

tracking GCC version 2.95.2

Hosting web site: http://community.zaurus.com

What it is:

Program development tools including all files necessary to do C and C++ language compiles, and to build complete Qt/E applications for the GUI built into the Zaurus PDAs and other devices (including make and the GDB debugger, and the moc and tmake Qt tools).

What is new in Release 2:

Releases 1 and 1.1 were based on gcc 2.95.1 to match the cross-compiling system distributed by Sharp and Trolltech, making presumably the most compatible system available. This release was built using gcc 2.95.2, with most components coming from the Debian Woody ARM distribution, to reduce storage (via smaller compiler executables and static libraries) and memory requirements to better fit the realities of the Zaurus, its built-in dynamic libraries, my personal needs, and my own "embedded system on-board compiling, debugging, and testing is good" mantra.

And this release adds the ability to design, compile, and test GPL'd Qt and Qtopia applications in ways that are arguably better, resource cheaper, and more convenient than any of the cross-compiler systems available. This Qt compilation system, based on the exploratory work of Jim Murff (via his "QtOntheZ" article), provides the Trolltech "moc" slot/signal precompiler, the Trolltech "tmake" project makefile builder (together with my custom template file), and the appropriate include files.

Finally, the GDB debugger and a number of other utilities have been added to make a more complete system.

The install has been simplified - zgcc is no longer required to live in the /usr directory hierarchy, and the problems with very many compiler related files showing up in the Qt "Documents" view is finally solved.

When stored on SD/MMC in its cramfs distribution format, it can be as small as 8 MBytes.

There are very few PDA based compiler systems with these abilities. This distribution has little that is Zaurus specific to it, however, and can probably be installed and used on a number of arm-linux devices with libc.so.6 support -- installation on Ipaq + linux would be an interesting test.

Limitations:

Why:

Well, I want to do onboard C/C++ development and I can, and I also want to share. This system solves the problem of development for the Z without having a separate PC Linux + cross compiler setup.

Requirements:

You will need to have some version of the console or terminal application installed -- the newest version of embeddedKonsole from one of the Zaurus program archives (such as www.zauruszone.com) is a good choice, but the terminal application built in to the 5000D and available on the CD included with other ZaurUS Models will suffice.

You will need about 23 Mbyte of storage for the full, uncompressed compiler system, or about 8 Mbytes of storage (on Ramdisk or SD/MMC) if you use the system in the mountable compressed cramfs volumes in which I am putting the distribution (the files "zgcc2Bin.cramfs" and "zgcc2Inc.cramfs"). The separate documentation cramfs volume (zgcc2Doc.cramfs) requires another 15 Mbytes uncompressed, or about 5 Mbytes if mounted compressed. You may, of course, opt to remove the Qt and/or the C++ capabilities to save space; C++ programmers will certainly regard the separate C compiler as superfluous.

Performance:

The compiler runs at about 1/3 to 1/4 as fast as x86 Linux on a 366 MHz Pentium II. The performance of the resulting executables shows a similar performance ratio (with no floating point code). This is a fast compiler, and this setup is capable of building large progams. (The test machine is a 206 mhz 5000D.)

Issues:

You must have sufficiant space in /tmp to hold the intermediate files during the compile. If you set up a very large swap file, use a ROM configuration with little available Ramdisk space, or fill up your Ramdisk with installed apps, this may be a problem. (See, however, the use of the TMPDIR environmental variable in the gcc documentation.)

The compiler, although involving a large executables, does not appear to have particularly problematical memory usage, and could, if you were pressed for executable memory, be used without starting the Qt GUI.

Compilation of Qt projects will severly tax the free execution RAM on Zaurii such as the 5000D -- the use of a ROM image with the largest executable memory partition is recommended.

Caveats:

Well, I have been able to build quite a few large C, C++ and Qt applications using these tools. My system is a 5000D with a 256 Mb Viking CF card in VFAT format and a 64 Mb Lexar SD card in ext2 format. Zgcc has been run extensively from the CF card uncompressed, and also from the SD card in the compressed cramfs format. I know that the C++ compiler has some issues with respect to exception handling accross C calls to shared libs -- see the docs/README.bugs file -- and I do little STL or template based programming, so there may be issues there. Further, the pared libc.so on the Zaurus is not the libc that the tools were built against, so there may be glitches left to uncover. I did leave out the standard configuration files for "make" and a lot of unnecessary other fluff that you may depend on -- you will need to find those things elsewhere and add it back in. The executables and libraries have been stripped of debugging info, and that may injure your use of GDB.

The "include" files were plucked from the cross-compiler distribution, but that means that they are not completely compatible with the more exacting C syntax rules of the new compiler. I have already corrected one such glitch and there may be more. If you run accross one of my hacks -- they are obvious and usually marked with "foxd" in a comment -- you may need to change something to get a compile.

License:

Go to www.gnu.org (or look in the included docs) to review the appropriate license for the compiler suite. I believe this distribution is in complience, but could stand correction if someone knows better. The Qt license has recently changed to be the GPL license for the header files I believe -- see http://www.trolltech.com for information on the status of the Qt/E Free SDK license if you wish to distribute Qt applications built usng the Qt tools and headers distributed here. To build your very own commercial Qt applications and make a fortune, you will at least need to buy the Qtopia commercial SDK (~$200) from Trolltech.

Installation overview:

One of the primary design goals of this release is improved management of the large number of files, reduction of large static storage requirements, and simplification of the configuration with respect to the situation in earlier releases. Specifically:

Option 1 -- Install the cramfs volumes:

Put the zgcc2Bin.cramfs and zgcc2Inc.cramfs files on your SD/MMC media (as, say, /mnt/card/zgcc2Bin.cramfs and /mnt/card/zgcc2Inc.bin), or, if you have room in Ramdisk, as, say, /home/QtPalmtop/share/zgcc2Bin.cramfs, etc.

Create subdirectories to be your mount points in the same place -- e. g.

mkdir /mnt/card/.zgcc
and
mkdir /mnt/card/.include
(Using subdirectories starting with a dot will prevent the Qt document-centric infrastucture and the Qt Filemanager from seeing them.)

Write a script (in your $PATH) to mount your volumes -- e. g. "mntzgcc.sh" containing:

mount -t cramfs /mnt/card/zgcc2Bin.cramfs /mnt/card/.zgcc -o loop
mount -t cramfs /mnt/card/zgcc2Inc.cramfs /mnt/card/.include -o loop

Running this script from the console command line with

source mntzgcc.sh
should successfully mount the volumes and make all of the compilers files visible via "ls /mnt/card/.zgcc", "ls /mnt/card/.include", etc.

Note that the Zaurus has only two loop devices (/dev/loop0 and /dev/loop1) set up in its default configuration. You can set up more -- use the command

mknod /dev/loop2 b 7 2
to make /dev/loop2 and
mknod /dev/loop[n] b 7 [n]
for the general case (up to n = 7, the presumed max). These will stick around until a reboot.

Option 2 -- Uncompressed Install:

To set up standard uncompressed directories, and presuming you have the necessary space (23+ meg), first mount as above from some convenient place in your system -- that could be a CF card temporarily for this operation. Once mounted, copy the contents from the mounted directories to your chosen install directories. For example to unpack "/mnt/cf/tmp/zgcc2Bin.cramfs" to "/mnt/cf/.zgcc" do

mkdir ztmp
mount -t cramfs /mnt/cf/tmp/zgcc2Bin.cramfs ztmp -o loop
mkdir /mnt/cf/.zgcc
cp -R ztmp/* /mnt/cf/.zgcc
umount ztmp
rm -r ztmp
And then do the same type of operation on zgcc2Inc.cramfs. After verifying that the contents of a cramfs volume have been correctly copied, you may, of course, delete the cramfs file.

Configuring the Compiler:

Now we need another script -- which should be launched by ~/.profile whenever bash starts. I call this script zgcc.sh (a copy of this script is in the "bin" directory for your reference) and it contains:

export GCC_EXEC_PREFIX=/mnt/card/.zgcc/lib/gcc-lib/arm-linux/2.95.2/
export COMPILER_PATH=/mnt/card/.zgcc/bin:/mnt/card/.zgcc/lib/gcc-lib/arm-linux/2.95.2/
export CPATH=/mnt/card/.include/
export LIBRARY_PATH=/mnt/card/.zgcc/lib/:/mnt/card/.zgcc/lib/gcc-lib/arm-linux/2.95.2/:/lib/:/home/QtPalmtop/lib/
export CPLUS_INCLUDE_PATH=/mnt/card/.include/g++-3/
PATH=/mnt/card/.zgcc/bin:$PATH
export PATH
LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/mnt/card/.zgcc/lib
export LD_LIBRARY_PATH
TMAKEPATH="/mnt/card/.zgcc/tmake/lib/sharp-onboard/"
export TMAKEPATH
ln -sf /lib/libc.so.6 /usr/lib/libc.so
ln -sf /lib/libm.so.6 /usr/lib/libm.so
ln -sf /mnt/card/.zgcc/bin/libstdc++-3-libc6.1-2-2.10.0.so /home/QtPalmtop/lib/libstdc++-libc6.2-2.so.3
This script could be run either manually preceding your compile, or by placing a line like
source zgcc.sh
in your ~/.profile script. I have it in my ~/.bashrc, which is in turn called by my ~/.profile. Its purpose is to allow the compiler stages and the "tmake" and "moc" tools to find their libraries, companion programs, and include files.

You are now ready to compile -- for example, with a file "foo.c" containing:

#include <stdio.h>
#include <math.h>
int main ()
{
  double x = 123.456;
  printf("sin(%f) = %f\n",x,sin(x));
}
compile with
gcc -o foo -lm foo.c
and execute (if it compiles without problems):

./foo
The 'make' utility is also included.

Configuring for Qt/E compilation:

If you want to compile Qt GUI applications, you have another choice to make. You can get the full benefit of the automated build process provided by Trolltech's tmake utility only if you install a version of the perl interpreter since tmake is a perl script. The present alternative is to make your Makfiles manually -- and I will give you some tips on that in a moment.

I have perl 5.6.1 installed and it looks like the whole thing is about 5 megs. -- sheesh. Well this is something we can hope to get fixed since Trolltech has already seen the light and made a new utilty -- qmake -- that is C++ based and could be statically compiled for our use.

Anyway, once you have a perl 5.x installed, you may need to edit both the first line of the tmake executable to point to your perl installation, and the tmake/lib/sharp-onboard/tmake.conf file to point to your Qt include files. If you are using the cramfs volumes, then editing also involves moving these file elsewhere (since the cramfs volumes are read-only). The TMAKEPATH environmental variable must point to the sharp-onboard directory whither you put it. You need only edit the tmake.conf file if you put the base of the Qt include files somewhere other than /mnt/card/.include/Qtopia. (Note that the Qt/E include files are in a subdirectory named "qte".)

The Trolltech utility "moc" also requires configuration, again because I have not succeded in compiling it specifically for our environment. The version I have included is dynamically linked against something called "libstdc++-libc6.2-2.so.3", which I don't have and will not work linked to a dynamic version of the static C++ library that I have chosen for the C++ compiler, so I have placed another apparently compatible dynamic library in the bin directory and the last line of the zgcc.sh script above forms the necessary symbolic link so that "moc" can find this library. This another kludge that we can hope to remove later.

I have included a simple Qt demo application in the "tmake/example" directory so that you can test your setup. Before you start playing around with it, copy this directory off to your work area. If you have installed perl, you should be able to use tmake to build your Makefile, and then compile:

perl /mnt/card/.zgcc/bin/tmake hello.pro>Makefile
or, if the first line of the tmake script points to your perl installation,

tmake hello.pro > Makefile
then
make
./hello
This test should confirm, on a succesful build of the executable "hello", all of the Qt and C++ settings.

If you wish to dispense with perl and tmake, you must make your Qt application makefiles manually. The Makefile in the tmake/example directory may serve as a template. The key ingredient that distinguishes Qt makefiles from those of standard C++ compilation is the appearence of the Q_OBJECT macro in a header or source file and the subsequent call to the "moc" preprocessor in the makefile to generate code for the signal/slot callback construct. Each file containing the macro must be processed by moc, and the resultant output files then compiled by g++. In the example, hello.h contains the macro, moc produces moc_hello.cpp, which is then compiled and linked into the executable.

Concluding remarks:

It's still too big damn big. Off of the full uncompressed install at about 23 Mb, you could do the following:

If you do not care to compile in the pure "C" of the default GNU C compiler (one can compile most C programs with the C++ compiler) you could pitch the gcc, c89 and cc1 programs saving 2 meg.

If you are not interested in Qt programming, delete the .include/Qtopia include file directory, moc and the supporting libstdc++-3-libc6.1-2-2.10.0.so shared library, and everything to do with tmake. This would save approximately 3Mb.

If you only want C programming capabilities, you could dump all of the Qt pieces and then cull the include/g++-3 directory, the g++ and cc1plus executables, and the libstdc++.a static library. That would save maybe 8 Mb in all.

Finally, you could take an axe to all those include files that surely are never used, but you would have to know what you are doing.

Note: several other packagers have made cramfs images for SD/MMC cards, but no cramfs volumes appear to work on CF cards because of unforgiving nature of the "unmount on suspend" behaviour of the Zaurus. My cramfs volumes suffer the same flaw -- if you need to put zgcc on a CF card then it should be uncompressed as detailed below. (I do hope a reader of this document can suggest an acceptable solution to this problem.)

Changing the contents of a cramfs volume:

Changing the contents of the cramfs volumes -- either to correct or add/remove funtionality -- will require that you uncompress first since these volumes are "read only" when mounted. I have added a copy of the "mkcramfs" program so that you can make new cramfs volumes. As an example of the syntax, I used a command like
mkcramfs /mmt/cf/.zgcc zgcc2Bin.cramfs
to make the cramfs mountable file "zgcc2Bin.cramfs" from the "/mnt/cf/.zgcc" directory. (Note: I fear that the advertised "insert file" capability of this version of "mkcramfs" is missleadingly documented or broken.)

To Do:

There will always be glitches to fix and utilities to add -- find my revision control system (RCS) elsewhere, and perhaps I will put out a build of "ctags" some time -- but the addition of a graphical design tool is probably what is needed most. This is a tool -- Qt Designer being an example -- that lets you precisly and graphically place widgets in a form so that your application windows have a polished "designed" look. There are several third party open source tools that could be ported to the Z.

If anyone can come up with a useful design tool, or merely compile qmake or moc properly for the Z, I will put together a new release with appropriate credit given.

Postscript:

Hey, this might not work do to my goof or yours so email me with your results and problems and suggestions and brickbats (Nerf only). I am really an unrecalcitrant Forth programmer, and will not be able to help you with the trickeries of C++ or Qt. I put the HTML version of Bruce Eckels' Thinking in C++ in my flash card and read along using Opera until the memory gives out.

Cheers,

Jeffrey R. Fox

Manitou Springs, CO

JeffreyRFox@msn.com

or, if that fails, JRFox@Adelphia.net