Cross-compiling applications for the Beaglebone

Yesterday I blogged about building Emacs on the Beaglebone. While this is great Sunday night fun, it’s not the most efficient way to compile applications for this device. The original Beaglebone has a 720 MHz processor and 256MB of RAM. My desktop has a 2.8GHz processer and 12GB of RAM. The turtle does not beat the hare in this race. It would be nice if I can compile an application on my desktop and send the compiled binary to the Beaglebone to run. Well, welcome to cross-compiling!

Now, there is a lot of information out there on building your own custom kernel, getting Ubuntu on the Beaglebone, etc… But that’s not what this post is about. This post attempts to answer the question, “I have an application in C/C++, how do I compile this for the Beaglebone.”

Sometimes, the simplest questions are the hardest to answer. Fortunately, I found this well-written summary. Basically, you can follow those instructions verbatim, but I’m going to outline the steps here in the case that site goes down and simultaneously, Google cache clears 🙂  Of course, after I found those instructions, I read the README on the setup-scripts distro itself, which has slightly different steps.  I have not yet gone back and tried those instructions…

I’ve got a Mac and while I love homebrew, I found it easier to work in Linux. So:

  1. I picked up an Ubuntu ISO.
  2. Loaded it up in Virtual Box.
  3. Updated packages, installed Emacs, etc…
  4. Download the Angstrom distro from github:
    git clone git://github.com/Angstrom-distribution/setup-scripts.git
  5. cd setup-scripts
  6. Followed the advice in the article and went to setup-scripts/conf/local.conf and commented out the line INHERIT += rm_work.
  7. Ran the following commands (the last one takes a while):
    MACHINE=beaglebone ./oebb.sh config beaglebone 
    MACHINE=beaglebone ./oebb.sh update 
    MACHINE=beaglebone ./oebb.sh bitbake virtual/kernel
  8. You may have to apt-get install packages if any of the above scripts grumble.

Now you’ve got the compiled kernel and target machine compilers. Let’s write a hello world program in C and send it to the board.

  1. Add the target compiler bin directory to your path (assuming your cloned from your home directory).  You’ll probably also want to put this in your appropriate bash config file as this only sets the PATH for your current session.
    PATH=$PATH:~/setup-scripts/build/tmp-angstrom_v2012_12-eglibc/sysroots/x86_64-linux/usr/bin/armv7a-vfp-neon-angstrom-linux-gnueabi
  2. Write a simple hello world program in C:
    #include <stdio.h>
    int main(void) 
    { 
      printf("Hello Beaglebone world!\n");
      return 0; 
    }
  3. To compile: arm-angstrom-linux-gnueabi-gcc -o hello hello.c
  4. Run: ./hello. Cannot execute binary file?!?! It worked! See, most likely your host computer is of an x86 architecture, which has different machine code instructions than an ARM (Beaglebone).  In this case, not working is a good thing.
  5. Fine, let’s see it really work. Put the binary on the board somehow (I’m using ssh / sftp).
  6. Run on the board!
Baby steps...
Baby steps…

That’s great if you have a small application.  But normally, a C program will have a makefile.  In this case type:

make ARCH=arm CROSS_COMPILE=arm-angstrom-Linux-gnueabi-

instead of the vanilla make and it will build for your Beaglebone. Getting the make install part might be a bit more tricky though since you still have to get the binaries on the board. Emacs built in about 7 minutes, running on VM on my mac compared to the 1 hour plus building directly on the Beaglebone. So, it pays to know how to cross-compile 🙂

11 thoughts on “Cross-compiling applications for the Beaglebone

  1. Do you happen to know what would have to change in these instructions to cross compile to the BeagleBone Black?

    1. Short answer: no, I haven’t tried.

      But, to which part are you referring? The kernel build or the make instructions? I did some searching at probably have come to the same conclusion that you did; it’s not very obvious. The best link I found was this which points to what sources were used.

      1. I’m not sure, my goal is to compile PCL for the BBB (one of the files needs more than 512MB of ram to build!), does that seem like the kind of thing I’d need a kernel build for? I did some searching and reached a very similar conclusion, and that is that I don’t know beans about cross compiling!

      2. Assuming by PCL you mean this?.

        My understanding is that you must build the kernel (or at least have the sources) on your build machine so that you can cross compile for the host. If it takes as much RAM as you say, than it may be tough building on the BBB.

        But, if that link above is correct, I noticed it requires cmake, not GNU make 😦 so there may be non-trivial differences.

        Maybe the first step is to find out if PCL is supported on ARM. If yes, then there’s hope. If the PCL people say no, that you would have a lot of work ahead of you. Maybe they have an IRC room / mailing list?

    2. Just a posing in case anyone has issues, if when doing “MACHINE=beaglebone ./oebb.sh bitbake virtual/kernel” you end up with “| make[1]: *** [doc/gcc.info] Error 1”, try downgradint your texinfo to version 4.x, seems version 5.x has some problems

  2. Thanks for the great tutorial, it works for beaglebone black. I was wondering if you know how to write a makefile to cross compile a .c file into .ko? I am trying to learn how to write device driver for beaglebone and I have no clue as for how to write the makefile…

    1. I have not successfully cross-compiled a kernel module yet. However, I was able to compile one on the BBB. If you look at how I did the Cryptodev module, you should be able to mimic that. The cryptodev makefile is pretty straightforward and can be a good template for your project. I had problems matching the kernel in my cross compile environment, with that of the BBB’s. So, it may take longer (to compile), but this may be the easier route.

Comments are closed.