2020-07-16 22:22:46 +02:00
|
|
|
// Copyright (C) 2020 Internet Systems Consortium, Inc. ("ISC")
|
|
|
|
//
|
|
|
|
// This Source Code Form is subject to the terms of the Mozilla Public
|
|
|
|
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
|
|
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
|
|
@page crossCompile Kea Cross-Compiling Example
|
|
|
|
|
|
|
|
The idea is to install Kea on a Raspberry Pi 4 Model B running Raspbian
|
|
|
|
operation system (e.g. the
|
2021-03-19 20:57:49 +02:00
|
|
|
<a href="https://www.raspberrypi.org/software/operating-systems/">
|
2020-07-16 22:22:46 +02:00
|
|
|
Raspbian Buster with desktop and recommended software</a> distribution)
|
|
|
|
without having to compile Kea on the Raspberry Pi box itself as it
|
|
|
|
takes some hours so using a standard Linux box with a x86_64 processor.
|
|
|
|
|
|
|
|
To cross-compile anything for Raspbian you need:
|
|
|
|
- a cross-compiler running on x86_64 producing arm binaries
|
|
|
|
- either an image of system copied from a Raspberry disk or extracted
|
|
|
|
from a Raspbian repository.
|
|
|
|
|
|
|
|
@section toolChain Cross-Compile Tool Chain
|
|
|
|
|
|
|
|
A priori it is possible to compile your own tool chain or to use
|
|
|
|
a package as the arm-linux-gnueabihf one on Ubuntu. But there is
|
|
|
|
reported compatibility issue with old Raspberry Pi versions) so
|
|
|
|
we recommend a pre-built dedicated tool chain for this purpose:
|
2020-07-23 21:15:06 +02:00
|
|
|
<a href="https://github.com/Pro/raspi-toolchain">RaspberryPi toolchain on github</a>.
|
2020-07-16 22:22:46 +02:00
|
|
|
|
|
|
|
The documentation of this tool chain gives a rsync command which
|
|
|
|
copies selected parts of the Raspberry Pi root filesystem ("rootfs").
|
|
|
|
If you have no access to a running Raspberry Pi it is still possible
|
2020-07-23 18:51:34 +00:00
|
|
|
to get them following next section instructions. If you have, simply
|
2020-07-16 22:22:46 +02:00
|
|
|
skip this part.
|
|
|
|
|
|
|
|
@section noRaspberry How to get system and packages without a running Raspberry Pi
|
|
|
|
|
|
|
|
It is not required to have access to a running Raspberry Pi.
|
|
|
|
The system disk image is available at the Raspbian URL.
|
|
|
|
Packages are in the Raspian repository which is given in
|
|
|
|
sources list files in this disk image or below.
|
|
|
|
|
2020-07-23 21:15:06 +02:00
|
|
|
The /etc/apt/sources.list file content is:
|
2020-07-16 22:22:46 +02:00
|
|
|
@verbatim
|
|
|
|
deb http://raspbian.raspberrypi.org/raspbian/ buster main contrib non-free rpi
|
|
|
|
# Uncomment line below then 'apt-get update' to enable 'apt-get source'
|
|
|
|
# deb-src http://raspbian.raspberrypi.org/raspbian/ buster main contrib non-free rpi
|
|
|
|
@endverbatim
|
|
|
|
|
2020-07-23 21:41:03 +02:00
|
|
|
and the /etc/apt/sources.list.d/raspi.list file content is:
|
2020-07-16 22:22:46 +02:00
|
|
|
@verbatim
|
|
|
|
deb http://archive.raspberrypi.org/debian/ buster main
|
|
|
|
# Uncomment line below then 'apt-get update' to enable 'apt-get source'
|
|
|
|
# deb-src http://archive.raspberrypi.org/debian/ buster main
|
|
|
|
@endverbatim
|
|
|
|
|
|
|
|
The disk image is a zipped image of a 4GB disk with a standard MSDOS
|
|
|
|
boot block with two volumes:
|
|
|
|
- boot (useless for this purpose)
|
|
|
|
- rootfs (the Raspberry Pi root filesystem)
|
|
|
|
|
|
|
|
The idea is to mount the rootfs on the Linux box (it can work on another
|
|
|
|
system as soon as it supports the ext4 file system type):
|
|
|
|
- first use fdisk or similar tool to get the offset of the first block
|
|
|
|
of the rootfs (second) volume
|
|
|
|
- if the offset is in block unit multiply by 512 (block size)
|
|
|
|
- mount as root (sudo mount ...) with the loop option, the offset option,
|
|
|
|
the unzipped image file name and a mount point (absolute path of
|
|
|
|
a directory)
|
|
|
|
If you have a SD card with Raspbian installed on it and a SD reader
|
|
|
|
you can directly mount the rootfs from it.
|
|
|
|
|
|
|
|
If a dependency (i.e. the Raspbian version of a library) is not in the
|
|
|
|
rootfs image you need to simulate its installation:
|
|
|
|
- get the .deb file from a Raspbian repository
|
2020-07-23 21:15:06 +02:00
|
|
|
- extract files using the dpkg-deb -R tool on the .deb file
|
2020-07-16 22:22:46 +02:00
|
|
|
- install the files (usually in the "rootfs"/usr directory)
|
2020-07-23 18:53:54 +00:00
|
|
|
The idea is the files (includes and libraries) can be found by
|
2020-07-16 22:22:46 +02:00
|
|
|
the cross-compiling tool chain.
|
|
|
|
|
|
|
|
It is possible to emulate a Raspberry Pi using qemu even I do not think
|
|
|
|
it can run Kea. But at least it can run some tests as the hello world sample
|
2020-07-23 21:15:06 +02:00
|
|
|
of the tool chain. Required qemu kernels can be found in
|
|
|
|
<a href="https://github.com/dhruvvyas90/qemu-rpi-kernel">this github repo</a> with
|
2020-07-23 18:55:19 +00:00
|
|
|
a documentation, which is well worth reading.
|
2020-07-16 22:22:46 +02:00
|
|
|
|
|
|
|
@section crossCompilePitfalls Usual problems
|
|
|
|
|
|
|
|
There are two usual problems when cross-compiling:
|
|
|
|
- have a binary for the wrong processor, e.g. either trying to run
|
|
|
|
an arm binary on the x86_64 box or building a x86_64 binary when
|
|
|
|
it will be run by the Raspberry Pi
|
|
|
|
- use the x86_64 system include or library instead of the Raspberry Pi
|
|
|
|
one from the rootfs image. Usually it gives a direct error for a library
|
|
|
|
but a wrong include is more subtle.
|
|
|
|
Note that Kea has a build tool (kea-msg-compiler) but its use is optional
|
|
|
|
so it should not be a problem. If anyway you need it simply copy it from
|
|
|
|
a native (i.e. not cross-compiled) Kea build.
|
|
|
|
|
|
|
|
@section raspbianDependencies Usual Kea Dependencies
|
|
|
|
|
|
|
|
Required and optional Kea dependencies, usually available as packages:
|
|
|
|
- Python (built-in)
|
|
|
|
- Cassandra (skipped here)
|
|
|
|
- libssl-dev (built-in in the full image)
|
|
|
|
- liblog4cplus-dev (in liblog4cplus package, load both the library and
|
|
|
|
the development part)
|
|
|
|
- libboost-system-dev (in boost-xxx, load both the boost-system and
|
|
|
|
the boost-libraries packages, the second includes header files)
|
|
|
|
- googletest (download the last release from github)
|
|
|
|
- doc (sphinx, texlive, etc: just generate docs on the build system)
|
|
|
|
- MySQL (in mysql-defaults and mariadb-* packages?)
|
|
|
|
- PostgreSQL (in postgresql-12?)
|
|
|
|
|
|
|
|
@section prepareCrossCompile Prepare Cross Compiling
|
|
|
|
|
|
|
|
This script was used with success: it sets the environment variables
|
|
|
|
before calling ./configure.
|
|
|
|
@code
|
|
|
|
# change when at another location
|
|
|
|
export ROOTFS="$HOME/rpi/rootfs"
|
|
|
|
|
|
|
|
# build commands
|
|
|
|
export BUILD=x86_64-pc-linux-gnu
|
|
|
|
export HOST=arm-linux-gnueabihf
|
|
|
|
export CC="${HOST}-gcc"
|
|
|
|
export CXX="${HOST}-g++"
|
|
|
|
export LD="${HOST}-ld"
|
|
|
|
export AR="${HOST}-ar"
|
|
|
|
export RANLIB="${HOST}-ranlib"
|
|
|
|
export STRIP="${HOST}-strip"
|
|
|
|
export NM="${HOST}-nm"
|
|
|
|
|
|
|
|
# g++ flags
|
|
|
|
CXXFLAGS="-O2 -g -isysroot ${ROOTFS} -I${ROOTFS}/usr/include"
|
|
|
|
CXXFLAGS+=" -I${ROOTFS}/usr/include/${HOST}"
|
|
|
|
|
|
|
|
# ld flags
|
|
|
|
LDFLAGS="--sysroot=${ROOTFS}"
|
|
|
|
LDFLAGS+=" -L/opt/cross-pi-gcc/arm-linux-gnueabihf/lib -Wl,-rpath-link,/opt/cross-pi-gcc/arm-linux-gnueabihf/lib"
|
|
|
|
LDFLAGS+=" -L/opt/cross-pi-gcc/lib -Wl,-rpath-link,/opt/cross-pi-gcc/lib"
|
|
|
|
LDFLAGS+=" -L${ROOTFS}/opt/vc/lib -Wl,-rpath-link,${ROOTFS}/opt/vc/lib"
|
|
|
|
LDFLAGS+=" -L${ROOTFS}/lib/${HOST} -Wl,-rpath-link,${ROOTFS}/lib/${HOST}"
|
|
|
|
LDFLAGS+=" -L${ROOTFS}/usr/local/lib -Wl,-rpath-link,${ROOTFS}/usr/local/lib"
|
|
|
|
LDFLAGS+=" -L${ROOTFS}/usr/lib/${HOST} -Wl,-rpath-link,${ROOTFS}/usr/lib/${HOST}"
|
|
|
|
LDFLAGS+=" -L${ROOTFS}/usr/lib -Wl,-rpath-link,${ROOTFS}/usr/lib"
|
|
|
|
LDFLAGS+=" -L${ROOTFS}/usr/lib/${HOST}/blas -Wl,-rpath-link,${ROOTFS}/usr/lib/${HOST}/blas"
|
|
|
|
LDFLAGS+=" -L${ROOTFS}/usr/lib/${HOST}/lapack -Wl,-rpath-link,${ROOTFS}/usr/lib/${HOST}/lapack"
|
|
|
|
|
|
|
|
# CPU tuning (use the most generic one)
|
|
|
|
# PI 4 (not sure for the FPU)
|
|
|
|
# CXXFLAGS+=" -mcpu=cortex-a72 -mfpu=neon-vfpv4 -mfloat-abi=hard"
|
|
|
|
# PI 3
|
|
|
|
# CXXFLAGS+=" -mcpu=cortex-a53 -mfpu=neon-vfpv4 -mfloat-abi=hard"
|
|
|
|
# PI 2
|
|
|
|
# CXXFLAGS+=" -mcpu=cortex-a7 -mfpu=neon-vfpv4 -mfloat-abi=hard"
|
|
|
|
# PI 1, zero, ...
|
|
|
|
CXXFLAGS+=" -mcpu=arm1176jzf-s -mfpu=vfp -mfloat-abi=hard"
|
|
|
|
|
|
|
|
export CXXFLAGS
|
|
|
|
export LDFLAGS
|
|
|
|
|
|
|
|
export PKG_CONFIG_PATH="${ROOTFS}/usr/lib/pkgconfig"
|
|
|
|
|
|
|
|
export PATH=/opt/cross-pi-gcc/bin:/opt/cross-pi-gcc/libexec/gcc/arm-linux-gnueabihf/8.3.0:$PATH
|
|
|
|
|
|
|
|
# libraries are in fact in ${ROOTFS}/usr/lib/${HOST} but
|
|
|
|
# the library path can be set only for boost.
|
|
|
|
CONF_CMD="./configure --build=${BUILD} --host=${HOST}"
|
|
|
|
CONF_CMD+=" --with-sysroot=${ROOTFS}"
|
|
|
|
CONF_CMD+=" --with-openssl=${ROOTFS}/usr"
|
|
|
|
CONF_CMD+=" --with-log4cplus=${ROOTFS}/usr"
|
|
|
|
CONF_CMD+=" --with-boost-include=${ROOTFS}/usr/include"
|
|
|
|
CONF_CMD+=" --with-boost-lib-dir=${ROOTFS}/usr/lib/${HOST}"
|
|
|
|
@endcode
|
|
|
|
|
|
|
|
Some explainations:
|
|
|
|
- the rootfs was copied or mounted in rpi/rootfs in the home directory.
|
|
|
|
- the build system triplet is x86_64-pc-linux-gnu (processor,
|
|
|
|
system, application binary interface). It is returned by the config.guess
|
|
|
|
script so please verify.
|
|
|
|
- the host system triplet is arm-linux-gnueabihf. It is used as the prefix
|
|
|
|
for cross-compiling tools so this value is critical.
|
|
|
|
- all tool variables are set to the cross-compiling tool name
|
|
|
|
- CXXFLAGS is defined to use the rootfs image for includes. It is critical
|
|
|
|
it does not use any build system include.
|
|
|
|
- LDFLAGS is defined to use the rootfs, all cross-compiler support libraries
|
|
|
|
and libraries from the rootfs image. It is critical it does not use
|
|
|
|
any build system library.
|
|
|
|
- CXXFLAGS can be tuned for a specific Raspberry Pi version. Proposed
|
|
|
|
tuning supports all versions.
|
2020-07-23 21:15:06 +02:00
|
|
|
- even if Kea ./configure does not depends on pkgconfig its path is set.
|
2020-07-16 22:22:46 +02:00
|
|
|
- PATH is updated to find first cross-compiling tools.
|
|
|
|
- I did not try yet database config scripts: perhaps they detect
|
|
|
|
cross-compiling and produce correct paths.
|
|
|
|
- CONF_CMD contains the ./configure common arguments.
|
2020-12-18 22:06:20 +02:00
|
|
|
|
2020-07-16 22:22:46 +02:00
|
|
|
The script can be used by:
|
|
|
|
- eventually run "autoreconf -i" (if sources are from git)
|
|
|
|
- put its content in a file, e.g. ccenv
|
|
|
|
- load the file by ". ccenv"
|
|
|
|
- configure Kea build by "$CONF_CMD <your arguments>"
|
|
|
|
|
|
|
|
Known problems:
|
|
|
|
- AC_TRY_RUN and AC_CHECK_FILE[S] autoconf macros do not support
|
|
|
|
cross-compiling. They were removed from ./configure.ac in Kea 1.7.10.
|
|
|
|
- libtool is a disaster for cross-compiling, in particular it produces
|
|
|
|
silly libtool archive (.la) files. Fortunately they are useless.
|
|
|
|
- bad paths for mkdir or sed on Raspbian.
|
|
|
|
- recent Debian systems including recent Ubuntu modified libtool to
|
|
|
|
not accept indirect dependencies. Makefiles were updated to have no
|
|
|
|
such indirect dependencies in common cases as it is in Kea Makefile
|
|
|
|
writing guidelines.
|
|
|
|
- the libtool variable managing this is link_all_deplibs. You can
|
|
|
|
edit the libtool script to set it to unknown or yes. Or simply
|
|
|
|
use another Linux distrib.
|
|
|
|
- there is no ldd in cross-compiling tools. The table of used
|
|
|
|
shared libraries in available by readelf -d which is in the
|
|
|
|
cross-compiling tools.
|
|
|
|
|
|
|
|
Final words: this is still highly experimental and does not cover
|
|
|
|
everything. New ways to offload almost everything outside the Raspberry
|
|
|
|
Pi are still to be found. Currently to provide Raspbian Kea packages
|
|
|
|
is not possible for ISC.
|
|
|
|
|
|
|
|
*/
|