Catmaker's Blog

Ramblings of a Robot Cat Maker Wannabee, Because Real Cats Aren't Allowed :P

Cross Compile a Beagleboard ARM OpenCV Application

leave a comment »

Why is cross-compiling so difficult? Because the libraries aren’t there!

What I have:

An Ubuntu desktop running oneiric ocelot. Some OMAP3-based boards like beagleboards B5′s and C2′s, gumstix overo fires, and IGEP modules on self-built baseboards. But for this blog, I’ll just refer to all these experiments as for the beagleboard.

What the OMAP’s are running and are for:

Mostly linaro oneirics on rebuilt linux 3.1.2, running OpenCV experiments. Only one of the beagleboards (the C2) is connected to a VGA monitor, and it’s running the linaro ALIP (generally an XFCE based X), the rest of them are headless.

So far:

All of them can compile OpenCV applications natively on themselves. But the compiler and tools like g++, svn, etc is so slow.

Why do I want cross-compile on my desktop?
  1. Faster compilation!
  2. Better tools like emacs (or vi if you like it). Personally I’ve installed and use jed on the beagleboards — it’s small and fast, but I still prefer my emacs on the desktop anytime.
  3. Tools on my desktop like subversion svn to my repository also feels faster.
  4. Testing the same code on my desktop is also convenient. My desktop is, well, graphical: I can easily add/modify code to use the display components of opencv on my desktop, instead of guessing around results from my headless toys.
What’s already in place:

Rebuilding the ARM kernel on the desktop already fulfils some of the requirements of cross-compilation an application for the beagleboard.

sudo apt-get install build-essential arm-linux-gnueabi-gcc etc,etc.

With the above tools already installed, I could already compile and transfer a simple hello.c program.

me@desktop:~$ arm-linux-gnueabi-gcc hello.c -o hello.bin
me@desktop:~$ scp hello.bin me@beagle:
me@desktop:~$ ssh me@beagle

me@beagle:~$
me@beagle:~$ ./hello.bin
Hello, world!
me@beagle:~$

When that above application runs, I thinks the runtime startup libraries and the Standard C libraries libc for the arm are already in place.

So whaabout compiling something bigger?

Like an OpenCV application? With its application-specific shared libraries? Hmmm, here’s the example code from opencv webcam capture-and-show application:

/*
http://opencv.willowgarage.com/documentation/cpp/ \
highgui_reading_and_writing_images_and_video.html#videocapture
*/

#include <opencv/cv.h>
#include <opencv/highgui.h>
using namespace cv;

int main(int, char**)
{
    VideoCapture cap(0); // open the default camera
    if (!cap.isOpened()) // check if we succeeded
        return -1;

    Mat edges;
    namedWindow("edges", 1);
    for (;;) {
        Mat frame;
        cap >> frame;   // get a new frame from camera
        cvtColor(frame, edges, CV_BGR2GRAY);
        GaussianBlur(edges, edges, Size(7, 7), 1.5, 1.5);
        Canny(edges, edges, 0, 30, 3);
        imshow("edges", edges);
        if (waitKey(30) >= 0)
            break;
    }
    return 0;
}

And compiling the above with:

me@desktop:~$ arm-linux-gnueabi-g++ opencv_camshow.cpp -o opencv_camshow.bin \
              `pkg-config --libs opencv`
Epic failure!
  1. The arm-based libraries cannot be found.
  2. The pkg-config command returned the correct library names, but the linker tried to use my ubuntu-desktop’s x86 opencv library files instead.
  3. And the arm-based opencv libraries weren’t installed in the first place!

Natively compiling the above on my beagleboard isn’t a problem at all: Generally, all I had to do to compile an opencv application, the libraries required are installed by “apt-get install libcv-dev libhighgui-dev libcvaux-dev” and all their dependencies (like libgtk2.0, etc) will automatically be installed also.

But on my i386 ubuntu desktop, these arm-based cross libraries must be pre-installed before the arm-linux-gnueabi compiler can use them. With help from blogs, help forums and tutorials I found (see my references below), I only just managed to learn how to install these cross libraries. The directory location where arm-linux-gnueabi-g++ searches for these arm-based libraries are in /usr/arm-linux-gnueabi/lib

The desktop tool used to install arm-based cross libraries is called xapt, which like apt-get, but downloads and installs cross-architecture packages. And I had to add a one-liner file of /etc/apt/sources.list.d/armel-oneiric.list for it to work.
Also, the pkg-config tool to be used instead is the arm-linux-gnueabi-pkg-config which I found in a linaro blog tutorial. (It’s also available as an ubuntu-precise package as pkg-config-arm-linux-gnueabi, but I’m running oneiric).

me@desktop:~$ sudo apt-get install xapt
me#desktop:~$ sudo sh -c "echo deb [arch=armel] http://ports.ubuntu.com/ \
              oneiric main restricted universe multiverse \
              >> /etc/apt/sources.list.d/armel-oneiric.list"

me@desktop:~$ sudo wget 'https://wiki.linaro.org/PeterMaydell/A15OnFastModels\
?action=AttachFile&do=get&target=arm-linux-gnueabi-pkg-config' \
-O /usr/bin/arm-linux-gnueabi-pkg-config
me@desktop:~$ sudo chmod 755 /usr/bin/arm-linux-gnueabi-pkg-config

me@desktop:~$ sudo xapt -a armel -m libv4l-dev libgtk2.0-dev \
              libcv-dev libcvaux-dev libhighgui-dev

me@desktop:~$ arm-linux-gnueabi-g++ opencv_camshow.cpp -o opencv_camshow.bin \
              `arm-linux-gnueabi-pkg-config --libs opencv`

Still fails @#%$!!! — The compiler complains of missing libblas and liblapack!

me@desktop:~$ dpkg -l | grep liblas-armel-cross
me@desktop:~$ dpkg -l | grep liblapack-armel-cross

shows they’re installed, but the libraries just aren’t there in /usr/arm-linux-gnueabi/lib/…

Ahhhh! What to do? Copy over the natives from my beagleboard which are in /usr/lib/libblas and/usr/lib/lapack over to my ubuntu-desktop /usr/arm-linux-gnueabi/lib

me@desktop:~$ sudo scp -r beagle:/usr/lib/*libblas* \
              beagle:/usr/lib/*lapack* \
              /usr/arm-linux-gnueabi/lib
me@desktop:~$ arm-linux-gnueabi-g++ opencv_camshow.cpp -o opencv_camshow.bin \
              `arm-linux-gnueabi-pkg-config --libs opencv`

and compile! OK!! Finally builds!!! Copying over to my beagleboard…

me@desktop:~$ scp opencv_camshow.bin me@beagle:
me@desktop:~$ ssh -Y me@beagle

me@beagle:~$
me@beagle:~$ ./opencv_camshow.bin
    #(Here, the application starts on my desktop in an Xwin and shows the webcam capture. Hooo!!!)
me@beagle:~$^C


Awww… OK, I still have a problem with the libblas3gf-armel-cross and liblapack3gf-armel-cross arm packages. But, I’m so relieved that cross-compiling can be made to work after all.

My references:
About these ads

Written by catmaker

2011/12/21 at 16:29

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: