Embedded Development, Linux

Building a Cross-Compilation Environment for the BeagleBone

Do What?



Want to write a native executable for the BeagleBone?  You have a few options.  One is to compile the code directly on the BeagleBone with the native compiler that is included with the BeagleBone distribution you are running (if it includes one).  The other is to use a cross-compiler and compile the code on another computer.  This first option will work fine for smaller programs and the official distribution for the BeagleBone is Angstrom Linux-based and includes a compiler.  However, compiling on the Bone itself will be slow for large code bases (like the whole Linux kernel.)  Cross-compiling is better suited for bigger software programs and is much faster on modern PCs.

Here are a simple set of instructions for building the cross-compiler tools for two of the more popular Linux distros to allow you to compile native applications for your BeagleBone.  This information isn’t new and I’ve included the links to the original material below.  However, I’ve added a few tidbits more of information for compiling in either an Ubuntu or CentOS.

What OS Do You Need?

This tutorial assumes you have already installed Linux natively on your hardware or as a virtual machine.  I used a VM in VirtualBox to accomplish these steps.  One VM was an Ubuntu variant (Xubuntu to be exact) and the other VM was CentOS.  Both worked well.  Ubuntu seems to cooperate better out of the box with the VirtualBox Guest Additions to allow the VM to operate more seamlessly.  This is primarily because the base Ubuntu distros include more packages.  CentOS is a slimmer default install but will work fine, too, with some manual tweaking.  The Guest Additions are helpful for things like cutting-and-pasting text to and from the guest OS and for resizing the VM to fit various window sizes.

I allotted both CPUs of my dual-core laptop as well as 2 GBs of memory to the VM.  This much memory is required for the build as the OpenEmbedded/Yocto compilation process builds up some large caches that require the memory.  Anything less than 2 GBs will likely cause build failures.  Once the cross compilation tools are built, you can reduce the amount of memory for the VM if need be.

Note, too, that the build process will generate almost  20 extra Gigabytes of data.  Therefore, count on sizing the virtual hard disk of your VM to be able to handle this file data.  I typically use a dynamic type disk in VirtualBox, but only allocate a small portion of it to the OS.  This let’s me grow it later.  I started out giving Linux only 40GB of a 120GB disk.  My CentOS VM started out at about 3 GB and grew to almost 23 GB.  In retrospect I probably should have gone ahead and given it 100 GB so as not to have to worry about do other kernel builds while maintaining my old ones.  I can always resize the partition later.

Get the Linux Packages You Need

Before the Angstrom Link process will completely build, you need to ensure you have all the required packages on your build OS/VM/PC/Computerthingy.

UbuntuPackages for Ubuntu

Using apt-get, acquire the following packages for your build:

sudo apt-get install git subversion gawk texinfo texi2html chrpath diffstat gcc gcc-c++ libgcc libstdc++ make

CentOSPackages for CentOS

Using the yum installer, acquire the packages below for your build.  Note that if you followed the CentOS instructions for setting up the Virtual Box Client Additions, then you will have already acquired some of these packages so this will progress quicker:

su -c 'yum install git subversion gawk texinfo texi2html chrpath diffstat gcc gcc-c++ libgcc libstdc++ make'

Grab the build scripts

To start the build process you’ll next need to grab the build scripts. These build scripts are based on the OpenEmbedded project’s build system of BitBake recipes.  This system is an alternative process of constructing Linux builds vs. the Buildroot method.  The build scripts are responsible for pulling down the required source, setting up the build environment, and then executing the build.  First, from your main user directory, make a directory to hold the build scripts.  I often named it “development” but you could name it “Francis”, “lemonmeringue”, or “portuguese_antelopes” if it makes you happy.

mkdir development

Change directories into this directory and retrieve the build scripts from the official Angstrom repository:

cd development
git clone git://github.com/Angstrom-distribution/setup-scripts.git

Note that the distribution of Angstrom Linux I was running on the BeagleBone which I was testing was an image created in November of 2012.  Since I pulled the latest version of the Angstrom distro and followed the generic instructions for building the BeagleBone kernel and libraries, I’m assuming it will work with the latest, too.  I had tried using the latest version of the official BeagleBone Angstrom distro (June 2013), but experienced trouble with the gadget driver not even showing up (at least when interfacing to my MacBook.)  This build compatibility implies that the kernel version has stayed similar enough to be binary compatible with BeagleBone builds in the last year or so.  If the builds aren’t binary compatible (compatible to the kernel headers) the application just won’t run.

