#!/bin/bash
|
set -euxo pipefail
|
|
# ROS_DISTRO will be overrided when docker image build
|
ROS_DISTRO=
|
|
export LD_LIBRARY_PATH=/buildroot/host/lib/
|
export SYSROOT=/buildroot/host/aarch64-buildroot-linux-gnu/sysroot/
|
export CC=/buildroot/host/bin/aarch64-buildroot-linux-gnu-gcc
|
export CXX=/buildroot/host/bin/aarch64-buildroot-linux-gnu-g++
|
export CROSS_COMPILE=/buildroot/host/bin/aarch64-buildroot-linux-gnu-
|
export TARGET_ARCH=aarch64
|
# Consist with buildroot target, not flag:m.
|
# flag:m(cpython-38m...) is enabled by --with-pymalloc
|
export PYTHON_SOABI=cpython-38-aarch64-linux-gnu
|
export ROS2_INSTALL_PATH=/buildroot/target/opt/ros/
|
export TARGET_TRIPLE=/buildroot/host/bin/aarch64-buildroot-linux-gnu
|
export ARCH=aarch64
|
|
cleanup() {
|
git -C src/ros2/mimick_vendor/ checkout .
|
|
if [ -e src/ros2/pybind11_vendor/CMakeLists.txt ]; then
|
git -C src/ros2/pybind11_vendor/ checkout .
|
fi
|
|
if [ -e src/ros2/python_cmake_module/ ]; then
|
git -C src/ros2/python_cmake_module/ checkout .
|
fi
|
|
echo "Strip Elf Object files"
|
|
# *.a : static library that must including symbols
|
KNOWN_NO_BINARY="xml|py|dsv|sh|ps1|bash|zsh|cmake|msg|idl|in|action|srv|yaml|gz|em|cpp|h|hpp|md|cc|c|bat|a|txt|pyc"
|
find ${ROS2_INSTALL_PATH} -type f -and ! -empty \
|
-and -regextype posix-extended ! -regex ".*\.(${KNOWN_NO_BINARY})" \
|
-exec grep -IL '' "{}" \; | xargs ${CROSS_COMPILE}strip
|
|
echo "build ros quit & cleanup source changes"
|
}
|
|
trap 'cleanup' EXIT
|
|
prepare_source() {
|
#FIXME: camke set wrong mimick_vendor ARCH when building, in file:
|
# CMakeFiles/3.16.3/CMakeSystem.cmake. This probably because
|
# qemu can run binary for aarch target directly inside Docker image, which broken cmake configuration.
|
# Workaround by set SYSTEM_NAME and SYSTEM_PROCESSER manually
|
sed -i '/^.*ExternalProject.*$/i \ \ list(APPEND cmake_configure_args "-DCMAKE_SYSTEM_NAME=${CMAKE_SYSTEM_NAME}") \n\ \ list(APPEND cmake_configure_args "-DCMAKE_SYSTEM_PROCESSOR=${CMAKE_SYSTEM_PROCESSOR}")' \
|
src/ros2/mimick_vendor/CMakeLists.txt
|
|
# When building galactic's rclpy package:
|
# ./ros/share/cmake/pybind11/pybind11Config.cmake:
|
# -> ./ros/share/cmake/pybind11/pybind11Tools.cmake: find_package(PythonLibsNew
|
# -> ./ros/share/cmake/pybind11/FindPythonLibsNew.cmake
|
# it read host's PYTHON_INCLUDE_DIRS, for example:
|
# $ grep isystem /opt/ros/
|
# .... -isystem /data/ros/install/include ...
|
# A hack as below can workaround and continue building:
|
# - colcon build --packages-up-to pybind11, and then,
|
# - Change PythonLibsNew to PythonLibs before building other packages
|
# but it can not set PYTHON_MODULE_EXTENSION correctly.
|
#
|
# To cross compile for aarch64 target, update to new version of pybind11
|
# see: https://github.com/pybind/pybind11/issues/2139, bug reported
|
# https://github.com/pybind/pybind11/pull/2370, which fixed by introducing "FindPython Mode"
|
if [ -e src/ros2/pybind11_vendor/CMakeLists.txt ]; then
|
sed -i 's|ExternalProject_Add(pybind11.*$|ExternalProject_Add(pybind11-2.7.1|' \
|
src/ros2/pybind11_vendor/CMakeLists.txt
|
sed -i 's|archive/v.*$|archive/v2.7.1.tar.gz|' \
|
src/ros2/pybind11_vendor/CMakeLists.txt
|
sed -i 's|URL_MD5.*$|URL_MD5 b87860218c143728f8e6efa6cba7e1ed|' \
|
src/ros2/pybind11_vendor/CMakeLists.txt
|
fi
|
|
# Use new FindPython Mode, so pybind11 will include pybind11Tools.cmake instead of
|
# pybind11Tools.cmake which finds PythonLibsNew and overrides PYTHON_* from host.
|
if [ -e src/ros2/python_cmake_module/cmake/Modules/FindPythonExtra.cmake ]; then
|
sed -i 's|^find_package(PythonInterp.*$|find_package(Python COMPONENTS Interpreter Development)|' \
|
src/ros2/python_cmake_module/cmake/Modules/FindPythonExtra.cmake
|
sed -i '/^.*find_package_handle_standard_args.*$/i set(PYTHON_MODULE_EXTENSION "${PythonExtra_EXTENSION_SUFFIX}${PythonExtra_EXTENSION_EXTENSION}" CACHE INTERNAL "")' \
|
src/ros2/python_cmake_module/cmake/Modules/FindPythonExtra.cmake
|
fi
|
}
|
|
prepare_source
|
|
mkdir -p /buildroot/build/ros /buildroot/target/opt/ros
|
# cmake's find_package only search sysroot path if CMAKE_SYSROOT has defined
|
# setting COLCON_CURRENT_PREFIX instead?
|
pushd /buildroot/host/aarch64-buildroot-linux-gnu/sysroot/
|
rm -rf opt
|
ln -sf ../../../target/opt/ros/ opt
|
popd
|
|
#FIXME: link buildroot binfmt just because CROSSCOMPILING_EMULATOR don't work
|
# when building foonathan_memory_vendor, and installing qemu-user-static/qemu-user-binfmt
|
# packages require root privilege. The CMAKE_CROSSCOMPILING_EMULATOR doesn't work too.
|
# "-DCMAKE_CROSSCOMPILING_EMULATOR=/usr/bin/qemu-aarch64-static;-L;/buildroot/target/"
|
mkdir -p /etc/qemu-binfmt
|
ln -sf /buildroot/target/ /etc/qemu-binfmt/aarch64
|
|
# install mixin which setup building evinronments
|
colcon mixin remove default || true
|
colcon mixin add default file:///root/index.yaml
|
colcon mixin update default
|
|
# HINTS:
|
# - Use --merge-install to avoid some find_package/find_path/find_library fails
|
|
LDFLAGS="-L/buildroot/host/lib -Wl,-rpath,/buildroot/host/lib" \
|
CFLAGS="-O2 -I/buildroot/host/include/" \
|
colcon build \
|
--mixin aarch64-linux \
|
--merge-install \
|
--build-base /buildroot/build/ros/ \
|
--install-base /buildroot/target/opt/ros \
|
--cmake-force-configure \
|
# --packages-select rclpy
|