Crosscompiling
Revision as of 15:19, 20 May 2024 by Damme (talk | contribs) (Created page with "Warning! You are in for a treat! :D - You have been warned. But reward is good, from 3250sec with docker buildx using qemu to 304s on my machine (Clean build) == Instructions == These instructions are made for Ubuntu 20.04.6 LTS <big>INSTALL ROS https://wiki.ros.org/noetic/Installation/Ubuntu</big> ==== Update source files ==== * Add '''<code>[arch=amd64]</code>''' after deb on each line in <code>/etc/apt/sources.list</code> (This should be changed to your current ma...")
Warning! You are in for a treat! :D - You have been warned. But reward is good, from 3250sec with docker buildx using qemu to 304s on my machine (Clean build)
Instructions
These instructions are made for Ubuntu 20.04.6 LTS
INSTALL ROS https://wiki.ros.org/noetic/Installation/Ubuntu
Update source files
- Add
[arch=amd64]
after deb on each line in/etc/apt/sources.list
(This should be changed to your current machines native arch!) - Add
[arch=amd64,arm64]
after deb in/etc/apt/sources.list.d/ros-latest.list
- Create
/etc/apt/sources.list.d/arm-cross-compile-sources.list
deb [arch=arm64] http://ports.ubuntu.com/ focal main restricted
deb [arch=arm64] http://ports.ubuntu.com/ focal-updates main restricted
deb [arch=arm64] http://ports.ubuntu.com/ focal universe
deb [arch=arm64] http://ports.ubuntu.com/ focal-updates universe
deb [arch=arm64] http://ports.ubuntu.com/ focal multiverse
deb [arch=arm64] http://ports.ubuntu.com/ focal-updates multiverse
deb [arch=arm64] http://ports.ubuntu.com/ focal-backports main restricted universe multiverse
- run
sudo apt update
sudo dpkg --add-architecture arm64
sudo apt install crossbuild-essential-arm64 parallel
- Clone open_mower_ros and its componnets.
cd /opt/
git clone https://github.com/ClemensElflein/open_mower_ros
git submodule update --init --recursive
We will use CMAKE_SYSROOT /opt/sysroot_arm64 and /opt/sysroot_arm64_download - change these accordingly in the files for your needs. Total size to download is about 200MB and extracted is ~1.1GB. Change the number of download threads as desired.
- create
toolchain.cmake
set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_SYSTEM_VERSION 1)
set(CMAKE_SYSTEM_PROCESSOR aarch64)
# Specify the cross compiler
set(CMAKE_C_COMPILER aarch64-linux-gnu-gcc)
set(CMAKE_CXX_COMPILER aarch64-linux-gnu-g++)
#set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static")
#set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -static")
# Specify the target system root
set(CMAKE_SYSROOT /opt/sysroot_arm64)
set(SYSROOT_PATH ${CMAKE_SYSROOT})
unset(CMAKE_SYSTEM_PREFIX_PATH)
list(APPEND CMAKE_SYSTEM_PREFIX_PATH ${CMAKE_SYSROOT}/opt/ros/noetic)
set(CMAKE_PREFIX_PATH ${CMAKE_SYSROOT}/opt/ros/noetic ${CMAKE_SYSROOT}/opt/ros/noetic/share)
set(CMAKE_LIBRARY_PATH ${CMAKE_SYSROOT}/opt/ros/noetic/lib)
set(CMAKE_INCLUDE_PATH ${CMAKE_SYSROOT}/opt/ros/noetic/include)
set(CMAKE_FIND_ROOT_PATH ${CMAKE_SYSROOT})
# Search for programs in the build host directories
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
# For libraries and headers in the target directories
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)
set(CMAKE_MODULE_PATH ${CMAKE_SYSROOT}/usr/share/cmake-3.13/Modules/)
set(ENV{PKG_CONFIG_PATH} ${CMAKE_SYSROOT}/usr/lib/aarch64-linux-gnu/pkgconfig/)
- create
1_setup-sysroot.bash
#!/bin/bash
set -e
SYSROOT=/opt/sysroot_arm64
DOWNLOADDIR=/opt/sysroot_downloads
PARALLELDOWNLOAD=6
#########################
rm -rf $SYSROOT
mkdir -p $SYSROOT
mkdir -p $DOWNLOADDIR
# Link might not be needed? Cant remember :D
ln -s $SYSROOT/usr/lib $SYSROOT/lib
install_package() {
# for PKG in "${PACKAGES[@]}"; do
PKG=$1
URL=$(apt-get download --print-uris $PKG | cut -d\' -f2)
if [ -n "$URL" ]; then
echo "Downloading $PKG ($URL)"
wget -q -nc $URL -P $DOWNLOADDIR && dpkg -x $DOWNLOADDIR/$(basename $URL) $SYSROOT
# --show-progress
# dpkg -x $DOWNLOADDIR/$(basename $URL) $SYSROOT
echo "Done installing $PKG"
else
echo "$PKG NOT FOUND!"
fi
# done
}
export -f install_package
export DOWNLOADDIR
export SYSROOT
# read packages.txt into PACKAGES
while IFS= read -r line; do
PACKAGES+=("$line")
done < "packages.txt"
parallel -j $PARALLELDOWNLOAD install_package ::: "${PACKAGES[@]}"
echo "Done!"
- Download my little
packages.txt
# Focal Ubuntu 20.04.6 LTS!
wget https://gist.githubusercontent.com/Damme/3161f92ccadf452b4d5f3eee32da097e/raw/8df0172858e95da76091b04f8492705fc0cf0396/packages.txt -O packages.txt
- create
2-fix-links-cmake.bash
SYSROOT=/opt/sysroot_arm64
echo "Linking some missing library links, broken links /hardcoded to /lib/..."
ln -sf $SYSROOT/usr/lib/aarch64-linux-gnu/libPocoFoundation.so.62 $SYSROOT/usr/lib/aarch64-linux-gnu/libPocoFoundation.so
ln -sf $SYSROOT/usr/lib/aarch64-linux-gnu/blas/libblas.so.3 $SYSROOT/usr/lib/aarch64-linux-gnu/libblas.so.3
ln -sf $SYSROOT/usr/lib/aarch64-linux-gnu/lapack/liblapack.so.3 $SYSROOT/usr/lib/aarch64-linux-gnu/liblapack.so.3
ln -sf $SYSROOT/lib/aarch64-linux-gnu/librt.so.1 $SYSROOT/sysroot_arm64/usr/lib/aarch64-linux-gnu/librt.so
ln -sf $SYSROOT/lib/aarch64-linux-gnu/libpthread.so.0 $SYSROOT/usr/lib/aarch64-linux-gnu/libpthread.so
ln -sf $SYSROOT/lib/aarch64-linux-gnu/libBrokenLocale.so.1 $SYSROOT/usr/lib/aarch64-linux-gnu/libBrokenLocale.so
ln -sf $SYSROOT/lib/aarch64-linux-gnu/libanl.so.1 $SYSROOT/usr/lib/aarch64-linux-gnu/libanl.so
ln -sf $SYSROOT/lib/aarch64-linux-gnu/libblkid.so.1.1.0 $SYSROOT/usr/lib/aarch64-linux-gnu/libblkid.so
ln -sf $SYSROOT/lib/aarch64-linux-gnu/libbz2.so.1.0 $SYSROOT/usr/lib/aarch64-linux-gnu/libbz2.so
ln -sf $SYSROOT/lib/aarch64-linux-gnu/libexpat.so.1.6.11 $SYSROOT/usr/lib/aarch64-linux-gnu/libexpat.so
ln -sf $SYSROOT/lib/aarch64-linux-gnu/libgpg-error.so.0 $SYSROOT/usr/lib/aarch64-linux-gnu/libgpg-error.so
ln -sf $SYSROOT/lib/aarch64-linux-gnu/libkeyutils.so.1 $SYSROOT/usr/lib/aarch64-linux-gnu/libkeyutils.so
ln -sf $SYSROOT/lib/aarch64-linux-gnu/liblzma.so.5.2.4 $SYSROOT/usr/lib/aarch64-linux-gnu/liblzma.so
ln -sf $SYSROOT/lib/aarch64-linux-gnu/libm.so.6 $SYSROOT/usr/lib/aarch64-linux-gnu/libm.so
ln -sf $SYSROOT/lib/aarch64-linux-gnu/libmount.so.1.1.0 $SYSROOT/usr/lib/aarch64-linux-gnu/libmount.so
ln -sf $SYSROOT/lib/aarch64-linux-gnu/libnsl.so.1 $SYSROOT/usr/lib/aarch64-linux-gnu/libnsl.so
ln -sf $SYSROOT/lib/aarch64-linux-gnu/libnss_compat.so.2 $SYSROOT/usr/lib/aarch64-linux-gnu/libnss_compat.so
ln -sf $SYSROOT/lib/aarch64-linux-gnu/libnss_dns.so.2 $SYSROOT/usr/lib/aarch64-linux-gnu/libnss_dns.so
ln -sf $SYSROOT/lib/aarch64-linux-gnu/libnss_files.so.2 $SYSROOT/usr/lib/aarch64-linux-gnu/libnss_files.so
ln -sf $SYSROOT/lib/aarch64-linux-gnu/libnss_hesiod.so.2 $SYSROOT/usr/lib/aarch64-linux-gnu/libnss_hesiod.so
ln -sf $SYSROOT/lib/aarch64-linux-gnu/libnss_nis.so.2 $SYSROOT/usr/lib/aarch64-linux-gnu/libnss_nis.so
ln -sf $SYSROOT/lib/aarch64-linux-gnu/libnss_nisplus.so.2 $SYSROOT/usr/lib/aarch64-linux-gnu/libnss_nisplus.so
ln -sf $SYSROOT/lib/aarch64-linux-gnu/libpcre.so.3 $SYSROOT/usr/lib/aarch64-linux-gnu/libpcre.so
ln -sf $SYSROOT/lib/aarch64-linux-gnu/libresolv.so.2 $SYSROOT/usr/lib/aarch64-linux-gnu/libresolv.so
ln -sf $SYSROOT/lib/aarch64-linux-gnu/libthread_db.so.1 $SYSROOT/usr/lib/aarch64-linux-gnu/libthread_db.so
ln -sf $SYSROOT/lib/aarch64-linux-gnu/libutil.so.1 $SYSROOT/usr/lib/aarch64-linux-gnu/libutil.so
ln -sf $SYSROOT/lib/aarch64-linux-gnu/libuuid.so.1.3.0 $SYSROOT/usr/lib/aarch64-linux-gnu/libuuid.so
ln -sf $SYSROOT/lib/aarch64-linux-gnu/libz.so.1.2.11 $SYSROOT/usr/lib/aarch64-linux-gnu/libz.so
echo "Fix cmake files with hardcoded paths.."
find $SYSROOT/opt/ros/noetic/ -name "*.cmake" | xargs sed -i s@/opt/ros/noetic/lib@\${SYSROOT_PATH}/opt/ros/noetic/lib@g
find $SYSROOT/opt/ros/noetic/ -name "*.cmake" | xargs sed -i s@PREFIX\ /opt/ros/noetic@PREFIX\ \${SYSROOT_PATH}/opt/ros/noetic@g
find $SYSROOT/opt/ros/noetic/ -name "*.cmake" | xargs sed -i s@\;/usr/@\;\$\{SYSROOT_PATH\}/usr/@g
find $SYSROOT/opt/ros/noetic/ -name "*.cmake" | xargs sed -i s@\"/usr/@\"\$\{SYSROOT_PATH\}/usr/@g
- create
3-patch-openmower-cmake.bash
#!/bin/bash
cd src/lib/slic3r_coverage_planner
patch CMakeLists.txt <<'EOF'
@@ -33,7 +33,9 @@ ExternalProject_Add(
CMAKE_CACHE_ARGS
SOURCE_SUBDIR src
- CMAKE_ARGS -DSLIC3R_BUILD_TESTS=OFF
+ CMAKE_ARGS -DSLIC3R_BUILD_TESTS=OFF -DCMAKE_TOOLCHAIN_FILE=${CMAKE_TOOLCHAIN_FILE}
+ -DCMAKE_EXE_LINKER_FLAGS:STRING=--sysroot=${CMAKE_SYSROOT}\;-L${CMAKE_SYSROOT}/opt/ros/noetic/lib\;-L${CMAKE_SYSROOT}/usr/lib/aarch64-linux-gnu
+ -DCMAKE_SHARED_LINKER_FLAGS:STRING=--sysroot=${CMAKE_SYSROOT}\;-L${CMAKE_SYSROOT}/opt/ros/noetic/lib\;-L${CMAKE_SYSROOT}/usr/lib/aarch64-linux-gnu
BUILD_COMMAND ${CMAKE_COMMAND} --build <BINARY_DIR> --config Release
)
EOF
cd ../../../
cd src/lib/xbot_driver_gps
patch CMakeLists.txt <<'EOF'
@@ -32,6 +32,9 @@ ExternalProject_Add(
INSTALL_COMMAND cmake -E echo "Skipping install step."
CMAKE_CACHE_ARGS
+ CMAKE_ARGS -DCMAKE_TOOLCHAIN_FILE=${CMAKE_TOOLCHAIN_FILE}
+ -DCMAKE_EXE_LINKER_FLAGS:STRING=--sysroot=${CMAKE_SYSROOT}\;-L${CMAKE_SYSROOT}/opt/ros/noetic/lib\;-L${CMAKE_SYSROOT}/usr/lib/aarch64-linux-gnu
+ -DCMAKE_SHARED_LINKER_FLAGS:STRING=--sysroot=${CMAKE_SYSROOT}\;-L${CMAKE_SYSROOT}/opt/ros/noetic/lib\;-L${CMAKE_SYSROOT}/usr/lib/aarch64-linux-gnu
BUILD_COMMAND ${CMAKE_COMMAND} --build <BINARY_DIR> --config Release
)
EOF
cd ../../../
- run the following:
bash 1-setup_sysroot.bash
bash 2-fix-links-cmake.bash
bash 3-patch-openmower-cmake.bash
- build with the following command, change -j1 for number of parallel processes. For some reason catkin_make does not parse toolchain.cmake without forcing it...
$ catkin_make -DCMAKE_TOOLCHAIN_FILE=/opt/open_mower_ros/toolchain.cmake -j1
Good luck!