feat(packaging): add voxl2 Debian package build

Add make_package.sh and supporting files to build a .deb package
for the voxl2 target, bundling both the ARM64 apps processor binary
and Hexagon SLPI DSP library. The package version is derived from
the git tag and short commit hash. CI is updated to build and upload
the .deb alongside existing .px4 artifacts.
This commit is contained in:
Eric Katzfey 2026-03-10 15:48:46 -07:00
parent 107b708918
commit 48207d11db
5 changed files with 300 additions and 1 deletions

View File

@ -181,6 +181,17 @@ jobs:
name: px4_${{matrix.group}}_build_artifacts
path: artifacts/
- name: Build voxl2 Debian Package
if: contains(matrix.targets, 'modalai_voxl2')
run: ./Tools/packaging/voxl2/make_package.sh
- name: Upload voxl2 Debian Package
if: contains(matrix.targets, 'modalai_voxl2')
uses: actions/upload-artifact@v4
with:
name: voxl-px4-deb
path: Tools/packaging/voxl2/*.deb
- name: Cache Post Build Stats
if: always()
run: |
@ -265,5 +276,7 @@ jobs:
with:
draft: true
prerelease: ${{ steps.upload-location.outputs.is_prerelease == 'true' }}
files: artifacts/*.px4
files: |
artifacts/*.px4
artifacts/*.deb
name: ${{ steps.upload-location.outputs.uploadlocation }}

View File

@ -0,0 +1,169 @@
#!/bin/bash
################################################################################
# Copyright (c) 2026 ModalAI, Inc. All rights reserved.
#
# Builds a Debian package for the voxl2 target from existing build artifacts.
# Both modalai_voxl2 and modalai_voxl2-slpi must be built before running this.
#
# Usage:
# ./Tools/packaging/voxl2/make_package.sh
#
################################################################################
set -e
################################################################################
# Resolve paths - script can be run from anywhere
################################################################################
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
PX4_DIR="$(cd "$SCRIPT_DIR/../../.." && pwd)"
PKG_DIR="$SCRIPT_DIR/pkg"
BOARD_DIR="$PX4_DIR/boards/modalai/voxl2"
BUILD_APPS="$PX4_DIR/build/modalai_voxl2_default"
BUILD_SLPI="$PX4_DIR/build/modalai_voxl2-slpi_default"
################################################################################
# Check arguments
################################################################################
for arg in "$@"; do
case "$(echo "$arg" | tr '[:upper:]' '[:lower:]')" in
"-h"|"--help")
echo ""
echo " Build a Debian package for the voxl2 target."
echo " You must build modalai_voxl2 and modalai_voxl2-slpi first."
echo ""
echo " Usage:"
echo " ./Tools/packaging/voxl2/make_package.sh"
echo ""
exit 0
;;
*)
echo "Unknown argument: $arg"
exit 1
;;
esac
done
################################################################################
# Derive version from git
################################################################################
cd "$PX4_DIR"
GIT_TAG=$(git describe --tags --abbrev=0 2>/dev/null || echo "0.0.0")
VERSION=$(echo "$GIT_TAG" | sed 's/^v//')
SHORT_HASH=$(git rev-parse --short HEAD)
VERSION="${VERSION}-g${SHORT_HASH}"
PACKAGE=$(grep "^Package:" "$PKG_DIR/control/control" | cut -d' ' -f 2)
echo "Package: $PACKAGE"
echo "Version: $VERSION"
################################################################################
# Validate build artifacts
################################################################################
MISSING=false
if [ ! -f "$BUILD_APPS/bin/px4" ]; then
echo "Error: $BUILD_APPS/bin/px4 not found. Run 'make modalai_voxl2' first."
MISSING=true
fi
if [ ! -f "$BUILD_APPS/bin/px4-alias.sh" ]; then
echo "Error: $BUILD_APPS/bin/px4-alias.sh not found."
MISSING=true
fi
if [ ! -f "$BUILD_SLPI/platforms/qurt/libpx4.so" ]; then
echo "Error: $BUILD_SLPI/platforms/qurt/libpx4.so not found. Run 'make modalai_voxl2-slpi' first."
MISSING=true
fi
if $MISSING; then
exit 1
fi
################################################################################
# Clean old packaging artifacts
################################################################################
DATA_DIR="$PKG_DIR/data"
DEB_DIR="$PKG_DIR/DEB"
rm -rf "$DATA_DIR"
rm -rf "$DEB_DIR"
rm -f "$SCRIPT_DIR"/*.deb
mkdir -p "$DATA_DIR"
################################################################################
# Stage files into data directory
################################################################################
# --- Apps processor binary ---
mkdir -p "$DATA_DIR/usr/bin"
cp "$BUILD_APPS/bin/px4" "$DATA_DIR/usr/bin/"
cp "$BUILD_APPS/bin/px4-alias.sh" "$DATA_DIR/usr/bin/"
chmod a+x "$DATA_DIR/usr/bin/px4"
chmod a+x "$DATA_DIR/usr/bin/px4-alias.sh"
# --- SLPI DSP library ---
mkdir -p "$DATA_DIR/usr/lib/rfsa/adsp"
cp "$BUILD_SLPI/platforms/qurt/libpx4.so" "$DATA_DIR/usr/lib/rfsa/adsp/"
# --- Target scripts ---
for script in voxl-px4 voxl-px4-start voxl-px4-hitl voxl-px4-hitl-start; do
if [ -f "$BOARD_DIR/target/$script" ]; then
cp "$BOARD_DIR/target/$script" "$DATA_DIR/usr/bin/"
chmod a+x "$DATA_DIR/usr/bin/$script"
fi
done
# --- Barometer calibration script ---
if [ -f "$BOARD_DIR/scripts/baro_temp_cal" ]; then
cp "$BOARD_DIR/scripts/baro_temp_cal" "$DATA_DIR/usr/bin/"
chmod a+x "$DATA_DIR/usr/bin/baro_temp_cal"
fi
# --- Configuration files ---
mkdir -p "$DATA_DIR/etc/modalai"
for config in voxl-px4-fake-imu-calibration.config voxl-px4-hitl-set-default-parameters.config; do
if [ -f "$BOARD_DIR/target/$config" ]; then
cp "$BOARD_DIR/target/$config" "$DATA_DIR/etc/modalai/"
chmod +x "$DATA_DIR/etc/modalai/$config"
fi
done
# --- Systemd service ---
mkdir -p "$DATA_DIR/etc/systemd/system"
cp "$PKG_DIR/services/voxl-px4.service" "$DATA_DIR/etc/systemd/system/"
# --- Build metadata ---
mkdir -p "$DATA_DIR/data/px4/etc/extras"
for meta in parameters.json.xz component_general.json.xz actuators.json.xz; do
if [ -f "$BUILD_APPS/$meta" ]; then
cp "$BUILD_APPS/$meta" "$DATA_DIR/data/px4/etc/extras/"
fi
done
if [ -f "$BUILD_APPS/events/all_events.json.xz" ]; then
cp "$BUILD_APPS/events/all_events.json.xz" "$DATA_DIR/data/px4/etc/extras/"
fi
# --- Create runtime directories ---
mkdir -p "$DATA_DIR/data/px4/param"
################################################################################
# Build the DEB package
################################################################################
mkdir -p "$DEB_DIR"
cp -rf "$PKG_DIR/control/" "$DEB_DIR/DEBIAN"
cp -rf "$DATA_DIR/"* "$DEB_DIR/"
# Write the version into the control file
sed -i "s/^Version:.*/Version: $VERSION/" "$DEB_DIR/DEBIAN/control"
DEB_NAME="${PACKAGE}_${VERSION}_arm64.deb"
dpkg-deb --build "$DEB_DIR" "$SCRIPT_DIR/$DEB_NAME"
echo ""
echo "Package built: $SCRIPT_DIR/$DEB_NAME"
echo "DONE"

