Cross-compilation Guide
IBMW cross builds separate host tools from target libraries. Use an explicit toolchain/sysroot and an explicit target dependency prefix; never allow a host ROS2 installation to satisfy target package lookup.
Variables
export IBMW_SOURCE_DIR="<ibmw-source-dir>"
export BUILD_DIR="${TMPDIR:-/tmp}/ibmw-cross-build"
export TARGET_SYSROOT="<target-sysroot>"
export ROS2_TARGET_PREFIX="<target-ros2-install-prefix>"
export TOOLCHAIN_FILE="$IBMW_SOURCE_DIR/cmake/toolchains/aarch64-linux-gnu.cmake"
Use a new build directory when changing source trees, generators, toolchains, or target prefixes.
AArch64 Linux without ROS2 types
cmake -S "$IBMW_SOURCE_DIR" -B "$BUILD_DIR" \
-DCMAKE_TOOLCHAIN_FILE="$TOOLCHAIN_FILE" \
-DCMAKE_SYSROOT="$TARGET_SYSROOT" \
-DIBMW_BUILD_PROTOCOLS=OFF \
-DIBMW_BUILD_WITH_ROS2=OFF \
-DIBMW_BUILD_ROS2_TYPES=OFF \
-DIBMW_BUILD_EXAMPLES=ON
cmake --build "$BUILD_DIR" -j"$(nproc)"
AArch64 Linux with DDS/ROS2 interface packages
The target prefix must contain target-architecture FastCDR, FastDDS/FastRTPS, and the ROS2 interface packages required by the selected target. Validate it before configure:
bash "$IBMW_SOURCE_DIR/scripts/deps/check_target_ros2_prefix.sh" \
"$ROS2_TARGET_PREFIX" fastdds types
For generated rosidl work, use the stricter lane:
bash "$IBMW_SOURCE_DIR/scripts/deps/check_target_ros2_prefix.sh" \
"$ROS2_TARGET_PREFIX" fastdds types rosidl
Then configure with host package paths removed and target paths explicit:
env -u CMAKE_PREFIX_PATH -u COLCON_PREFIX_PATH -u ROS_PACKAGE_PATH \
AMENT_PREFIX_PATH="$ROS2_TARGET_PREFIX" \
cmake -S "$IBMW_SOURCE_DIR" -B "$BUILD_DIR" \
-DCMAKE_TOOLCHAIN_FILE="$TOOLCHAIN_FILE" \
-DCMAKE_SYSROOT="$TARGET_SYSROOT" \
-DIBMW_TARGET_ROS2_DEPS_PREFIX="$ROS2_TARGET_PREFIX" \
-DIBMW_BUILD_WITH_ROS2=OFF \
-DIBMW_BUILD_ROS2_TYPES=ON \
-DIBMW_BUILD_DDS_EXTENSION=ON
cmake --build "$BUILD_DIR" -j"$(nproc)"
OHOS ARM64
export OHOS_SDK_NATIVE_ROOT="<ohos-sdk-native-root>"
export BUILD_DIR="${TMPDIR:-/tmp}/ibmw-ohos-build"
export ROS2_TARGET_PREFIX="<ohos-ros2-install-prefix>"
For the DDS-only lane:
cmake -S "$IBMW_SOURCE_DIR" -B "$BUILD_DIR" \
-DOHOS_SDK_NATIVE_ROOT="$OHOS_SDK_NATIVE_ROOT" \
-DIBMW_BUILD_WITH_ROS2=OFF \
-DIBMW_BUILD_ROS2_TYPES=OFF \
-DIBMW_BUILD_DDS_EXTENSION=ON
cmake --build "$BUILD_DIR" -j"$(nproc)"
For the ROS2 interface/rosidl lane, provide the target prefix and any required host Python explicitly. Prefer the repository helper because it isolates host package variables and performs target artifact checks:
IBMW_OHOS_ROS2_PREFIX_LIST="$ROS2_TARGET_PREFIX" \
IBMW_OHOS_SDK_NATIVE_ROOT="$OHOS_SDK_NATIVE_ROOT" \
bash "$IBMW_SOURCE_DIR/scripts/check_ohos_ros2_rosidl_compile.sh" "$BUILD_DIR"
Verification
Inspect target artifacts rather than relying on configure success:
file "$BUILD_DIR/<target-artifact>"
readelf -h "$BUILD_DIR/<target-artifact>"
readelf -d "$BUILD_DIR/<target-artifact>"
Confirm that:
- ELF architecture matches the target.
- dynamic dependencies do not contain absolute host paths;
- CMake cache/package metadata resolves target libraries from the sysroot or
$ROS2_TARGET_PREFIX; - installed package metadata does not reference
$BUILD_DIR; - a clean external consumer can configure against the install prefix.
Cross compilation proves target artifact construction. Deployment, discovery, permissions, shared-memory setup, and board runtime require separate target-side validation. See the Support Matrix.