Building Raspberry Pi programs on a traditional PC
Large Programs
You can compile larger programs that you would typically install with the command triplet ./configure; make; make install
on an external system by adding the option --host=arm-linux-gnueabihf
or arm-bcm2708-linux-gnueabi
or arm-bcm2708hardfp-linux-gnueabi
to ./configure
. The translation process will then look for the suitable cross-compiler and tools, as long as they are in the path. You can then execute the time-intensive Make on the better-performing computer. The complete result for a successful build is copied onto a Rasp Pi, and the program is then finally installed via make install
.
Larger applications usually need various dependencies in the form of libraries or other programs. For the compilation, these dependencies also need to be present on the host system. You can either cross-compile the necessary dependencies or install the packages on the Raspberry Pi, including the development versions, which are designated by the prefix dev-
, and then copy the installation to the host computer.
Alternatively, you can take the memory card out of the Raspberry Pi and mount the complete Rasp Pi system on the PC. Then, you can communicate with the build process in ./configure
via a series of options about where to find the various compiler and header files. These options are typically called --with-
<package name>
=[...].
Larger software packages frequently offer a shell script called <Package name>-config
(e.g. wx-config
for wxWidgets, sdl-config
for SDL, …) to simplify this process. This can also typically be activated with ./configure
options, such as --with-wx-config
when compiling wxMaxima. The command wx-config --libs --cflags
provides the necessary compiler--flags, where the libraries and header files are located. When cross-compiling, you do not use the 'native' wx-config tool (/usr/bin/wx-config
, which would point to the native libraries), but the one in the crosscompiling environment, which points to the libraries for the Arm architecture.
With programs that only use a simple makefile for a build, it is possible to modify the compiler and other tools. Frequently, there are definitions for variables, such as CC
(C Compiler) and CXX
(C++ Compiler), that you will only need to adapt for the corresponding Raspberry cross-compiler. With build systems based on CMake, toolchain files indicate which compiler the build process should use and which target system the build is intended for. A simple example is presented in Listing 8. The invocation is made from the build directory according to Listing 9. You should reference the file Toolchain-raspi.cmake
, which has been adapted for the Raspberry Pi as a toolchain file.
Listing 8
Building with CMake
set(CMAKE_SYSTEM_NAME Linux) set(CMAKE_SYSTEM_VERSION 1) set(CMAKE_SYSTEM_PROCESSOR arm) set(CMAKE_C_COMPILER arm-linux-gnueabihf-gcc) set(CMAKE_CXX_COMPILER arm-linux-gnueabihf-g++) # where is the target environment set(CMAKE_FIND_ROOT_PATH "/opt/tools/arm-bcm2708/ gcc-linaro-arm-linux-gnueabihf-raspbian/") # search for programs in the build host directories SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) # search for libraries and headers in the target directories SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) SET(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
Listing 9
Invoking CMake
$ cmake -DCMAKE_TOOLCHAIN_FILE=<path>/ <to>/<toolchain>/<file>/ Toolchain-raspi.cmake <path>/<to>/the/<sourcecode>x
Google Go
The Go programming language, which was originally developed by Google [4], contains built-in functionality for cross-compiling. Go describes the functionality in the installation instructions by stating, "In effect, you are always cross-compiling." In general, the build system is consistent with the target system. This functionality is advantageous for Rasp Pi developers. Most of the Linux distributions have Go in their package sources. However, you will need to manually install Go for cross-compiling (Listing 10).
Listing 10
Installing Go for Cross-Compiling
cd $HOME # for bootstrapping Go 1.5 we need Go 1.4 so install that first: wget https://storage.googleapis.com/golang/ go1.4.3.linux-386.tar.gz # install Go 1.4 into $HOME/go1.4/ # (it is searched there when building Go 1.5) tar xzf go1.4.3.linux-386.tar.gz --transform 's/go/go1.4/' wget https://storage.googleapis.com/golang/go1.5.1.src.tar.gz # extract Go 1.5.1 into $HOME/go/ tar xzf go1.5.1.src.tar.gz cd go/src/ # build Go 1.5.1 with native and Arm CPU support GOOS=linux GOARCH=arm ./make.bash cd $HOME
After you complete the installation, the Go compiler will be in the ~/go
directory. You should set the environment variable $GOROOT
and expand the path with the directory so that it works properly. In this way, the self-compiled Go compiler takes precedence over any other version of the Go compiler on the system that might be lacking cross-compiling capabilities (Listing 11). If Go finds the environment variables GOOS=linux
and GOARCH=arm
, the compiler will spit out a Rasp Pi-compatible binary image. Listing 12 demonstrates the process using the example of the simple "Hello World" demo helloworld.go
(Listing 13) [9].
Listing 11
Setting GOROOT
$ export GOROOT=$HOME/go $ export PATH=$GOROOT/bin:$PATH
Listing 12
Getting the Binary Image
$ go run helloworld.go # run program without compilation hello world $ go build helloworld.go # compile program native $ file helloworld # Result: a binary for x86-64 helloworld: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, not stripped $ GOOS=linux GOARCH=arm go build helloworld.go # crosscompile for the RasPi $ file helloworld # Result: a binary for the RasPi helloworld: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), statically linked, not stripped
Listing 13
Hello in Go
package main import "fmt" func main() { fmt.Println("hello world") }
« Previous 1 2 3 Next »
Buy this article as PDF
Pages: 6
(incl. VAT)