Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cross Compiler for HWCTRL package #83

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions hwctrl/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
cc_internals/
log/
21 changes: 21 additions & 0 deletions hwctrl/CC.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Cross Compile Instructions

1. Download docker desktop from here (https://www.docker.com/products/docker-desktop) for windows (WSL 2) and OSX. If you're using linux, I'm sure theres a way to run docker images too. (following the directions here should work fine: https://docs.docker.com/engine/install/ubuntu/)

2. Run `chmod +x {filename}` on both scripts in this folder

3. Run the setup script from this directory (make sure you run this as root (`sudo`))

4. change directory to your catkin workspace (such as `catkin_ws` or similar).

5. Run `catkin clean`

6. Run the cross compile command: `{workspace_name}/src/NASA-RMC-2020/hwctrl/cross_compile.sh .` (The dot at the end is important). IT WILL NOT WORK UNLESS YOU RUN IT FROM THE WORKSPACE ROOT! This will take a while on the first run and will take a few GB of space to download the docker image. After that, the build takes around 60 seconds on my computer with 7 cores allocated to docker.

7. Use `scp` to transfer binary to the beaglebone. Eventually I will make a script for this. For now, do it manually.

#### Note:
Sometimes theres issues with shared libraries and such on the beaglebone. Usually you just have to simlink some binaries due to differing versions.

### Links:
https://github.com/ros-tooling/cross_compile
8 changes: 4 additions & 4 deletions hwctrl/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -104,10 +104,10 @@ add_executable(hwctrl_cal

add_executable(led_node src/led_node.cpp)

if(CATKIN_ENABLE_TESTING)
catkin_add_gtest(hwctrl_tests test/testing.cpp src/util.cpp)
target_link_libraries(hwctrl_tests ${catkin_LIBRARIES})
endif()
# if(CATKIN_ENABLE_TESTING)
# catkin_add_gtest(hwctrl_tests test/testing.cpp src/util.cpp)
# target_link_libraries(hwctrl_tests ${catkin_LIBRARIES})
# endif()

# we only want lto if we are in release mode
if(CMAKE_BUILD_TYPE STREQUAL "Release")
Expand Down
14 changes: 14 additions & 0 deletions hwctrl/cc_internals/armhf-ubuntu-melodic/build_workspace.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#!/bin/bash
set -euxo pipefail

mkdir -p /opt/ros/"${ROS_DISTRO}"
touch /opt/ros/"${ROS_DISTRO}"/setup.bash

set +ux
# shellcheck source=/dev/null
source /opt/ros/"${ROS_DISTRO}"/setup.bash
set -ux
colcon build --mixin "${TARGET_ARCH}"-docker \
--build-base build_"${TARGET_ARCH}" \
--install-base install_"${TARGET_ARCH}"
chown -R "${OWNER_USER}" .
53 changes: 53 additions & 0 deletions hwctrl/cc_internals/armhf-ubuntu-melodic/gather_rosdeps.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
#!/bin/bash
set -euxo pipefail

if [ ! -d ./src ]; then
echo "No src/ directory found at $(pwd), did you remember to mount your workspace?"
exit 1
fi

if [ -f "${CUSTOM_SETUP}" ]; then
chmod +x "${CUSTOM_SETUP}"
pushd "$(dirname "${CUSTOM_SETUP}")"
"${CUSTOM_SETUP}"
popd
fi

out_dir=$(dirname "${OUT_PATH}")
mkdir -p "${out_dir}"

rosdep update

cat > "${OUT_PATH}" <<EOF
#!/bin/bash
set -euxo pipefail
EOF

mapfile -t package_paths < <(colcon list -p)

rosdep install \
--os "${TARGET_OS}" \
--rosdistro "${ROSDISTRO}" \
--from-paths "${package_paths[@]}" \
--ignore-src \
--reinstall \
--default-yes \
--skip-keys "${SKIP_ROSDEP_KEYS}" \
--simulate \
>> /tmp/all-deps.sh

# Grep returns nonzero when there are no matches and we exit on error in this script,
# but it's ok if there are no matches, so use "|| true" to always return 0
# Find the non-apt lines and move them as-is to the final script
grep -v "apt-get install -y" /tmp/all-deps.sh >> "${OUT_PATH}" || true

# Find all apt-get lines from the rosdep output
# As an optimization, we will combine all such commands into a single command to save time
grep "apt-get install -y" /tmp/all-deps.sh > /tmp/apt-deps.sh || true
# awk notes:
# "apt-get", "install", "-y", package_name is the fourth column
# ORS=' ' makes the output space-separated instead of newline-separated output
echo "apt-get install -y $(awk '{print $4}' ORS=' ' < /tmp/apt-deps.sh)" >> "${OUT_PATH}"

chmod +x "${OUT_PATH}"
chown -R "${OWNER_USER}" "${out_dir}"
4 changes: 4 additions & 0 deletions hwctrl/cc_internals/armhf-ubuntu-melodic/install_rosdeps.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#!/bin/bash
set -euxo pipefail
#[apt] Installation commands:
apt-get install -y ros-melodic-catkin ros-melodic-roscpp ros-melodic-sensor-msgs ros-melodic-message-runtime ros-melodic-std-msgs ros-melodic-rostest ros-melodic-rospy ros-melodic-message-generation ros-melodic-geometry-msgs
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
build:
aarch64-docker: {}
aarch64-linux:
cmake-args:
- "-DCMAKE_SYSTEM_NAME=Linux"
- "-DCMAKE_SYSTEM_VERSION=1"
- "-DCMAKE_SYSTEM_PROCESSOR=aarch64"
- "-DCMAKE_C_COMPILER=/usr/bin/aarch64-linux-gnu-gcc"
- "-DCMAKE_CXX_COMPILER=/usr/bin/aarch64-linux-gnu-g++"
- "-DCMAKE_SYSROOT=$CC_ROOT/sysroot"
- "-DCMAKE_TRY_COMPILE_TARGET_TYPE=STATIC_LIBRARY"
- "-DCMAKE_FIND_ROOT_PATH=$CC_ROOT/sysroot/root_path:$CC_ROOT/install"
- "-DCMAKE_INSTALL_RPATH=$CC_ROOT/sysroot/opt/ros/$ROS_DISTRO/lib"
- "-DCMAKE_INSTALL_RPATH_USE_LINK_PATH=TRUE"
- "-DCMAKE_FIND_ROOT_PATH_MODE_PROGRAM=NEVER"
- "-DCMAKE_FIND_ROOT_PATH_MODE_PACKAGE=ONLY"
- "-DCMAKE_FIND_ROOT_PATH_MODE_LIBRARY=ONLY"
- "-DCMAKE_FIND_ROOT_PATH_MODE_INCLUDE=ONLY"
- "-DPYTHON_SOABI=cpython-36m-aarch64-linux-gnu"
- "-DTHREADS_PTHREAD_ARG=0"
- "--no-warn-unused-cli"
arm-linux:
cmake-args:
- "-DCMAKE_SYSTEM_NAME=Linux"
- "-DCMAKE_SYSTEM_VERSION=1"
- "-DCMAKE_SYSTEM_PROCESSOR=armv7l"
- "-DCMAKE_C_COMPILER=/usr/bin/arm-linux-gnueabi-gcc"
- "-DCMAKE_CXX_COMPILER=/usr/bin/arm-linux-gnueabi-g++"
- "-DCMAKE_SYSROOT=$CC_ROOT/sysroot"
- "-DCMAKE_FIND_ROOT_PATH=$CC_ROOT/sysroot/root_path:$CC_ROOT/install"
- "-DCMAKE_INSTALL_RPATH=$CC_ROOT/sysroot/opt/ros/$ROS_DISTRO/lib"
- "-DCMAKE_INSTALL_RPATH_USE_LINK_PATH=TRUE"
- "-DCMAKE_FIND_ROOT_PATH_MODE_PROGRAM=NEVER"
- "-DCMAKE_FIND_ROOT_PATH_MODE_PACKAGE=ONLY"
- "-DCMAKE_FIND_ROOT_PATH_MODE_LIBRARY=ONLY"
- "-DCMAKE_FIND_ROOT_PATH_MODE_INCLUDE=ONLY"
- "-DPYTHON_SOABI=cpython-36m-arm-linux-gnueabi"
- "-DTHREADS_PTHREAD_ARG=0"
- "--no-warn-unused-cli"
armhf-docker:
cmake-args:
- "-DCMAKE_C_FLAGS=-Wno-psabi"
- "-DCMAKE_CXX_FLAGS=-Wno-psabi"
- "--no-warn-unused-cli"
armhf-linux:
cmake-args:
- "-DCMAKE_SYSTEM_NAME=Linux"
- "-DCMAKE_SYSTEM_VERSION=1"
- "-DCMAKE_SYSTEM_PROCESSOR=arm"
- "-DCMAKE_C_COMPILER=/usr/bin/arm-linux-gnueabihf-gcc"
- "-DCMAKE_CXX_COMPILER=/usr/bin/arm-linux-gnueabihf-g++"
- "-DCMAKE_SYSROOT=$CC_ROOT/sysroot"
- "-DCMAKE_C_FLAGS=-Wno-psabi"
- "-DCMAKE_CXX_FLAGS=-Wno-psabi"
- "-DCMAKE_FIND_ROOT_PATH=$CC_ROOT/sysroot/root_path:$CC_ROOT/install"
- "-DCMAKE_INSTALL_RPATH=$CC_ROOT/sysroot/opt/ros/$ROS_DISTRO/lib"
- "-DCMAKE_INSTALL_RPATH_USE_LINK_PATH=TRUE"
- "-DCMAKE_FIND_ROOT_PATH_MODE_PROGRAM=NEVER"
- "-DCMAKE_FIND_ROOT_PATH_MODE_PACKAGE=ONLY"
- "-DCMAKE_FIND_ROOT_PATH_MODE_LIBRARY=ONLY"
- "-DCMAKE_FIND_ROOT_PATH_MODE_INCLUDE=ONLY"
- "-DPYTHON_SOABI=cpython-36m-arm-linux-gnueabihf"
- "-DTHREADS_PTHREAD_ARG=0"
- "--no-warn-unused-cli"
x86_64-docker: {}
x86_64-linux: {}
2 changes: 2 additions & 0 deletions hwctrl/cc_internals/armhf-ubuntu-melodic/mixins/index.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
mixin:
- cross-compile.mixin
23 changes: 23 additions & 0 deletions hwctrl/cc_internals/armhf-ubuntu-melodic/rosdep.Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# This Dockerfile describes a simple image with rosdep installed.
# When `run`, it outputs a script for installing dependencies for a given workspace
# Requirements:
# * mount a colcon workspace at /ws
# * see gather_rosdeps.sh for all-caps required input environment
FROM ubuntu:bionic

RUN apt-get update && apt-get install --no-install-recommends -y \
dirmngr \
gnupg2 \
&& rm -rf /var/lib/apt/lists/*
RUN apt-key adv --keyserver 'hkp://keyserver.ubuntu.com:80' --recv-key C1CF6E31E6BADE8868B172B4F42ED6FBAB17C654
RUN echo "deb http://packages.ros.org/ros/ubuntu bionic main" > /etc/apt/sources.list.d/ros-latest.list
RUN apt-get update && apt-get install --no-install-recommends -y \
python-rosdep \
python3-colcon-common-extensions \
&& rm -rf /var/lib/apt/lists/*

RUN rosdep init
COPY gather_rosdeps.sh /root/
RUN mkdir -p /ws
WORKDIR /ws
ENTRYPOINT ["/root/gather_rosdeps.sh"]
15 changes: 15 additions & 0 deletions hwctrl/cc_internals/armhf-ubuntu-melodic/runtime.Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# This dockerfile creates an image containing the runtime environment for the workspace.
# For now this is a thin layer on top of the sysroot/buildroot environment used to build.
# It re-sets the entrypoint to a shell instead of a build script, and copies in the install.
# The eventual plan for it is to only contain `<exec_depends>` of the workspace

ARG BASE_IMAGE
FROM $BASE_IMAGE

WORKDIR /ros_ws

ARG INSTALL_PATH
COPY $INSTALL_PATH/ install

RUN echo "source /ros_ws/install/setup.bash" >> ~/.bashrc
ENTRYPOINT /bin/bash
102 changes: 102 additions & 0 deletions hwctrl/cc_internals/armhf-ubuntu-melodic/sysroot.Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
# This file describes an image that has everything necessary installed to build a target ROS workspace
# It uses QEmu user-mode emulation to perform dependency installation and build
# Assumptions: qemu-user-static directory is present in docker build context

ARG BASE_IMAGE
FROM ${BASE_IMAGE}

ARG ROS_VERSION

SHELL ["/bin/bash", "-c"]

COPY bin/* /usr/bin/

# Set timezone
RUN echo 'Etc/UTC' > /etc/timezone && \
ln -sf /usr/share/zoneinfo/Etc/UTC /etc/localtime

RUN apt-get update && apt-get install --no-install-recommends -y \
tzdata \
locales \
&& rm -rf /var/lib/apt/lists/*

# Set locale
RUN echo 'en_US.UTF-8 UTF-8' >> /etc/locale.gen && \
locale-gen && \
update-locale LC_ALL=en_US.UTF-8 LANG=en_US.UTF-8
ENV LANG en_US.UTF-8
ENV LC_ALL C.UTF-8

# Add the ros apt repo
RUN apt-get update && apt-get install --no-install-recommends -y \
dirmngr \
gnupg2 \
lsb-release \
&& rm -rf /var/lib/apt/lists/*
RUN apt-key adv --keyserver 'hkp://keyserver.ubuntu.com:80' \
--recv-key C1CF6E31E6BADE8868B172B4F42ED6FBAB17C654

RUN echo "deb http://packages.ros.org/${ROS_VERSION}/ubuntu `lsb_release -cs` main" \
> /etc/apt/sources.list.d/${ROS_VERSION}-latest.list

# ROS dependencies
RUN apt-get update && apt-get install --no-install-recommends -y \
build-essential \
cmake \
python3-colcon-common-extensions \
python3-colcon-mixin \
python3-dev \
python3-pip \
&& rm -rf /var/lib/apt/lists/*

RUN python3 -m pip install -U \
setuptools

# Install some pip packages needed for testing ROS 2
RUN if [[ "${ROS_VERSION}" == "ros2" ]]; then \
python3 -m pip install -U \
flake8 \
flake8-blind-except \
flake8-builtins \
flake8-class-newline \
flake8-comprehensions \
flake8-deprecated \
flake8-docstrings \
flake8-import-order \
flake8-quotes \
pytest-repeat \
pytest-rerunfailures \
pytest \
pytest-cov \
pytest-runner \
; fi

# Install Fast-RTPS dependencies for ROS 2
RUN if [[ "${ROS_VERSION}" == "ros2" ]]; then \
apt-get update && apt-get install --no-install-recommends -y \
libasio-dev \
libtinyxml2-dev \
&& rm -rf /var/lib/apt/lists/* \
; fi

# Run arbitrary user setup (copy data and run script)
COPY user-custom-data/ custom-data/
COPY user-custom-setup .
RUN chmod +x ./user-custom-setup && \
./user-custom-setup && \
rm -rf /var/lib/apt/lists/*

# Use generated rosdep installation script
COPY install_rosdeps.sh .
RUN chmod +x install_rosdeps.sh
RUN apt-get update && \
./install_rosdeps.sh && \
rm -rf /var/lib/apt/lists/*

# Set up build tools for the workspace
COPY mixins/ mixins/
RUN colcon mixin add cc_mixin file://$(pwd)/mixins/index.yaml && colcon mixin update cc_mixin
# In case the workspace did not actually install any dependencies, add these for uniformity
COPY build_workspace.sh /root
WORKDIR /ros_ws
ENTRYPOINT ["/root/build_workspace.sh"]
Empty file.
Loading