Author

Matthias Lang

Why Cross Compile

Cross compiling means using one type of system to compile the Erlang runtime system for a different type of system. A typical example would
be using an x86-based linux system to compile Erlang for an embedded MIPS CPU.

You usually cross compile when you want to run Erlang on a system which doesn't have its own development environment, i.e. no C compiler, libraries and make system.

In this howto, the term target means the system you want to run Erlang on when you're finished. The term build platform means the system you're using to compile the Erlang runtime system.

Prerequisites

A working C compiler and C libraries. Verify that it generates object files which run on the target, for instance by writing hello world. This howto assumes that your build platform is a unix or unix-like system.

The autoconf tools.

The Erlang/OTP source code, from erlang.org. The examples assume R10B-10.

Some cross-compiling experience. If you've never cross-compiled before, it's probably worth starting with something a bit simpler than Erlang, just to get a feeling for how it's meant to work. One suggestion: busybox.

Experience with native compiling Erlang. If you haven't built the Erlang runtime from source before, do that first, to get a feeling for how it's meant to work.

A generous serving of gumption.

Unpack the source

Make a directory for the cross compiling work, say /usr/local/src/mips_erlang/ and untar the source distribution there.

Patch the configure script

A couple of small changes to the configure script supplied with the Erlang source makes cross compiling much easier. Take this patch:

and apply it in the erts/ directory in the source tree you just unpacked.

After applying the patch, you need to re-run autoconf to update the configure script:

cd erts
autoconf configure.in > configure

Set environment variables for non-detectable features

In a native compile, the 'configure' script autodetects many settings by compiling and running small C programs. When cross compiling, this isn't possible, so you need to do some manual setup to override the autodetection:

The values of the variables above are correct for an AU1000 MIPS CPU running linux 2.4.x. They're probably not correct for your particular system. You need to manually figure out the right settings, i.e. is your system bigendian? How large is a long_long on your system? If you're not sure, write a short C program to find out, and run the C program on your target.

Set environment variables to set up the C compiler

Next, we need to set up the environment so that we use the right C compiler and related tools:

Run the configure script

Assuming configure ran all the way through without failing, we're now ready to compile. At this point, it's worth spending five minutes manually browsing through 'config.h' and checking that everything looks reasonable. For instance, you can check that the endianness settings are correct for your system.

Run make

TARGET=mips-linux make noboot | cat > buildlog

The above will take a while. After it's done, you probably want to install the Erlang runtime somewhere. Become root, and then:

TARGET=mips-linux make install

Correct the bin/erl path

There's one thing left to manually fix: the installed copy of the Erlang runtime will have some incorrect paths in it. Edit 'bin/erl' by hand to fix that.

Slimming the system

Disk space is often limited on embedded systems. By deleting parts of OTP you don't use, stripping binaries and recompiling all .beams without debug information and with the +compressed flag, it's
possible to get the entire Erlang system down to less than 3MB.

History

The build system in Open Source Erlang includes some relatively unappetising support for cross compiling to a VxWorks target.

Matthias Lang realised that for "similar build and target systems", it was possible to run 'configure' natively on the build system, hack the resulting makefiles to take into account differences between the build and target and then compile using a cross compiler.

Brian Zhou then pointed out how to use manual overrides through environment variables to avoid much of the hacking.

The methods described in this article are used to cross-compile Erlang for Motorola MPC 860 PPC systems, Au1000 MIPS systems and NSLU2.