@autr wrote:
Hi all, I wanted to share my research into getting cross-compiling working for Raspberry Pi with OF 10.1 - in the hopes we can make this accessible to intermediate users (myself included).
As a recap - cross-compiling allows an Pi Arm6 / 7 application to be compiled on a host virtual Linux machine instead of the Pi - the binary / app then copied back across to the Pi for testing, which greatly speeds up the development process (something which can be painfully slow otherwise).
I’m keeping a personal guide for working with the Pi over here:
And cross-compiling guide here: of-cross-compiled-guide.md
What I’ve seen is that there are broadly three documented methods for cross-compiling OpenFrameworks each encompassing the steps:
- Mount or build an up-to-date root filesystem
- Update mounted root filesystem symlinks / paths
- Download and build GCC cross compiler toolchain
1) Debian with Samba
Summary: compiles via network drive, but can’t get past SMB / NFS permissions
System: Debian 9 w. Parallels and macOS
This method mounts the root filesystem via SMB, and also compiles directly onto the network attached Pi, and is first outlined by @jvcleave in the guide for 0.9.0 here:
With an updated gist
build_cross_gc.sh
for 0.10 here:
build_cross_gc.sh
needs some repeat runs before completing - and removing caches helps (ie.rm ./build-gcc/gmp/config.cache
), after which I’m stuck at permission write errors for the SMB drive during compile.This is documented in the original thread and also amended in the SMB guide (where root is mounted at
/rootfs
), but no such luck. I’ve also tried with NFS and am starting to think it could be an issue with using Parallels over VirtualBox.2) ofNode 0.10 Branch
Summary: working, but difficult root setup and addons use
System: Ubuntu 18.4 w. Parallels and macOS
This is the CMake ofNode project last updated for 0.9.8 with Raspbian Jessie, with @avilleret maintaining a 0.10 Stretch branch over here;
And install guide here: how_to_create_sysroot.md
I was unable to create sysroot this way so instead reused RPI_ROOT from the previous guide. Once available, its relatively straight forward generating makefiles and I’ve had success compiling example apps with Arm6.
Addons and addons dependencies however must be defined in the CMakeLists.txt, and I’ve had difficulty getting ofxOMXPlayer v2 and others to work.
3) Continuous Integration / Travis
Summary: works, but with some jiggery pokery
System: Debian 9 w. Parallels and macOS
This is a method outlined by @arturo in the original 0.9.8 thread and reuses Travis CI scripts from the main OF branch to build both cross-compiler and raspbian root.
The main issue I found was that against the autogenerated raspbian root (created during
install.sh
), the build is passing - but the resultant apps / binaries are non functional.OF compiles extremely quickly, but this seems to be because the outputted app is missing its internals;
./colorExample: symbol lookup error: ./colorExample: undefined symbol: glTexEnvf
My solution has been to again re-use the the RPI_ROOT from the second method alongside ENV variables - with success compiling examples for ofxOMXPlayer, ofxOMXCamera and ofxGPIO etc. I also opted to mount the root as a USB clone rather than over network, which speeds up compiling.
I also made a fork of OF here containing:
buildAllRPiExamples.sh
- updated to have failsafes against non-example folders and files; a summary of what is passing and what is not; and loop to clean and rebuild failing examples w. chmod 777build_crosscompiler_arm6.sh
- for now just a WIP reference for stages outlined in the guideOpenFrameworks 0.10.1 Cross-Compile Guide Armv6
Tested macOS Mojave with Debian 9 via Parallels Desktop, Raspberry Pi 3B+ with Raspbian Stretch Lite, OpenFrameworks 0.10.1
Prerequisites
- Linux Debian 9 installation or vitual machine
- USB stick (can be smaller than SD card, but large enough for filesystem)
From the Pi
1️⃣ Install Raspbian Stretch
- Download Raspbian Stretch
- On Mac, ApplePi Baker works well
- On Windows, use PiBakery
- On Linux,
sudo dd bs=1M if=/dev/sdX of=raspbian.img status=progress
2️⃣ SSH in and update everything:
sudo apt update && sudo apt upgrade sudo raspi-config # >>> expand filesystem # >>> update raspi-config # >>> enable GPIO, camera etc
3️⃣ Install all OF dependencies:
cd # Get OF armv6 from downloads page... wget https://openframeworks.cc/versions/v0.10.1/of_v0.10.1_linuxarmv6l_release.tar.gz tar -xvzf of_v0.10.1_linuxarmv6l_release.tar.gz cd of_v0.10.1_linuxarmv6l_release/scripts/linux/debian sudo ./install_dependencies.sh && sudo ./install_codecs.sh
4️⃣ Install any additional addon dependencies (optional):
# ofxOMXPlayer dependencies: cd ~/of_v0.10.1_linuxarmv6l_release/addons git clone https://github.com/jvcleave/ofxOMXPlayer.git cd ofxOMXPlayer sudo ./install_depends.sh
5️⃣ Attach USB stick and copy entire filesystem:
# Install rpi-clone to bin git clone https://github.com/billw2/rpi-clone.git cd rpi-clone sudo cp rpi-clone rpi-clone-setup /usr/local/sbin cd ../ rm -rf rpi-clone # Find out name of USB stick df -h # Clone it sudo rpi-clone sdX
You now have a backup USB…
From Linux
1️⃣ Attach the USB and mount it
# View disks df -h # USB root is the larger partition mkdir /media/Data sudo mount /dev/sdX2 /media/Data/
2️⃣ Create a non-destructive copy of the root
cd ~ mkdir RPI_ROOT cd RPI_ROOT # Create symlinks ln -s /media/Data/etc/ etc ln -s /media/Data/lib/ lib ln -s /media/Data/opt/ opt # Copy entire /usr directory cp -Rv /media/Data/usr/ usr
3️⃣ Update hardcoded links to relative links in
usr
folder (see comment)cd usr/lib/arm-linux-gnueabihf rm libanl.so libBrokenLocale.so libcidn.so libcrypt.so libdbus-1.so libdl.so libexpat.so libglib-2.0.so liblzma.so libm.so libmnl.so libnsl.so libnss_compat.so libnss_dns.so libnss_files.so libnss_hesiod.so libnss_nisplus.so libnss_nis.so libpcre.so libresolv.so librt.so libthread_db.so libusb-1.0.so libutil.so libuuid.so libz.so ln -s ../../../lib/arm-linux-gnueabihf/libanl.so.1 libanl.so ln -s ../../../lib/arm-linux-gnueabihf/libBrokenLocale.so.1 libBrokenLocale.so ln -s ../../../lib/arm-linux-gnueabihf/libcidn.so.1 libcidn.so ln -s ../../../lib/arm-linux-gnueabihf/libcrypt.so.1 libcrypt.so ln -s ../../../lib/arm-linux-gnueabihf/libdbus-1.so.3.14.15 libdbus-1.so ln -s ../../../lib/arm-linux-gnueabihf/libdl.so.2 libdl.so ln -s ../../../lib/arm-linux-gnueabihf/libexpat.so.1.6.2 libexpat.so ln -s ../../../lib/arm-linux-gnueabihf/libglib-2.0.so.0 libglib-2.0.so ln -s ../../../lib/arm-linux-gnueabihf/liblzma.so.5.2.2 liblzma.so ln -s ../../../lib/arm-linux-gnueabihf/libm.so.6 libm.so ln -s ../../../lib/arm-linux-gnueabihf/libmnl.so.0.2.0 libmnl.so ln -s ../../../lib/arm-linux-gnueabihf/libnsl.so.1 libnsl.so ln -s ../../../lib/arm-linux-gnueabihf/libnss_compat.so.2 libnss_compat.so ln -s ../../../lib/arm-linux-gnueabihf/libnss_dns.so.2 libnss_dns.so ln -s ../../../lib/arm-linux-gnueabihf/libnss_files.so.2 libnss_files.so ln -s ../../../lib/arm-linux-gnueabihf/libnss_hesiod.so.2 libnss_hesiod.so ln -s ../../../lib/arm-linux-gnueabihf/libnss_nisplus.so.2 libnss_nisplus.so ln -s ../../../lib/arm-linux-gnueabihf/libnss_nis.so.2 libnss_nis.so ln -s ../../../lib/arm-linux-gnueabihf/libpcre.so.3 libpcre.so ln -s ../../../lib/arm-linux-gnueabihf/libresolv.so.2 libresolv.so ln -s ../../../lib/arm-linux-gnueabihf/librt.so.1 librt.so ln -s ../../../lib/arm-linux-gnueabihf/libthread_db.so.1 libthread_db.so ln -s ../../../lib/arm-linux-gnueabihf/libusb-1.0.so.0.1.0 libusb-1.0.so ln -s ../../../lib/arm-linux-gnueabihf/libutil.so.1 libutil.so ln -s ../../../lib/arm-linux-gnueabihf/libuuid.so.1.3.0 libuuid.so ln -s ../../../lib/arm-linux-gnueabihf/libz.so.1.2.8 libz.so
4️⃣ Clone OpenFrameworks from Github, using one of two options:
# A) my fork with additional scripts git clone -b cross-compile-pi --recursive git@github.com:autr/openFrameworks.git # B) current release git clone -b patched-release --recursive git@github.com:openframeworks/openFrameworks.git
5️⃣ Install dependencies & toolchain
# Dependencies sudo openFrameworks/scripts/linux/download_libs.sh sudo openFrameworks/scripts/linux/debian/install_dependencies.sh sudo openFrameworks/scripts/linux/debian/install_codecs.sh # CI Toolchain sudo openFrameworks/scripts/ci/linuxarmv6l/install.sh
6️⃣ Update bash profile with ENV variables taken from
install.sh
(taking care to updateRPI_ROOT
)# Edit .profile sudo nano ~/.profile # Add these export OF_ROOT=/home/username/openFrameworks # Optional export GCC_PREFIX=arm-linux-gnueabihf export GST_VERSION=1.0 export RPI_ROOT=/home/username/RPI_ROOT # Updated to RPI_ROOT export TOOLCHAIN_ROOT=${OF_ROOT}/scripts/ci/$TARGET/rpi_toolchain export PLATFORM_OS=Linux export PLATFORM_ARCH=armv6l export PKG_CONFIG_LIBDIR=${RPI_ROOT}/usr/lib/pkgconfig:${RPI_ROOT}/usr/lib/${GCC_PREFIX}/pkgconfig:${RPI_ROOT}/usr/share/pkgconfig export CXX="ccache ${TOOLCHAIN_ROOT}/bin/${GCC_PREFIX}-g++" export CC="ccache ${TOOLCHAIN_ROOT}/bin/${GCC_PREFIX}-gcc" export AR=${TOOLCHAIN_ROOT}/bin/${GCC_PREFIX}-ar export LD=${TOOLCHAIN_ROOT}/bin/${GCC_PREFIX}-ld # Reload .profile . ~/.profile # Check its reloaded echo $RPI_ROOT
7️⃣ Compile openFrameworks
sudo openFrameworks/scripts/linux/compileOF.sh
8️⃣ Grab examples from commonly used addons (optional)
cd $OF_ROOT/addons # For video playback... git clone https://github.com/jvcleave/ofxOMXPlayer.git mkdir ../examples/ofxOMXPlayer cp -R ofxOMXPlayer/example* ../examples/ofxOMXPlayer/ # For the GPIO... git clone https://github.com/kashimAstro/ofxGPIO.git mkdir ../examples/ofxGPIO cp -R ofxGPIO/example* ../examples/ofxGPIO/ # For the CSI camera... git clone https://github.com/jvcleave/ofxOMXCamera.git mkdir ../examples/ofxOMXCamera cp -R ofxOMXCamera/example* ../examples/ofxOMXCamera/ # For awesome projection mapping... git clone https://github.com/kr15h/ofxPiMapper.git mkdir ../examples/ofxPiMapper cp -R ofxPiMapper/example* ../examples/ofxPiMapper/
9️⃣ Try compiling all of the examples
sudo chmod -R 777 $OF_ROOT cd $OF_ROOT/scripts/linux/buildAllRPIExamples.sh
If using my fork, script will copy template Makefile for each, loop back around and try to clean and rebuild failing examples, and finally copy each compiled app to an of-rpi-examples folder. You can then copy these examples in one go for testing:
scp $OF_ROOT/of-rpi-examples pi@raspberrypi.local:~/
Test an app from the Pi
ssh pi@raspberrypi.local ./of-rpi-examples/3d/3DPrimitivesExample
Done!
Next Steps
Next up I would like to try the same method in mind to create an Arm7 and headless Arch guide. Re. Travis CI scripts it would be great to work out the built
raspbian
is completing correctly, to avoid the RPI_ROOT generation step. From there perhaps too a customisable stage of multistep.conf for addon dependencies…There is also talk of an official 64bit OS coming to Pi soon, and in the mean time some experimental 64bit OSes, so it may be interesting to try building binaries for these:
Cheers!
Posts: 1
Participants: 1