summaryrefslogtreecommitdiffstats
path: root/doc/devel/cross-compile.dox
diff options
context:
space:
mode:
Diffstat (limited to 'doc/devel/cross-compile.dox')
-rw-r--r--doc/devel/cross-compile.dox226
1 files changed, 226 insertions, 0 deletions
diff --git a/doc/devel/cross-compile.dox b/doc/devel/cross-compile.dox
new file mode 100644
index 0000000..cc7685e
--- /dev/null
+++ b/doc/devel/cross-compile.dox
@@ -0,0 +1,226 @@
+// Copyright (C) 2020-2022 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
+<a href="https://www.raspberrypi.org/software/operating-systems/">
+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:
+<a href="https://github.com/Pro/raspi-toolchain">RaspberryPi toolchain on github</a>.
+
+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
+to get them following next section instructions. If you have, simply
+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.
+
+The /etc/apt/sources.list file content is:
+@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
+
+and the /etc/apt/sources.list.d/raspi.list file content is:
+@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
+ - extract files using the dpkg-deb -R tool on the .deb file
+ - install the files (usually in the "rootfs"/usr directory)
+The idea is the files (includes and libraries) can be found by
+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
+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
+a documentation, which is well worth reading.
+
+@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)
+ - 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 explanations:
+ - 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.
+ - even if Kea ./configure does not depends on pkgconfig its path is set.
+ - 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.
+
+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.
+
+*/