Tweak It a Smidgen

The default build configuration will delete the kernel sources once the build is complete.  This might be annoying if you want to make any tweaks or changes.  So, you’ll want to edit the configuration to prevent this.  Open the file “conf/local.conf” file (that is within the “setup-scripts” directory) using your favorite text editor and comment-out or remove the following line:

INHERIT += “rm_work”

You can comment it out by inserting a hash, “#”, in front of the line.  I chose to comment it out.

Build It Already!

From the terminal prompt within the “setup-scripts” directory type the following three commands in succession.  The first will take about five minutes to execute (depending on the speediness of your computer).  The second less than a minute.  And the third will really depend on how fast your machine it.  My CentOS VirtualBox VM running in a host OS of OS X 10.8 on a 2.3 GHz Intel Core i5 took about 3 hours.  The three commands are:

MACHINE=beaglebone ./oebb.sh config beaglebone

… lots of output gets spit out after this one …

MACHINE=beaglebone ./oebb.sh update

… lots of output gets spit out after this one …

MACHINE=beaglebone ./oebb.sh bitbake virtual/kernel

… lots of output gets spit out after this one ….  Here are the last several lines of the output from my successful build:

NOTE: Preparing runqueue
NOTE: Executing SetScene Tasks
NOTE: Executing RunQueue Tasks
WARNING: Failed to fetch URL http://www.apache.org/dist/apr/apr-util-1.5.1.tar.gz, attempting MIRRORS if available
WARNING: Failed to fetch URL http://cbuild.validation.linaro.org/snapshots/gcc-linaro-4.7-2013.02-01.tar.bz2, attempting MIRRORS if available
WARNING: Failed to fetch URL ftp://ftp.ossp.org/pkg/lib/uuid/uuid-1.6.2.tar.gz, attempting MIRRORS if available
WARNING: QA Issue: linux-mainline: Files/directories were installed but not shipped
NOTE: Tasks Summary: Attempted 907 tasks of which 249 didn't need to be rerun and all succeeded.

Where Are They?

The cross-compiler executables are located in the directory listed below.  The path to this directory may be different for your build, but will still be similar.


The contents in this directory are:


Build a Simple App

To test that the cross-compiler is working, let’s build an incredibly simple “Hello World!” type application.  First, make a new directory from beneath your development directory (or whatever you called it) and name it, “howdy”

mkdir ~/development/howdy

Then cut and paste this text into a text editor and save it as howdy.c in your newly created directory:

#include <stdio.h>

int main(void)
   printf("Hey you!  Yes, you, the big nerd in front of this monitor!  This program worked.\n");
   return 0;

Next, update your path environment variable like so (you can make it permanent if you want by adding it to your .bashrc file.):


Then compile your file to get a simple executable:

arm-angstrom-linux-gnueabi-gcc -o howdy howdy.c

You should see that a “hello” executable file is created.  One that you can’t run on your Linux build box, by the way, since it is for the BeagleBone.  Next, copy this file to your BeagleBone (using “scp” if you have a network connection is the easiest).  Try to run it and it should spit out the the correct text.  That’s it!  Here’s the “scp” command I used to copy my compiled file from my VM to my network connected BeagleBone whose IP address was

scp howdy root@

And here’s the output on the BeagleBone:

root@beaglebone:~# ls -al
total 32
drwxr-xr-x 3 root root 4096 Jul 14 02:09 .
drwxr-sr-x 3 root root 4096 Nov 21 2012 ..
-rw------- 1 root root 139 Jul 14 02:05 .bash_history
-rw-r--r-- 1 root root 20 Nov 22 2012 .bashrc
-rw------- 1 root root 623 Nov 22 2012 .viminfo
drwxr-xr-x 2 root root 4096 Jan 1 2000 Desktop
-rwxr-xr-x 1 root root 7866 Jul 14 02:06 howdy
root@beaglebone:~# ./howdy
Hey you! Yes, you, the big nerd in front of this monitor! This program worked.


Much thanks to these two posts from where I regurgitated all this material.