Building Pi Apps on a PC » Raspberry Pi Geek
The Raspberry Pi is an excellent computer for hobbyists, but the Pi is not well suited for some CPU-intensive tasks. Compiling software, for example, can take hours even on a high-performing system. If you write your own software for the Raspberry Pi, you may be wondering if it is possible to develop and prepare code on a faster desktop computer and still use it later on the Pi.
The answer is, yes, you can, but the complexity of the task depends greatly on the programming language you are using. This article describes some of the steps you’ll need to take for cross-coding with different languages.
As you will learn, the most popular and best-performing languages, such as C and C++, take the most effort because they require a compiler. The problem with compiling a Pi program on an ordinary desktop computer is that most desktop systems (including most Linux home computers, Windows systems, and recent-era Macs) have a CPU based on the Intel x86 chip family, and the Raspberry Pi CPU runs on an ARM chip. You’ll need to become familiar with cross-compilers if you want to compile code on one hardware architecture then get it to run on a different architecture.
Of course, the tools are different depending on which host system you want to use for writing and preparing the software. This article focuses primarily on Linux tools. Because Linux is the system running on most Raspberry Pi systems, it is a good choice for the host system also. One benefit of using Linux is that most of the development tools are available for free. This article also provides some tips for compiling your Rasp Pi code on a Windows system.
Mục lục bài viết
Script Languages and Bytecode
Scripting languages that are interpreted at runtime, such as Perl, Python, Ruby, PHP, and shell, can be copied and run on the Rasp Pi without complications. Applications programmed in Java also present few problems, because Java programs use machine-independent bytecode that can be executed on any architecture. The only requirement for Java programs is that you have the correct Java runtime environment.
Applications written in Microsoft’s .NET environment will run on Linux using the Mono framework, which is available for most Rasp Pi systems. Applications written in Mono/.Net are similarly flexible, even though they might present some complications. It is easy to write a simple “Hello World” program in Mono (Listing 1) and then translate it into an executable file (Listing 2). The program will have the misleading text (detected by the ‘file’ command) PE32 executable (console) Intel 80386, […], but the reference to Intel 80386 is no cause for worry.
Listing 1
Mono Hello
class HelloWorldProgram { public static void Main() { System.Console.WriteLine("Hello, world!"); } }
Listing 2
Creating an Executable
$ mcs helloworld.cs # compile the C#-program $ file helloworld.exe # what is the result? helloworld.exe: PE32 executable (console) Intel 80386, for MS Windows Mono/.Net assembly, $ mono helloworld.exe # execute program on the Raspberry Pi Hello, world!
The result of a compiled Mono program is not x86-specific but is rather in the format of the Common Language Infrastructure (CLI). CLI code is similar to the CPU-independent bytecode in Java. The EXE file that emerges from the compile process can be copied onto a Rasp Pi without any problem and then executed via mono helloworld.exe
. If you now disassemble the file via monodis helloworld.exe
, the results on a PC will not be any different from the result on a Raspberry Pi but for a few comments.
The short “Hello World” program in Listing 1 took 10 seconds to compile on the Rasp Pi and .01 seconds on an Intel Core i5-2430M with 2.40GHz. This difference in compiling times becomes more pronounced when compiling a Java program. The PC can accomplish this task in about 0.7 seconds. The Rasp Pi needs more than 11 seconds.
Cross-Compilers
Although Java and .NET/Mono are admittedly easier environments for writing portable code, developers writing open source programs continue to prefer compiled programming languages such as C or C++, which offer better performance and, according to many programmers, more versatility and freedom. Fortran is another compiled language used in Mathematics and Science. Numerous CPU architectures support the free GNU Compiler Collection (GCC), which will allow you to compile these languages. You can find cross-compiling tools for the Raspberry Pi with most recent GCC versions; however you will not find these cross-compiling components in the regular package management.
To set up your Linux computer to act as a development system, you will need to copy Git onto the system, usually from the package of the same name. You should also check out the Raspberry tools [1] from GitHub (Listing 3).
Listing 3
Loading the Developer Code
$ git clone https://github.com/raspberrypi/tools.git
The command in Listing 3 will load the current developer code directly from the administrative system of the version rather than retrieving an archive from a website or FTP server. The result lands in a new subfolder named tools/
. Therefore, you should call the Git command in your home directory. Alternatively, you can call the command from the folder for the programs installed over the package administration with the root rights in /opt/
.
The directories shown in Listing 4 contain the so-called toolchain, which consists of the compiler and the remainder of the tools, such as the linker, assembler, and help programs. The native cross-compiler for the floating point operations without numeric co-processor, or “soft float,” is found in the first folder. The second folder holds the compiler for floating point co-processors or “hard float” [2]. The third directory contains the Linaro cross-compiler for 32-bit computers (see the box titled “Linaro”), and the fourth directory has cross-compilers for 64-bit computers.
Linaro
Linaro is an organization made up of several well-known companies, including LG, Broadcom, Qualcomm, Allwinner, MediaTek, and ZTE. One mission of this organization is to work on optimizing widely used open source software like the Linux kernel or the GNU Compiler Collection, for the ARM architectures [3].
Ideally, you should add the directory containing the desired compilers to the path. If necessary, you can add all of the compilers. Depending on the Linux distribution or the shell, you will need to edit ~/.profile
and ~/.bashrc
and extend the PATH
variable via corresponding export
directives. The example from Listing 5 is limited to the hard float compiler saved under /opt/
and the cross-compiler for the 64-bit systems.
Listing 4
Toolchain
tools/arm-bcm2708/arm-bcm2708-linux-gnueabi/bin/ tools/arm-bcm2708/arm-bcm2708hardfp-linux-gnueabi/bin/ tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian/bin/
Listing 5
Example Path
[...] export PATH=$PATH:/opt/tools/arm-bcm2708/ arm-bcm2708hardfp-linux-gnueabi/bin/ export PATH=$PATH:/opt/tools/arm-bcm2708/ gcc-linaro-arm-linux-gnueabihf-raspbian-x64/bin/ [...]
The compiler and the remaining tools can be distinguished from one another by their prefix and the toolchain referenced in the name: arm-linux-gnueabihf-
for the Linaro-Toolchain, arm-bcm2708-linux-gnueabi-
for the Soft-Float-Toolchain, and arm-bcm2708hardfp-linux-gnueabi-
for the Hard-Float-Toolchain. Windows cross-compilers use a naming convention such as i686-w64-mingw32-
, with the first set of characters identifying the CPU; the second set specifying the operating system, which might include more exact specifications, such as hardfp
, softfp
, mingw32
, or cygwin
. The final set of characters indicates the name of the command. This can be a compiler name like gcc
, g++
, gfortran
, or a tool like strip
or objdump
.
If the path variable of the shell contains the cross-compiler, you should look to Listing 6 for translating a short C program, such as the standard helloworld.c
, onto your PC (Listing 7). Afterwards, copy the result onto the Raspberry Pi and execute it. Even when dealing with such a small program, a laptop proves faster than the Rasp Pi by a factor of 10.
Listing 6
Cross-Compiling Hello World
$ arm-linux-gnueabihf-gcc -o helloworld helloworld.c
Listing 7
Hello in C
#include<stdio.h> int main() { printf("Hello World\n"); return 0; }