Monday, April 13, 2009

Cross compilers, the new wave

When my faithful Linux machine silently died under my fingers, I knew I had a lot of work to do. I need a lot of different software and installing and configuring it takes quite some time. A job I'm particularly "fond" of is installing the cross compilers I need for my 4tH compiler. Yes, although I'm a dedicated Linux user, I create MS-DOS and MS-Windows packages as well.

Even if you're using a Debian-based distro this may apply to you, because although several people pointed out to me that cross compilers can be installed easily with apt-get, you're still left with a barebone cross compiler. The fun starts when you want to add a library. But since I use OpenSuSE 11.0 I have no such luck whatsoever. There are several cross compilers available from the repository for a host of different systems, but the ones I need are lacking.

So yesterday I took a deep breath and started installing. First I gave Volker Grabsch's MinGW cross compiling environment 2.5 a go. I had some very good results with his previous version, so I didn't worry too much about that one. The previous version consisted of a shell script, but this one was completely different. The documentation is very terse, so I felt a bit apprehensive anyway.

The first thing you should do is save any previous installation of the MinGW cross compiling environment. Assuming you've installed it under /opt/mingw (any other directory will do as well), you should execute the following commands:
su
mv /opt/mingw /opt/mingw.old
exit

Now download and unpack the tarball:
tar -xzvf mingw_cross_env-2.5.tar.gz

Then we need to transfer the entire directory to its definitive location. I will assume again you use /opt/mingw, but feel free to use any other directory if you like.
su
mv mingw_cross_env-2.5 /opt/mingw
exit

We're almost done. Just change to your newly created directory and get going:
cd /opt/mingw

Now it depends on what you actually want - or need. If you choose to enter:
make

You're in for a long wait, because Volker's tool compiles a lot of stuff. Almost seventy packages, including a whopping 58 libraries. On the other hand it doesn't require any intervention, so you're free to do whatever you like - like watch a movie or go for a night on the town. When it's done you'll find that you've installed a very capable Win32 cross compiler onto your system. Vanilla Debian packages won't provide you with a cross compiler environment as rich as this one.

Volker told me that if you only need the most basic tools you can also use:
make gcc

And add any additional packages you need later on. However, this has not been documented yet, but it will certainly be included in the next version. You can also supply a host of packages on the commandline, e.g.:
make gtk lua libidn

He assured me that you'll always end up with a consistent cross compiler environment. After you're done it just needs a little post-installation. Edit your .bashrc script in order to change $PATH:
export PATH=/opt/mingw/usr/bin:$PATH

BTW, note that any compiler related environment variables (like $CC, $LDFLAGS, etc.) may spoil your compiling pleasure, so be sure to delete or disable those. You probably will have to make a few adjustments to your Makefile:
CC=$(CROSS)gcc
LD=$(CROSS)ld
AR=$(CROSS)ar

You may have to add a few others, depending on your project. All you have to do is type this:
make CROSS="i386-mingw32msvc-"

If you're using configure, all you have to do is:
./configure --host="i386-mingw32msvc"
make

That's it! Don't let any warnings put you off:
configure: WARNING: If you wanted to set the --build type, don't use --host.
If a cross compiler is detected then cross compile mode will be used.

Everything will be just fine. All in all, Volker's MinGW cross compiling environment is a painless road to Win32 cross compilation. Highly recommended.

Now the really scary thing was on: the compilation of the MS-DOS cross compiler DJGPP. You may remember that the last time installation was far from flawless. Well, not much has changed. If you use a reasonably recent distro, this may help you. If not, refer to my previous post on cross compilers.

First download binutils, crx and gcc. Then execute the following commands:
su
rpm -Uvh djcrx-2.04pre-5.src.rpm

Now change to the SPECS directory, which is usually located at /usr/src/packages/SPECS. If not, you will have to find it for yourself. Then continue as root:
rpmbuild -bb djcrx.spec

After that you'll find a neat package in the RPMS directory. Install it:
cd ../RPMS/noarch
rpm -Uvh djcrx-2.04pre-5.noarch.rpm

Now return to the directory where you downloaded the files and install the next one:
rpm -Uvh djcross-binutils-2.19-9ap.src.rpm
cd /usr/src/packages/SPECS
rpmbuild -bb djcross-binutils-2.19.spec
cd ../RPMS/i586
rpm -Uvh djcross-binutils-2.19-9ap.i586.rpm

Return again to the directory where you downloaded the files and install the final one:
rpm -Uvh djcross-gcc-4.3.2-8ap.i686.rpm
exit

Done. That wasn't too hard was it? Well, I tried to compile the source RPM and after four attempts I simply gave up. I couldn't do it. I did a few simple tests and DJGPP seemed to work fine, although I have to stress I still have to test it properly. IMHO it is this kind of installs that give Linux its bad rap in certain circles and I hope the maintainers will get their act together in the future.

The bottom line? By using cross compilers I can create an entire Win32 installation package in the comfort of my Linux machine without resorting to virtual machines or proprietary software. So next time you install the 4tH compiler on your Windows machine, you know it is the first time it dwells in this environment.

Update: I've used the cross compilers in order to produce the release of 4tH v3.5d and they did the job. The MS-DOS cross compiler produced relatively large binaries, but they worked just fine. It was pointed out to me that there is a nice alternative to the MinGW cross compiler environment that also produces an OS/X cross compiler. I haven't tested this one, but since it might be interesting to others, I'm happy to list it as well.