Porting a C/C++ Application to Raspberry Pi

This article is part of a series with the name IoT Remote Power Switch – Project Part 9.

It describes the port of the web client application from Ubuntu 14 LTS to Raspbian, the operating system running on Raspberry Pi embedded computers. I’ve ordered and received a device in the mean time.

Reading the paragraphs below you will note that I haven’t added the controlling of the GPIO port of the Raspberry Pi to the source code. I postponed this step intentionally. It’s challenging enough for me to do one step at a time. Once cross compilation works and the application runs on both platforms, I will add the missing code.

Involved Components

The task is basically trivial: compile the C code on my Ubuntu PC for a different type of computer. The Raspberry Pi is equipped with an ARM CPU, compared to my PC that has an Intel i7 CPU. Fact is, the instruction sets of these two CPUs are absolutely incompatible. In addition, the Raspberry Pi runs the Raspbian OS, while my PC runs Ubuntu. Although these two operating systems are quite similar – both base on the Linux kernel – they have been compiled for different processor types and therefore have different, incompatible libraries.

So, what is the same, what is different on the Raspbian system compared to the development host? Obviously, my source code should stay the same. In addition, I want to keep the IDE the same if possible. It is possible. When I selected Eclipse CDT (C/C++ Development Tools) for the development of the web client application on Ubuntu, I knew that if offers the possibility for cross compilation, a term for describing the compilation of source code on one platform (for example x64) for another platform (for example ARMv6). Platform in this context means not only the CPU family and its instruction set, but also the operating system and its libraries.

When I installed Eclipse CDT on my Ubuntu 14 system for C/C++ development, it didn’t include the compiler. I had to download and install the GNU compiler collection (known as GCC) separately. On Ubuntu this can be done by installing the build-essential meta package ($> sudo apt-get install build-essential). This is a bunch of related and required packages around the GNU compiler collection (which also includes the linker by the way) that allows building executables for the system it has been installed on.
Note: GCC’s wiki page doesn’t mention the build-essential meta package; that’s an Ubuntu special. You may alternatively follow the instructions of the GCC crew.

The GNU Compiler Collection supports a lot of processor types and languages. However, it’s not trivial to download and configure it for a specific CPU type. The libraries for the target CPU have to be built locally, since the downloaded tools can’t possibly contain all imaginable libraries for all supported processors. For this purpose, the Raspberry Pi team has put together a tools folder that contains both, the tailored cross compiler suite AND the pre-compiled libraries in one place.

Summarized, these are the required components:
Identical Components

  • Application specific source code
  • IDE

Different Components

  • Target specific compiler and linker
  • Target specific header files and system libraries

Installation of Missing Components

The different components are still missing on my development host. They can be downloaded from Raspberry Pi’s GitHub account. They are located in the tools repository. That repo contains the target specific compiler and linker, as well as the header files and pre-compiled system libraries.

Configuration of Eclipse and Application Build

I found useful instructions how to configure Eclipse for cross compilation on this wiki page on GitHub. At a closer look I registered that the last submit was roughly two years ago. That’s usually not a good sign. Nevertheless, follow steps 1 to 4. The remaining steps are described in this document. They are more up to date. It’s possible to build the application without the xenorasp library from awesomebytes (although they did a very good job at that time; I tried out their library and instructions too, the build worked).

So here is what I do to get a working build inside Eclipse. It works for the Kepler and Mars release (that’s currently the latest), and should also work for other releases. It’s a Hello World! program that I can use later for build verification on the Raspberry Pi board.

  1. Via a right-click inside the Project Explorer create a new C project.
  2. Give the project the name Learn1RPi
  3. Select Hello World ANSI C Project
  4. Select Cross GCC as Toolchain
  5. Click Next until the dialog Configure the Cross GCC path and prefix appears; enter arm-linux-gnueabihf- for the Cross compiler prefix and <path/to>/tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian-x64/bin for Cross compiler path
  6. Then click Finish

If necessary change the file Learn1RPi.c such that it uses C libraries. Use this as an example:

#include <stdio.h>
#include <stdlib.h>

int main(void) {
	puts("Hello world!"); /* prints 'Hello world!' on the console */
	return EXIT_SUCCESS;
}

This makes sure that the program is built against two C libraries. If that works, it shows that the include and library files can be found.
Now, build the application. It should work. If not, check the Console output carefully and correct the project configuration as necessary.

Finally, I’d like to build the Remote Power Switch web client application, the one I described in the previous post. It does build for an Ubuntu 14 host and runs, I’ve tested that. Now, I’ve to change the build configuration such that it builds for a Raspbian target. I select this project in the Project Explorer and edit its properties as follows:

  1. Open the project properties dialog
  2. Under C/C++ Build click on Tool Chain Editor
  3. Click on Manage Configurations and click New
  4. In the Create New Configuration dialog, give the new configuration the name DebugRaspbian and the description Cross compilation for a Raspberry Pi/Raspbian target.
  5. Select Copy settings from: Existing configuration: Debug and click OK
  6. Set the new configuration as active configuration and click OK
  7. Back in the Tool Chain Editor dialog, select the DebugRaspbian configuration and start changing it for cross compilation:
  8. Select Cross GCC as Current toolchain and click Apply
  9. Select C/C++ Build –> Settings –> Cross Settings and select the same Prefix and Path as for the Hello world! program above
  10. Click OK to close the dialog

Uups! The application won’t build yet because of the missing cURL library. The one installed on my development host is for an Ubuntu/x64 target, the library for a Raspbian/ARMv6 target is still missing. Since it seems to me that this is enough for this post, I’ll show how to install a cURL version for a Raspbian target in the next post, along with the next steps.

Summary and Outlook

As usual, you find the source code here; it’s pre-release v0.7. Note that the node_modules folder isn’t part of the repository. After downloading the repo or its zip file you’ll have to change directory to the top-level folder of the project and run $> npm install.

So, I cross-compiled the dummy application on Ubuntu for Raspbian. But will it run and work as expected?
The Remote Power Switch application doesn’t build yet. I’ll have to add the cURL library on the development host first.
The next post will describe my experiences with the Raspberry Pi board and what I had to do in order to get the Remote Power Switch application running on it.