Cross compiling Erlang for the BeagleBone Black
Note: this was updated on 02/02/2014
Here are the steps I followed to cross compile from an amd64 Debian host onto the ARM-based target board running Ångström Linux.
Getting the Ångström cross-compiler toolkit
Since my host was an amd64 Debian one, I downloaded the x86_64 cross compiler toolkit from http://www.angstrom-distribution.org/toolchains/:
The file itself is simply a gzipped self installable script. Once gunzipped, simply make the file executable and run it:
$ gunzip angstrom-eglibc-x86_64-armv7a-vfp-neon-v2012.12-toolchain.gz $ chmod +x ./angstrom-eglibc-x86_64-armv7a-vfp-neon-v2012.12-toolchain $ sudo ./angstrom-eglibc-x86_64-armv7a-vfp-neon-v2012.12-toolchain
I followed the default instructions which installed the toolkit under /usr/local/oecore-x86_64/.
Getting the latest Erlang from source
I simply got it from GitHub:
$ git clone https://github.com/erlang/otp.git
The instructions for cross compiling Erlang can be found here.
Some notes about the actual compilation steps
I originally tried to follow what the instructions mentioned regarding cross compiling using the otp_build script that resides in the root of the Erlang source tree. This also meant that I had to create a new configuration script under the xcomp folder and pass it to otp_build using the --xcomp-conf flag.
Unfortunately this didn't work for me and I kept getting the following assembler-related errors:
$ pthread/ethread.c: Assembler messages: $ pthread/ethread.c:190: Error: invalid instruction suffix for `pop' $ pthread/ethread.c:193: Error: invalid instruction suffix for `push' $ pthread/ethread.c:196: Error: invalid instruction suffix for `pop' $ make: *** [obj/x86_64-unknown-linux-gnu/opt/r/ethread.o] Error 1
My initial investigation seems to lead to an incompatibility issue between the code getting cross compiled assuming the 32bit ARM architecture and the actual host toolchain assuming it is 64bit.
I might try to dig deeper into why exactly this happened in the future, but for now I'll describe the alternative method which is also documented in the cross compiling instructions of Erlang/OTP. This is the one that worked for me and it involves calling the autotools/make toolchain manually rather than running the otp_build script.
Building the bootstrap system
Cross compiling Erlang first requires a working version of Erlang on the host system (in my case this was Debian). Since the version needs to match the one that we actually want to cross compile, it is recommended to first build a minimal bootstrap system in the same source tree as the one where the actual cross compiled target will be built.
This was done by running the following:
$ export ERL_TOP=`pwd` $ autoreconf -ifv $ ./configure --enable-bootstrap-only $ make
Once the bootstrap system had been built the next step was to setup the shell environment so that all the compiler-related tools (i.e. CC, AR, ...) are the ones from the cross compiler toolkit. After this is setup, I simply had to run make after first telling configure to cross compile.
$ source /usr/local/oecore-x86_64/environment-setup-armv7a-vfp-neon-angstrom-linux-gnueabi $ ./configure --host=arm-bbb-linux --build=amd64-debian-linux $ make
Then I staged the installation into a target folder and archived it so that it could be moved onto the BeagleBone.
$ mkdir /tmp/bb_erlang $ make install DESTDIR=/tmp/bb_erlang $ cd /tmp/bb_erlang $ tar zcvf bb_erlang.tar.gz usr/
Finally, I copied it onto the stock BeagleBone Black board.
$ scp bb_erlang.tar.gz firstname.lastname@example.org: $ ssh email@example.com $ cd / $ tar zxvf ~/bb_erlang.tar.gz .
That was it. I was then able to run Erlang on my BeagleBone Black.