Project

General

Profile

Cross-compiling NDN projects for Raspberry Pi » History » Version 48

Junxiao Shi, 01/31/2021 08:11 PM

1 47 Junxiao Shi
# NDN Packages for Raspberry Pi
2
3 48 Junxiao Shi
## Important Notice
4
5
Binary packages are now published for Raspberry Pi and similar devices:
6
7
* [named-data PPA](https://launchpad.net/~named-data/+archive/ubuntu/ppa) for [Ubuntu](https://wiki.ubuntu.com/ARM/RaspberryPi)
8
* [NFD nightly packages](https://nfd-nightly.ndn.today) for Raspberry Pi OS
9
10 47 Junxiao Shi
Original content of this page is retained for historical purpose.
11
12
---
13
14
15 1 Wentao Shang
Cross-compiling NDN projects for Raspberry Pi
16
=============================================
17
18 2 Wentao Shang
Note: before reading this document, you should already be familiar with the basic concepts of compiling and linking (especially the linking part). If not, you may be interested in reading this great book: [Linkers and Loaders](http://www.amazon.com/Linkers-Kaufmann-Software-Engineering-Programming/dp/1558604960/ref=sr_1_1?ie=UTF8&qid=1394130356&sr=8-1&keywords=linker+and+loader)
19 3 Wentao Shang
20 10 Wentao Shang
Basic idea
21 7 Wentao Shang
----------
22 1 Wentao Shang
23 7 Wentao Shang
Remember to compile a C/C++ project, we need the source code for the project, the header files for the included libraries, the binary objects of the libraries, and the compiler tools (gcc, as, ld, etc.). The combination of the last three things together is referred to as a _building environment_. Cross-compiling is no different. To cross compile a project, we first need to setup the building environment and then build the source code in that environment.
24
25
Difference between "native compiling" and "cross compiling"
26 9 Wentao Shang
--------
27 7 Wentao Shang
28 14 Wentao Shang
The biggest difference is that for native compiling, you build the binaries that will run on the same platform where you build them. For cross compiling, however, you build the binaries on one platform (called _build_ platform) and run them on another platform (called _host_ or _target_ platform). The platforms may differ in the operating systems (Windows vs. Linux) and/or the CPU architectures (x86_64 vs. arm32).
29 8 Wentao Shang
30 10 Wentao Shang
Raspberry Pi platform information
31 1 Wentao Shang
--------
32 10 Wentao Shang
33
Raspberry Pi runs on *ARMv6* CPU, which is a 32bit chip with hardware float-point support (abbreviated as *armhf*). There are many operating systems available. The one we are going to use is called *Raspbian*, which is a port of the Debian "wheezy" Linux distribution.
34
35 15 Wentao Shang
Creating compiling toolchain for Raspberry Pi
36 10 Wentao Shang
--------
37 1 Wentao Shang
38 46 Wentao Shang
To prepare a building environment, we need to get the gcc/g++ compiler toolchain that will generate binaries for the armhf platform. Raspbian already provided a set of compiling tools on their official [github](https://github.com/raspberrypi/tools), which works for both 32bit and 64bit Linux. If you decide to use the official toolchain, you may skip the rest of this section.
39 15 Wentao Shang
40
The tool we are going to use to build our gcc is [ct-ng](http://crosstool-ng.org/). It is designed to run on Linux but can be adjusted via some hacks to run on MacOSX. It is pretty easy to use and you may find this [article](http://www.kitware.com/blog/home/post/426) very helpful when building your own toolchain.
41
42
Tip: you may use the configuration file from Raspbian [github](https://github.com/raspberrypi/tools/blob/master/configs/bcm2708hardfp-ct-ng.config), which will load the "official" configurations for the platform.
43 16 Wentao Shang
44 40 Wentao Shang
We have a toolchain package available for download. It is compiled on Ubuntu 12.04 64bit platform and should also work for later versions of Ubuntu 64bit. The download link is http://irl.cs.ucla.edu/~wentao/pi/pi-tools.tar.gz
45
46 16 Wentao Shang
Getting libraries ready
47
--------
48 17 Wentao Shang
49 18 Wentao Shang
After we have the toolchain, the next step is to gather the libraries, including the header files (_.h_ files) and the binaries (_.a, .so_ files). The libraries used by the NDN projects include *openssl, Boost, sqlite3, crypto++*. Those libraries may recursively depend on other libraries and it will be a big headache to compile all of them from source code and resolve the dependencies manually. Fortunately, Raspbian has a public package repo containing the binaries for most packages available on Debian. So the easy walk-around is to _install_ those libraries directly on Raspberry Pi using _apt-get_ and then copy the relevant files down to our build machine.
50 19 Wentao Shang
51 21 Wentao Shang
On Raspbian, all the header files are in the */usr/include* folder, while the binary objects for the libraries are scattered in many places, such as */usr/lib, /lib*, etc. A simple way to find the path of a library is to run the following command:
52 19 Wentao Shang
53
    ldconfig -p | grep _library_name_
54
55 20 Wentao Shang
*ldconfig -p* will show all the dynamic linking libraries currently available on the system and their locations in the file system.
56 22 Wentao Shang
57
You may copy all the binaries into the same folder. For example, on the build machine you may have the folder _~/pi/_ and inside that folder there are two sub-folders _./include_ and _./lib_. You can copy all the header files into the include folder and the binaries into the lib folder.
58
59 33 Wentao Shang
Here is the list of library files that you need to get in order to compile the NDN projects. You MAY need other library files for your own project.
60
61
    .
62
    ├── include
63 34 Wentao Shang
    │   ├── boost/
64
    │   ├── cryptopp/
65 33 Wentao Shang
    │   ├── expat_config.h
66
    │   ├── expat_external.h
67
    │   ├── expat.h
68 34 Wentao Shang
    │   ├── openssl/
69
    │   ├── pcap/
70 33 Wentao Shang
    │   ├── pcap-bpf.h
71
    │   ├── pcap.h
72
    │   ├── pcap-namedb.h
73
    │   ├── sqlite3ext.h
74
    │   └── sqlite3.h
75
    └── lib
76
        ├── ld-linux-armhf.so.3
77
        ├── libboost_chrono.so
78
        ├── libboost_date_time.so
79
        ├── libboost_filesystem.so
80
        ├── libboost_iostreams.so
81
        ├── libboost_program_options.so
82 42 Wentao Shang
        ├── libboost_random.so
83 33 Wentao Shang
        ├── libboost_regex.so
84
        ├── libboost_system.so
85
        ├── libbz2.so.1.0
86
        ├── libcryptopp.so -> libcrypto++.so
87
        ├── libcrypto.so
88
        ├── libcrypto++.so
89
        ├── libexpat.so
90
        ├── libicudata.so.48
91
        ├── libicui18n.so.48
92
        ├── libicuuc.so.48
93
        ├── libpcap.so
94
        ├── libsqlite3.so
95
        ├── libssl.so
96
        ├── libz.so.1
97 1 Wentao Shang
        └── pkgconfig
98 41 Wentao Shang
99
We have packaged the minimum library files into a package and made it available for download. Note that the Boost library contained in this package is not complete: it only includes the minimum required libs for ndn-cxx and NFD project. The download link is http://irl.cs.ucla.edu/~wentao/pi/pi-env.tar.gz
100 33 Wentao Shang
101 43 Wentao Shang
Note: later versions of ndn-cxx also added dependency on libboost\_random, which is not included in the pi-env package. The .so file can be downloaded at http://irl.cs.ucla.edu/~wentao/pi/libboost_random.so
102
103 22 Wentao Shang
Building the source code
104
--------
105 23 Wentao Shang
106 24 Wentao Shang
The final step is to compile the projects using the environment we created. The basic idea is to call the cross toolchain and link against the cross-compiled libraries. To do that, we need to export a set of shell variables that are used by the *make* command. For example, we can export the following variables in the shell:
107
108
    export AS=/path/to/your/toolchain/as
109
    export LD=/path/to/your/toolchain/ld
110
    export CC=/path/to/your/toolchain/cc
111
    export CXX=/path/to/your/toolchain/c++
112
113 28 Wentao Shang
This will tell *make* to use the toolchain we specify instead of the default toolchain.
114 25 Wentao Shang
115 29 Wentao Shang
In order to point the toolchain to the correct location to search libraries, we also need to export *CFLAGS/CPPFLAGS* and *LDFLAGS* variables, which will be provided to *gcc* as options:
116 1 Wentao Shang
117 26 Wentao Shang
    export CFLAGS="-I/path/to/your/include/folder -L/path/to/your/lib/folder -Wl,-rpath=/path/to/your/lib/folder"
118
    export LDFLAGS="-L/path/to/your/lib/folder -Wl,-rpath=/path/to/your/lib/folder"
119
120 28 Wentao Shang
Note that we repeat the *LDFLAGS* in the *CFLAGS*. This is because some Makefile script may combine the compiling and linking steps together and use only *CFLAGS*. (This actually happens when building the NDNx project.)
121 26 Wentao Shang
122 28 Wentao Shang
Another important option is the _rpath_ option. This specifies where the linker will search for recursive dependencies.
123 35 Wentao Shang
124 38 Wentao Shang
Here is a sample script for configuring & compiling NFD. It can be ported to compile other *waf* based projects as well.
125 35 Wentao Shang
126
    #!/bin/bash
127
128
    export PATH=/home/wentao/tools/arm-bcm2708/arm-bcm2708hardfp-linux-gnueabi/bin:$PATH
129
130
    arch="arm-bcm2708hardfp-linux-gnueabi"
131
132
    export AR="${arch}-ar"
133
    export AS="${arch}-as"
134
    export LD="${arch}-ld"
135
    export CC="${arch}-cc"
136
    export CXX="${arch}-c++"
137
    export RANLIB="${arch}-ranlib"
138
139
    export CFLAGS="-O2 -std=gnu99 -I/home/wentao/pi/include -L/home/wentao/pi/lib"
140 44 Wentao Shang
    export CXXFLAGS="-O2 -g -std=c++11 -I/home/wentao/pi/include -L/home/wentao/pi/lib"
141 35 Wentao Shang
    export LDFLAGS="-Wl,-rpath=/home/wentao/pi/lib -L/home/wentao/pi/lib"
142
    export PKG_CONFIG_PATH=~/pi/lib/pkgconfig
143
144
    ./waf configure --prefix=/home/wentao/pi --boost-includes=/home/wentao/pi/include --boost-libs=/home/wentao/pi/lib
145
146 45 Wentao Shang
    if [ $? = 0 ]
147
    then
148
        ./waf clean
149
        ./waf
150
    fi
151 1 Wentao Shang
152 38 Wentao Shang
After running this script, you may run *./waf install* to copy all the generated binaries into the folder you specified in *--prefix* option at *./waf configure* step. In our case, it will be */home/wentao/pi*. This is helpful if you are cross-compiling your own libraries (e.g., ndn-cxx) that you want to use to further compile other projects.
153 35 Wentao Shang
154 39 Wentao Shang
Another sample script for configuring and compiling ndn-cxx:
155
156
    #!/bin/bash
157
158
    export PATH=/home/wentao/tools/arm-bcm2708/arm-bcm2708hardfp-linux-gnueabi/bin:$PATH
159
160
    arch="arm-bcm2708hardfp-linux-gnueabi"
161
162
    export AR="${arch}-ar"
163
    export AS="${arch}-as"
164
    export LD="${arch}-ld"
165
    export CC="${arch}-cc"
166
    export CXX="${arch}-c++"
167
    export RANLIB="${arch}-ranlib"
168
169
    export CFLAGS="-O2 -std=gnu99 -I/home/wentao/pi/include -L/home/wentao/pi/lib"
170 44 Wentao Shang
    export CXXFLAGS="-O2 -g -std=c++11"
171 39 Wentao Shang
    export LDFLAGS="-Wl,-rpath=/home/wentao/pi/lib"
172
    export PKG_CONFIG_PATH=~/pi/lib/pkgconfig
173
174 1 Wentao Shang
    ./waf configure --prefix=/home/wentao/pi --boost-includes=/home/wentao/pi/include --boost-libs=/home/wentao/pi/lib --with-openssl=/home/wentao/pi --with-cryptopp=/home/wentao/pi
175
176 45 Wentao Shang
    if [ $? = 0 ]
177
    then
178
        ./waf clean
179
        ./waf
180
    fi
181
182
Note: starting from Oct. 30, 2014, ndn-cxx and NFD have switched to adopt C++11 standard. As a result, you need to feed "-std=c++11" flag to gcc during cross-compiling.
183 39 Wentao Shang
184 38 Wentao Shang
Here is the sample script for configuring & compiling NDNx. It can be ported to compile other *automake* based projects as well.
185
186 35 Wentao Shang
    #!/bin/bash
187
188
    export PATH=/home/wentao/tools/arm-bcm2708/arm-bcm2708hardfp-linux-gnueabi/bin:$PATH
189
190
    arch="arm-bcm2708hardfp-linux-gnueabi"
191
192
    export AR="${arch}-ar"
193
    export AS="${arch}-as"
194
    export LD="${arch}-ld"
195
    export CC="${arch}-cc"
196
    export CXX="${arch}-c++"
197
    export RANLIB="${arch}-ranlib"
198
199
    export CFLAGS="-O2 -std=gnu99 -I/home/wentao/pi/include -L/home/wentao/pi/lib -Wl,-rpath=/home/wentao/pi/lib"
200 1 Wentao Shang
    export LDFLAGS="-L/home/wentao/pi/lib -Wl,-rpath=/home/wentao/pi/lib"
201
202 35 Wentao Shang
    ./configure --build="x86_64-linux-gnu" --host="${arch}" --prefix="/home/wentao/pi"
203 38 Wentao Shang
204
    make