/**

\page tutorial-install-crosscompiling-raspberry Tutorial: Cross-compilation for Raspberry Pi from Ubuntu host
\tableofcontents

Compiling ViSP directly on your Raspberry Pi will take a lot of time.
In this tutorial you will learn how to cross-compile ViSP from source on an Ubuntu 14.04 host for a <a href="http://www.raspberrypi.org/help/what-is-a-raspberry-pi">Raspberry Pi 1, 2 or 3</a> target.

Adapting this tutorial for other linux hosts (Fedora, Linux Mint, Debian...) should not be too complicated.

The material that is here involved is the following:
- a \b host computer running Ubuntu 14.04 where we will cross-compile ViSP that will then be used on your Raspberry Pi
- a Raspberry Pi board that will the \b target.

\note Concerning ViSP installation on Raspberry Pi, we provide also this other \ref tutorial-install-raspberry.

\section cross_raspberry_setup Setting up Raspberry Pi target

There are a lot of documentation and tutorial that explain different ways to setup a Raspberry Pi. A good reference is the official page <a href="http://www.raspberrypi.org/">http://www.raspberrypi.org</a>

We suppose here that you have a Raspberry Pi board that is already running.

Depending on you application or usage, you may want to install some 3rd parties useful to enable some ViSP capabilities. We recommend to install the following on your Raspberry Pi:

- OpenCV
\verbatim
$ sudo apt-get install libopencv-dev
\endverbatim
- libX11 to be able to open a window to display images
\verbatim
$ sudo apt-get install libx11-dev
\endverbatim
- lapack to benefit from optimized mathematical capabilities
\verbatim
$ sudo apt-get install liblapack-dev
\endverbatim
- libv4l to grab images from usb or analogic cameras
\verbatim
$ sudo apt-get install libv4l-dev
\endverbatim
- QR code detection
\verbatim
$ sudo apt-get install libzbar-dev
\endverbatim

\section cross_raspberry_host Setting up Ubuntu host computer

\subsection cross_raspberry_host_toolchain Install Raspberry official toochain

\note Everything in this section is to run on your Ubuntu host computer.

Start with making a folder in your home directory called \c raspberrypi.
\verbatim
$ mkdir -p $HOME/soft/raspberrypi
\endverbatim

Go in to this folder and pull down the offical Raspberry tools folder.
\verbatim
$ cd $HOME/soft/raspberrypi
$ git clone git://github.com/raspberrypi/tools.git --depth=1
\endverbatim

The toochain that will be used is located in \c $HOME/soft/raspberrypi/tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian. Add now toolchain binaries location to your \c PATH adding
\verbatim
export PATH=$PATH:$HOME/soft/raspberrypi/tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian/bin
\endverbatim
to the end of the file named \c ~/.bashrc

Now you can either log out and log back in (i.e. restart your terminal session), or run \c . \c ~/.bashrc in your terminal to pick up the \c PATH addition in your current terminal session.

Now, verify that you can access the compiler \c arm-linux-gnueabihf-g++.

\verbatim
$ arm-linux-gnueabihf-g++ --version
\endverbatim

You should get something like this:
\verbatim
arm-linux-gnueabihf-g++ (crosstool-NG linaro-1.13.1-4.8-2014.01 - Linaro GCC 2013.11) 4.8.3 20140106 (prerelease)
Copyright (C) 2013 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
\endverbatim

\subsection cross_raspberry_host_rsync Install Raspberry Pi sysroot

This step is mandatory to cross-compile ViSP with the 3rd parties that are already installed on the Raspberry target.

In your raspberrypi folder, make a folder called \c rootfs.

\verbatim
$ mkdir $HOME/soft/raspberrypi/rootfs
\endverbatim

Now you need to copy via \c rsync the entire Raspberry \c /lib and \c /usr directories to this newly created folder.

\verbatim
$ rsync -rl --delete-after --safe-links pi@192.168.1.PI:/{lib,usr} $HOME/soft/raspberrypi/rootfs
\endverbatim
where \c 192.168.1.PI is replaced by the IP of your Raspberry Pi.

\subsection cross_raspberry_visp_src Get ViSP source code

Cross-compilation capabilities are fully supported since ViSP 3.0.1 release.

There are different ways to get ViSP source code on Raspberry Pi:

- You can download a <a href="https://visp.inria.fr/download#snapshot">daily snapshot</a>. Once downloaded, uncompress the file using
\verbatim
$ tar xvzf visp-snapshot-yyyy-mm-dd.tar.gz
\endverbatim

- Or you get the cutting-edge ViSP from <a href="https://github.com/lagadic/visp">GitHub repository</a> using the following command
\verbatim
$ git clone https://github.com/lagadic/visp.git
\endverbatim

- Or you can download the <a href="https://visp.inria.fr/download">latest release</a> (should be at least 3.0.1) as a zip or a tarball. Once downloaded, uncompress the file using either
\verbatim
$ tar xvzf visp-x.y.z.tar.gz
\endverbatim
or
\verbatim
$ unzip visp-x.y.z.zip
\endverbatim

We suppose now that ViSP source is in a directory denoted \c \<source_dir\>, for example \c $HOME/soft/visp

\subsection cross_raspberry_visp_config Cross-compiling ViSP from source

- Create first a directory denoted \c \<binary_dir\> where you want to cross-compile ViSP. This directory will contain generated Makefiles, object files, and output libraries and binaries that could be later used on the Raspberry Pi.
\verbatim
$ mkdir $HOME/soft/visp-crossbuild
\endverbatim

- Enter \c \<binary_dir\> and configure the build:
\verbatim
$ cd $HOME/soft/visp-crossbuild
$ cmake -DCMAKE_TOOLCHAIN_FILE=../visp/platforms/linux/arm-raspberrypi.toolchain.cmake ../visp
\endverbatim
\note See also \ref cross_raspberry_tips_howto_other_toolchain and \ref cross_raspberry_tips_howto_other_rootfs.

- Cross-compile ViSP
\verbatim
$ make -j4 install
\endverbatim
At this point, depending on your Raspberry version you may encounter the following issues \ref cross_raspberry_tips_libpthread, \ref cross_raspberry_tips_libc, \ref cross_raspberry_tips_libpng, \ref cross_raspberry_tips_gcc_4_9 for which we give some hints to work around.

At the end, the resulting installation is available in\c $HOME/soft/visp-crossbuild

\subsection cross_raspberry_visp_usage Using ViSP cross-compilation result on Raspberry

The result of the cross-compilation could then be used on the Raspberry. We give a brief summary of the steps:

- Copy the cross-build installation to Raspberry Pi target
\verbatim
$ tar cvzf install.tar.gz install
$ scp -r install.tar.gz pi@192.168.1.PI:
\endverbatim

- Usage on Raspberry Pi
First move the libraries that were cross-build to a more friend location
\verbatim
$ ssh pi@192.168.1.PI
pi@raspberrypi:~ $ tar xvzf install.tar.gz
pi@raspberrypi:~ $ mv install visp-crossbuild
\endverbatim
Then as described in \ref tutorial-getting-started create a tutorial-viewer.cpp and the corresponding CMakeLists.txt file in $HOME/started:
\verbatim
pi@raspberrypi:~ $ cd $HOME/started
pi@raspberrypi:~ $ ls
tutorial-viewer.cpp CMakeLists.txt
\endverbatim
Create a build folder:
\verbatim
pi@raspberrypi:~ $ mkdir build
pi@raspberrypi:~ $ cd build
\endverbatim
To configure this project, you may run:
\verbatim
pi@raspberrypi:~ $ cmake .. -DVISP_DIR=/home/pi/visp-crossbuild/lib/cmake/visp
\endverbatim
At this step you may encounter the following issue with a Raspberry Pi 1: \ref cross_raspberry_tips_cmake_version. Once fixed, to build just run:
\verbatim
pi@raspberrypi:~ $ make
\endverbatim

\section cross_raspberry_tips Tips and tricks

\subsection cross_raspberry_tips_howto_other_toolchain How to use an other toochain

The default toolchain used in \c arm-raspberrypi.toolchain.cmake file is the one located in \c $HOME/soft/raspberrypi/tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian/bin. To set an other toochain, use \c ARM_RASPBERRY_CROSSCHAIN cmake var:
\verbatim
$ cmake -DARM_RASPBERRY_CROSSCHAIN=$HOME/soft/raspberrypi/tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian-x64/bin -DCMAKE_TOOLCHAIN_FILE=../visp/platforms/linux/arm-raspberrypi.toolchain.cmake ../visp
\endverbatim

Don't forget to update the location of the toolchain in your PATH in \c ~/.bashrc file:
\verbatim
export PATH=$PATH:$HOME/soft/raspberrypi/tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian-x64/bin
\endverbatim

\subsection cross_raspberry_tips_howto_other_rootfs How to use an other rootfs location

The default rootfs used in \c arm-raspberrypi.toolchain.cmake file is the one located in \c $HOME/soft/raspberrypi/roots. To set an other location, use \c ARM_RASPBERRY_ROOTFS cmake var:
\verbatim
$ cmake -DARM_RASPBERRY_ROOTFS=$HOME/soft/raspberrypi/root-fs-pi3 -DCMAKE_TOOLCHAIN_FILE=../visp/platforms/linux/arm-raspberrypi.toolchain.cmake ../visp
\endverbatim

\subsection cross_raspberry_tips_libpthread Linker cannot find libpthread.so

During the cross-compilation, if you get the following error:

\verbatim
Linking CXX shared library ../../lib/libvisp_core.so
 .../tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian/bin/../lib/gcc/arm- linux-gnueabihf/4.8.3/../../../../arm-linux-gnueabihf/bin/ld: cannot find /lib/arm-linux-gnueabihf/libpthread.so.0
 .../tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian/bin/../lib/gcc/arm-linux-gnueabihf/4.8.3/../../../../arm-linux-gnueabihf/bin/ld: cannot find /usr/lib/arm-linux-gnueabihf/libpthread_nonshared.a
\endverbatim

Do the following:
\verbatim
$ cd $HOME/soft/raspberrypi/rootfs
$ find . -name libpthread.so
./usr/lib/arm-linux-gnueabihf/libpthread.so
\endverbatim

Edit this file to set relative path:

\verbatim
$ vi ./usr/lib/arm-linux-gnueabihf/libpthread.so
OUTPUT_FORMAT(elf32-littlearm)
GROUP ( ../../../lib/arm-linux-gnueabihf/libpthread.so.0 ../../../usr/lib/arm-linux-gnueabihf/libpthread_nonshared.a )
\endverbatim

\subsection cross_raspberry_tips_libc Linker cannot find libc.so

During the cross-compilation, if you get the following error:
\verbatim
.../tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian/bin/../lib/gcc/arm-linux-gnueabihf/4.8.3/../../../../arm-linux-gnueabihf/bin/ld: cannot find /lib/arm-linux-gnueabihf/libc.so.6
.../tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian/bin/../lib/gcc/arm-linux-gnueabihf/4.8.3/../../../../arm-linux-gnueabihf/bin/ld: cannot find /usr/lib/arm-linux-gnueabihf/libc_nonshared.a
.../tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian/bin/../lib/gcc/arm-linux-gnueabihf/4.8.3/../../../../arm-linux-gnueabihf/bin/ld: cannot find /lib/arm-linux-gnueabihf/ld-linux-armhf.so.3
\endverbatim

Do the following:
\verbatim
$ cd $HOME/soft/raspberrypi/rootfs
$ find . -name libc.so
./usr/lib/arm-linux-gnueabihf/libc.so
\endverbatim

Edit this file to set relative path:
\verbatim
$ vi ./usr/lib/arm-linux-gnueabihf/libc.so
OUTPUT_FORMAT(elf32-littlearm)
GROUP ( ../../../lib/arm-linux-gnueabihf/libc.so.6 ../../../usr/lib/arm-linux-gnueabihf/libc_nonshared.a  AS_NEEDED ( ../../../lib/arm-linux-gnueabihf/ld-linux-armhf.so.3 ) )
\endverbatim

\subsection cross_raspberry_tips_libpng No rule to make target libpng.so

If during cross-compilation, you get the error:
\verbatim
make[3]: *** No rule to make target `.../raspberrypi/rootfs/usr/lib/arm-linux-gnueabihf/libpng.so', needed by `lib/libvisp_io.so.3.0.1'
\endverbatim

It mean that libpng.so is not found. The fix consists in reparing \c libpng12.so link that was miss updated during \c rsync:

\verbatim
$ cd $HOME/soft/raspberrypi/rootfs
$ cd usr/lib/arm-linux-gnueabihf
$ ls -als libpng*
172 -rw-r--r-- 1 fspindle fspindle 175234 juin   7 15:18 libpng12.a
  0 lrwxrwxrwx 1 fspindle fspindle     13 juin   7 15:17 libpng12.so -> libpng12.so.0
  0 lrwxrwxrwx 1 fspindle fspindle     10 juin   7 15:17 libpng.a -> libpng12.a
  0 lrwxrwxrwx 1 fspindle fspindle     11 juin   7 15:17 libpng.so -> libpng12.so
$ rm libpng12.so
$ ln -s ../../../lib/arm-linux-gnueabihf/libpng12.so.0 libpng12.so
\endverbatim

\subsection cross_raspberry_tips_gcc_4_9 Undefined reference to __throw_out_of_range_fmt

This error occurs when cross-compiling for Raspberry Pi 3 Model B.
\verbatim
Linking CXX executable testArray2D
/home/fspindle/sThis is unfortunately due to the OpenCV core library (for Jessie) being built with a newer version of gcc/g++ oft/raspberrypi/rootfs/usr/lib/arm-linux-gnueabihf/libopencv_ts.so.2.4.9: undefined reference to `std::__throw_out_of_range_fmt(char const*, ...)@GLIBCXX_3.4.20'
\endverbatim
This error is due to the fact that OpenCV was built with gcc-4.9 on Raspberry Pi Jessy distro, while the cross-compiler uses gcc-4.8 version.

There exists different work around depending on your use case:
- if you are just interested to build ViSP libraries, a simple workaround is to turn off the build of the tests, demos, tutorials and examples:
\verbatim
$ cd $HOME/soft/visp-crossbuild
$ cmake -DCMAKE_TOOLCHAIN_FILE=../visp/platforms/linux/arm-raspberrypi.toolchain.cmake ../visp -DBUILD_DEMOS=OFF -DBUILD_EXAMPLES=OFF -DBUILD_TESTS=OFF -DBUILD_TUTORIALS=OFF
\endverbatim

- if you are not interested in OpenCV usage on the Raspberry, disable OpenCV:
\verbatim
$ cd $HOME/soft/visp-crossbuild
$ cmake -DCMAKE_TOOLCHAIN_FILE=../visp/platforms/linux/arm-raspberrypi.toolchain.cmake ../visp -DUSE_OPENCV=OFF
\endverbatim

- an other way, that we didn't investigate in depth is to upgrade the toochain to gcc-4.9. Notice that arm-rpi-4.9.3-linux-gnuabihf toolchain in https://github.com/raspberrypi/tools.git doesn't allow cmake to detect all the 3rd parties. During our trial, we succeed to build ViSP, but X11 was not detected. During the configuration cmake only found OpenCV and zbar libraries.

\subsection cross_raspberry_tips_cmake_version CMake 2.8.12 or greater requested

The following error may occur on Raspberry Pi 1 when you are trying to build a project with the resulting cross-build material:
\verbatim
pi@raspberrypi:~ $ cmake .. -DVISP_DIR=/home/pi/visp-crossbuild/lib/cmake/visp
-- The C compiler identification is GNU 4.6.3
-- The CXX compiler identification is GNU 4.6.3
-- Check for working C compiler: /usr/bin/gcc
-- Check for working C compiler: /usr/bin/gcc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
CMake Error at /home/pi/visp-crossbuild/lib/cmake/visp/VISPModule
s.cmake:156 (message):
  This file relies on consumers using CMake 2.8.12 or greater.
Call Stack (most recent call first):
  /home/pi/visp-crossbuild/lib/cmake/visp/VISPConfig.cmake:170 (i
nclude)
  CMakeLists.txt:5 (find_package)
\endverbatim

The current cmake version is 2.8.9 while 2.8.12 is requested:
\verbatim
pi@raspberrypi:~ $ cmake --version
cmake version 2.8.9
\endverbatim

You definitely need to update cmake version on the Raspberry Pi. To this end download and unpack the lastest CMake release. In our case it was cmake-3.5.2.tar.gz

\verbatim
pi@raspberrypi ~ $ cd soft
pi@raspberrypi ~/soft $ tar xvzf cmake-3.5.2.tar.gz
pi@raspberrypi ~/soft $ cd cmake-3.5.2
\endverbatim

Now to build cmake 3.5.2 run the following (it can take some hours on a Raspberry Pi 1):

\verbatim
pi@raspberrypi ~/soft/cmake-3.5.2 $ ./bootstrap --prefix=/usr
pi@raspberrypi ~/soft/cmake-3.5.2 $ sudo make install
pi@raspberrypi ~/soft/cmake-3.5.2 $ cmake --version
cmake version 3.5.2
\endverbatim

Now you should be able to configure your project and build

\verbatim
pi@raspberrypi:~ $ cmake .. -DVISP_DIR=/home/pi/visp-crossbuild/lib/cmake/visp
pi@raspberrypi:~ $ make
\endverbatim

\section cross_raspberry_next Next tutorial

You are now ready to see the next \ref tutorial-getting-started that will show you how to use ViSP as a 3rd party to build your own project on Raspberry Pi or on any other system. Then if you have a Raspberry Pi camera module, you can also follow the \ref tutorial-tracking-blob especially subsection Tracking form v4l2 live cameras.

*/
