Friday, June 22, 2012

Cross Compiling and Cross Debugging C++ with Eclipse from Debian Squeeze x64 to Debian Squeeze ARM (Raspberry Pi)

1. Introduction

I have received yesterday my Raspberry Pi (http://www.raspberrypi.org/unit. 


Fig 1. Raspberry Pi connected




After complete successfully the basic setup (http://www.raspberrypi.org/quick-start-guide)  and after installing the Debian Squeeze distribution provided by the community (http://www.raspberrypi.org/downloads) I want to collaborate with this interesting project by writing a step by step tutorial that will show how to create a program on C++, and how to run it and debug it on our Raspberry.

2. Pre-Requirements


2.1 Eclipse

As usual Eclipse is not completely mandatory (You can directly write C++ files with almost any text editor), but It is a great help.


If you do not have JAVA yet, you have to install it. You can do it from the  package manager.

Download Eclipse IDE for C/C++ Developers from the official download page (http://www.eclipse.org/downloads/)


Unzip it and execute the 'Eclipse' file inside the 'Eclipse' folder


2.2 Arm Toolchain Cross Compilation

In order to generate programs that can run and be debugged on our RaspBerry, we need to install an appropriated compiler and an appropriated debugger.

2.2.1. Add the native compiler, make and ncurses library if they are not already in your development system.


sudo apt-get install gcc g++ make libncurses5-dev


2.2.2. Add the following line to /etc/apt/sources.list


deb http://www.emdebian.org/debian/ squeeze main

2.2.3. Install the following packages:

sudo apt-get install linux-libc-dev-armel-cross
sudo apt-get install libc6-armel-cross 
sudo apt-get install libc6-dev-armel-cross 
sudo apt-get install binutils-arm-linux-gnueabi
sudo apt-get install gcc-4.4-arm-linux-gnueabi
sudo apt-get install g++-4.4-arm-linux-gnueabi 
sudo apt-get install uboot-mkimage

2.2.4. Install the remote gdb:

sudo apt-get install gdb-arm-linux-gnueabi

warning: At this point you can find conflicts with the already installed gdb (http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=603347). If it is the case you will need to upgrade from gdb 7.0.1 (the currently installed) to gdb 7.4.1 (You can find it on http://ftp.gnu.org/gnu/gdb/). You will need to download it, configure it and install it, but do not worry too much, there are just 3 steps that can be found on the README file inside the downloaded file.

3. Our first Raspberry project

3.1 Open Eclipse and click on File --> C++ Project

3.2 Select Cross-Compile Project and give it a name and click on finish.

Fig 2. Our first Raspberry project on C++


3.3 Create a "src" folder inside the just created project and include a source file called "main.cpp" inside it. Fill the main.cpp with the following content:

Fig 3. Content and structure of our first Raspberry project on C++

4. Cross Compiling and executing the 'Hello World' project


4.1 Now that we have our project written, we need to compile it. In order to do that, open the project properties select settings and on the 'Cross G++ Compiler' change the command 'g++' by arm-linux-gnueabi-g++:

Fig 4. Cross project compiler

4.1 Do the same on the Cross G++ Linker:

Fig 5. Cross project linker


4.2 Build the project, (Ctrl+b) you should get a message on the console like the following one:

Fig 6. Cross project linker

As you can see, the project has been compiled and linked by using arm-linux-gnueabi-g++, that was the whole point. If you try to run the compiled from eclipse you wont see nothing happening. If you try to run it from the command line, it wont be recognize as an executable:

Fig 7. Error when executing the result from the host


But if you copy it and execute it from the Raspberry:


Fig 8. Project executed from Raspberry

Voila!! Our first C++ Cross-project running on Raspberry  :D

4. Cross Debugging the 'Hello World' project


Now that we have run successfully our project, let's see how we can debug it.


4.1 Install on your Raspberry gdbserver


sudo apt-get install gdbserver 

4.2 Run gdb server against your program, listening on the port 2345:

gdbserver :2345 MyFirstRaspBerryProject

If everything went ok, the system should get stuck waiting for a remote debug:

Fig 9. gdbserver started on the raspberry machine

4.3 From Eclipse click on the arrow besides the symbol of debug and select 'Debug Configurations'. Click twice on the tab 'C/C++ Remote Application' an new remote application will be automatically created:

Fig 10. New debug configuration


Click on the text 'Select other...' besides the button 'Apply'. On the new window, check the box 'Use configuration specific settings' and select  'GDB (DSF) Manual Remote Debuggin Launcher':

Fig 11. Manual Remote selection

Clicking on OK it will bring us to the previous screen. Set the main and debugger tabs as following:

Fig 12. Main Tab

Fig 13. Debugger Main Tab


Fig 14. Debugger Connection tab


Now you can click on the Debug button and:

Fig 15. Cross Debugging our project


33 comments:

  1. Thanks for this tuto! I'll try that as soon as I receive my Pi!

    ReplyDelete
    Replies
    1. Thank to you for reading it. Yo do not necessarily wait for your RB to come, you can start developing and testing your software virtually with quemu :)

      http://wiki.qemu.org/Main_Page

      Delete
    2. Why not, but in the mean time, I received my rPi and was able to remote debug my "hello world" program !!

      Now, I'm trying RSE in eclipse to automatically deploy and run the software on the rPi from my computer!

      Delete
  2. This comment has been removed by the author.

    ReplyDelete
  3. Might be crazy: Is there any tutorial how to do this from Windows 7 64bit machine? It's great for Linux, but I have to use a Windows on this machine.....

    ReplyDelete
    Replies
    1. I really have no experience on Windows 7 but you can run for sure a Debian inside a virtual machine. Here you can find a tutorial about how to do it on the contrary direction (How to run windows on linux):

      http://linuxtortures.blogspot.fr/2011/01/virtualization-with-virtualbox.html

      Delete
    2. Here a brave one that did it from Windows 7: http://www.a2p.it/wordpress/tech-stuff/development/remote-debugging-raspberrypi/

      Delete
    3. Here is a tutorial how to prepare Windows cross-compiler for Raspberry Pi and how to use Eclipse to debug Raspberry Pi software from Windows:
      http://www.gurucoding.com/en/raspberry_pi_eclipse/index.php

      Delete
  4. Hi, how do I do the following?

    "2.2.4. Install the remote gdb:


    gdb-arm-linux-gnueabi"

    All I get is "gdb-arm-linux-gnueabi not found". Is this a script? If so, where is it?

    Thanks.

    ReplyDelete
    Replies
    1. Indeed it is an application. You have to execute the following command in order to install it:

      sudo apt-get install gdb-arm-linux-gnueabi

      Delete
  5. Nice tutorial but I'm afraid I'm missing something important here:
    I have installed eclipse and done the 'sudo' stuff You mention above.
    'GDB' didn't install so I downloaded it directly and I >think< I have installed it correctly.

    But when I start eclipse it doesn't find the tool chain (I think). So, when selecting 'new project' I don't get the option to create a c/c++ project.
    Can You help me there? I'm not very good in Linuxing.
    Under windows I am using an Eclips-based IDE too, but that comes completely 'ready-made'.

    Thanks again,
    Christoph

    ReplyDelete
    Replies
    1. If you have installed Eclipse by using the version included on the official repository (Debian, Ubuntu, etc) you wont have the CDT Tools installed by default (important requirement if you want to create C/C++ projects). On one of my previous posts: http://linuxtortures.blogspot.fr/2011/01/c-development-tools.html you can find how to get it.

      Ps: I strongly recommend you to directly download the Eclipse CDT from the eclipse download page.

      Hope this help!!

      Br

      Delete
    2. Hi,

      I'm spiralling towards success, somehow ;)

      I've deinstalled my eclipse version (which was the one from the package manager, as You had suspected) and reinstalled the cdt version from the eclipse website. That seemed to work.

      Now I get the problem that the included files are not found (neither with c nor c++). Where do I add the correct pathes? Which are these anyway?

      Thanx,
      Christoph

      Delete
    3. For this one I need a bit more of info. What are the files you are talking about? main.cpp? Files includes on main.cpp (iostream)?

      Delete
  6. hi there,

    i've got an issue concerning the repository 2.2.2 - the following error message appears:
    W: Failed to fetch http://www.emdebian.org/debian/dists/squeeze/InRelease Unable to find expected entry 'main/binary-armhf/Packages' in Release file (Wrong sources.list entry or malformed file)

    I checked the releases and as far as i can tell no arm support is offered. what am i missing?

    Thanks in advance!

    ReplyDelete
  7. Hello,
    Great and easy toturial!
    I'm using eclipse daily for other project on my windows machine. This might be a stupid question! but should it not be possible to use the tool chain as you describe and compile it from eclipse on my windows platform?

    ReplyDelete
    Replies
    1. I am far from being an expert on windows technology, but if I am not wrong you can install a short of linux running on windows (Cygwin). With a good dose of patience you should be able to download/compile/install the 'tool chain'. Another option could be to install a native tool chain on windows as explained here: http://download.ronetix.info/toolchains/arm/arm_cross_development_guide.pdf

      Hope this helps br!

      Delete
    2. Here a brave one that did it from Windows 7: http://www.a2p.it/wordpress/tech-stuff/development/remote-debugging-raspberrypi/

      Delete
  8. Hi Javier
    I'm getting "Unresolved inclusion" errors (in the include files) with my Eclipse, although the code is compiled correctly. Yes, the paths to the include files are correct (the compiler get them well only the eclipse indexer has problems). This seems to be a known error but I noticed that you don't had this problem. Why?
    Regards
    Helio

    ReplyDelete
    Replies
    1. I had this problem long time ago but I do not really remember how I managed to fix it. In any case it seems to be something eclipse-related. Try to have a look in here: http://stackoverflow.com/questions/9337757/unresolved-inclusion-stdio-h

      Delete
  9. Hi Javier,

    Thanks for the super tutorial

    I loaded Eclipse CDT from the eclipse downloads website (Version Juno Service Release 1) and everything went well except that when eclipse is launched it complains that "EGit could not detect where Git is installed"

    Steps 2.2.1 to 2.2.4 went ok though i used the Synaptic Package Manager to achieve the steps

    But when i come to step 3.1 i cannot find the "Cross Compile project" option under the "Executable" Project type

    Any bright ideas why this might be so

    Apologies in advance for this stupid question

    ReplyDelete
  10. It is not a stupid question. This option it is only available on Eclipse's 64bit Version. The good new is that you can select a regular "Hello world C++ project" and follow exactly the same steps.

    Br.

    ReplyDelete
  11. Javier - you are a star

    I was starting to doubt my sanity - too long living in the company of an insane parrot

    many thanks

    ReplyDelete
  12. Hi Javier,

    Everything is working (thanks for your previous help) except (there is always 1 exception!!) remote debugging

    As you can see from the shell output...

    pi@raspberrypi ~ $ ./WOD
    !!!Hello Jasper Parrot!!!

    pi@raspberrypi ~ $
    pi@raspberrypi ~ $ gdbserver :2345 WOD
    Process WOD created; pid = 1735
    Listening on port 2345
    Remote debugging from host 192.168.2.100
    readchar: Got EOF
    Remote side has terminated connection. GDBserver will reopen the connection.
    Listening on port 2345


    But within Eclipse Debug view I get...
    WOD Debug[C/C++ Remote Application]
    gdb


    So i tried launching arm-linux-gnueabi-gdb from within a shell window...
    (gdb) target remote 192.168.2.102:2345
    Remote debugging using 192.168.2.102:2345
    Malformed packet(b) (missing colon): ore:0;
    Packet: 'T050b:00000000;0d:b0f6ffbe;0f:c0070040;thread:69c;core:0;'

    So i am not sure where the problem lies.

    Could it be related to the issue you identified in your blog ...
    "...warning: At this point you can find conflicts with the already installed gdb (http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=603347). If it is the case you
    will need to upgrade from gdb 7.0.1 (the currently installed) to gdb 7.4.1 (You can find it on http://ftp.gnu.org/gnu/gdb/). You will need to download it, configure it and install it, but do not worry too much, there are just 3 steps that can be found on the README file
    inside the downloaded file"


    If so - then i have a further question - you mention 3 steps - but in the readme i only find 2 steps and i am a little concerned about proceeding in case i 'disturb' the GNU toolchain in doing so

    Thanks in advance for any help/suggestions you can offer.

    ReplyDelete
  13. Hi Javier,

    The last post got slightly mangled

    When identifying the Eclipse debug output it should have said...
    [terminated] WOD Debug[C/C++ Remote Application]
    [terminated, exit value: 0]gdb

    I have replaced the "less than" and "greater than" symbols with square braces.

    ReplyDelete
    Replies
    1. It seems your debugger server does not like what is receiving from eclipse... It should not come from the warning step, because what we are doing there is changing the non-arm gdb. Coul you please check that you are using the arm-gdb (fig 13) to communicate with the raspberry?

      Delete
  14. Hi Javier,

    yes I am definitely using the arm-linux-gnueabi-gdb; as per fig 13.

    But I am a little further on. I googled the 'error' ["Malformed packet(b) (missing colon)..."] and it appears this is common between 'mismatched' gdb components (gdb & gdbserver). Inspecting via gdbserver --version (& similar for gdb) reveals that the gdbserver included in the raspbian distribution (I am using a pre loaded SD card) is based on gdbserver 7.4.1-debian whilst that of the arm-linux-gnueabi-gdb is 7.0.1-debian (as i think you mentioned in 2.2.4)

    So what i am now trying to do is build (from the location mentioned in 2.2.4 http://ftp.gnu.org/gnu/gdb/) a gdb based on 7.4.1. I have 'nearly' succeeded except when i launched the built component from within Eclipse it complained that ...

    warning: Can not parse XML target description; XML support was disabled at compile time
    warning: Unable to find dynamic linker breakpoint function.
    GDB will be unable to debug shared library initializers
    and track explicitly loaded dynamic code.
    warning: Can not parse XML OS data; XML support was disabled at compile time

    So now it looks like i have to build the libexpat library component and then rebuild the gdb 7.4.1 component again.

    I think my 'configure' would then be...
    configure --host=i686-linux-gnu --target=arm-linux-gnueabi --with-expat

    Alternatively i could take the gdbserver on the pi back to 7.0.1 but i do not know if that is a good idea.

    Any suggestions??





    ReplyDelete
    Replies
    1. Check out this:

      http://stackoverflow.com/questions/5665800/compiling-gdb-for-remote-debugging

      It seems the guy had exactly the same problem than you. Hope this help!!

      Delete
  15. Hi Javier,

    Thank you for the impressive sharing. I am a step closer to completion of setting up. However, I am click on the debug, my program get downloaded to the target, and Eclipse stop at the dialog box of Progress Information, it says, Launching [MyProgram] Debug. The status bar progress till about 80%, and showing "Configuring GDB".

    I have run gdbserver on the target and it is listening at port 3785. After that, I start my debugging session on Eclipse.

    I have even allowed inbound and outbound port 3785 from my firewall.

    Appreciate if you can shed some light on my issue on why gdbserver is not connecting.

    Thank you.

    Cheers,
    Bryan

    ReplyDelete
  16. Hello Brayn..
    Thanks for the tutorial. I could cross compile my first program. Now a little off the topic. I am trying OpenCv on eclipse .I can run the normal program. but when i try to cross compile the same to pi, its giving me error for adding the libraries files(OpenCv). The cross compile path and the library paths are different. I am not able to figure out hoe to resolve this.
    any help is appreciated.
    Regards

    ReplyDelete
  17. Hello,
    when I try to download one of these:
    linux-libc-dev-armel-cross
    libc6-armel-cross
    libc6-dev-armel-cross
    binutils-arm-linux-gnueabi
    gcc-4.4-arm-linux-gnueabi
    g++-4.4-arm-linux-gnueabi
    uboot-mkimage

    he says that is unable to find the package, why?

    ReplyDelete
  18. I can cross compile simple C programs from Windows using eclipse to Raspberry Pi(running on Debian Linux). i can also compile and run opencv programs only on windows(Intel). using Eclipse. but i'm not able to cross compile opencv programs on raspberry pi using windows and eclipse. Please help me find a solution.

    ReplyDelete