View File

@ -0,0 +1,13 @@
Package: voxl-px4
Version: 0.0.0
Section: devel
Priority: optional
Architecture: arm64
Depends: libfc-sensor (>=1.0.10),
voxl-px4-params (>=0.3.10),
voxl3-system-image(>=0.0.2) | voxl2-system-image(>=1.5.4) | rb5-system-image(>=1.6.2),
modalai-slpi(>=1.1.16) | modalai-adsp(>=1.0.2)
Replaces: px4-rb5-flight
Conflicts: px4-rb5-flight
Maintainer: Eric Katzfey <eric.katzfey@modalai.com>
Description: ModalAI PX4 flight controller for VOXL2

View File

@ -0,0 +1,91 @@
#!/bin/bash
################################################################################
# Post-install script for voxl-px4
#
# Creates px4 module symlinks, sets up directories, and handles DSP signatures.
################################################################################
set -e
################################################################################
# Create px4 module symlinks from px4-alias.sh
################################################################################
cd /usr/bin
if [ -f px4-alias.sh ]; then
# Auto-generate symlinks from the alias file produced by the build.
# Each alias line looks like: alias <name>='px4-<module> ...'
# We extract the px4-<module> part and create a symlink to the px4 binary.
grep "^alias " px4-alias.sh | grep -v "^alias set=" | \
sed -n "s/^alias [^=]*='\\(px4-[^ ']*\\).*/\\1/p" | \
sort -u | while read -r MODULE; do
ln -f -s px4 "$MODULE"
done
echo "Created px4 module symlinks"
else
echo "Warning: px4-alias.sh not found, skipping symlink creation"
fi
################################################################################
# Platform detection
################################################################################
PLATFORM="M0197"
if [ -x /usr/bin/voxl-platform ]; then
PLATFORM=$(/usr/bin/voxl-platform 2>/dev/null || echo "M0197")
fi
if [ "$PLATFORM" = "M0052" ]; then
echo "Error: M0052 is no longer supported"
exit 1
fi
echo "Platform: $PLATFORM"
################################################################################
# Create runtime directories
################################################################################
mkdir -p /data/px4/param
mkdir -p /data/px4/slpi
if [ "$PLATFORM" = "M0197" ]; then
chown fastrpc:fastrpc /data/px4/slpi
else
chown system:system /data/px4/slpi
fi
################################################################################
# DSP test signature
################################################################################
SIG_SCRIPT_DIR=/share/modalai/qrb5165-slpi-test-sig
if [ "$PLATFORM" = "M0197" ]; then
SIG_SCRIPT_DIR=/share/modalai/qcs6490-slpi-test-sig
fi
if /bin/ls /usr/lib/rfsa/adsp/testsig-*.so &>/dev/null; then
echo "Found DSP signature file"
else
echo "DSP signature file not found"
if [ -f "$SIG_SCRIPT_DIR/generate-test-sig.sh" ]; then
echo "Generating DSP signature..."
"$SIG_SCRIPT_DIR/generate-test-sig.sh"
else
echo "Warning: DSP signature generation script not found at $SIG_SCRIPT_DIR"
fi
fi
################################################################################
# Cleanup and reload
################################################################################
# Remove legacy config file
rm -f /etc/modalai/voxl-px4.config
sync
# Reload systemd if available
set +e
if [ -f /bin/systemctl ]; then
systemctl daemon-reload
fi
exit 0

View File

@ -0,0 +1,13 @@
[Unit]
Description=px4
After=sscrpcd.service
Requires=sscrpcd.service
[Service]
ExecStartPre=/bin/sleep 2
ExecStart=/usr/bin/voxl-px4
ExecStopPost=/usr/bin/voxl-reset-slpi
Restart=on-failure
[Install]
WantedBy=multi-user.target