mirror of
https://github.com/PX4/PX4-Autopilot.git
synced 2026-03-23 10:03:41 +08:00
feat(boards/modalai/voxl2): add Debian packaging framework
Add a scalable .deb packaging framework for VOXL2, built on the existing cmake/package.cmake CPack infrastructure. The framework handles multi-processor boards by having the POSIX (_default) build own the .deb and pull in the companion SLPI build's artifacts. Board-specific files: - cmake/package.cmake: CPack variable overrides (name, deps, version) - cmake/install.cmake: install() rules for all .deb contents - debian/postinst: px4-* symlinks, DSP signature, directory setup - debian/prerm: service stop, symlink cleanup - debian/voxl-px4.service: systemd unit (after sscrpcd) Infrastructure changes: - cmake/package.cmake: hook for board-specific CPack overrides - platforms/posix/CMakeLists.txt: hook for board install.cmake - Makefile: %_deb pattern rule (build _default, then cpack -G DEB) - CI: auto-discover _deb targets, collect .deb artifacts, upload to GitHub Releases Future boards: add cmake/package.cmake + cmake/install.cmake and CI discovers it automatically. No new file formats or tools needed. Signed-off-by: Ramon Roche <mrpollo@gmail.com>
This commit is contained in:
4
.github/workflows/build_all_targets.yml
vendored
4
.github/workflows/build_all_targets.yml
vendored
@@ -265,5 +265,7 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
draft: true
|
draft: true
|
||||||
prerelease: ${{ steps.upload-location.outputs.is_prerelease == 'true' }}
|
prerelease: ${{ steps.upload-location.outputs.is_prerelease == 'true' }}
|
||||||
files: artifacts/*.px4
|
files: |
|
||||||
|
artifacts/*.px4
|
||||||
|
artifacts/*.deb
|
||||||
name: ${{ steps.upload-location.outputs.uploadlocation }}
|
name: ${{ steps.upload-location.outputs.uploadlocation }}
|
||||||
|
|||||||
7
Makefile
7
Makefile
@@ -234,6 +234,13 @@ modalai_voxl2: modalai_voxl2_slpi
|
|||||||
all_config_targets: $(ALL_CONFIG_TARGETS)
|
all_config_targets: $(ALL_CONFIG_TARGETS)
|
||||||
all_default_targets: $(CONFIG_TARGETS_DEFAULT)
|
all_default_targets: $(CONFIG_TARGETS_DEFAULT)
|
||||||
|
|
||||||
|
# DEB package targets: builds _default config, then runs cpack.
|
||||||
|
# Multi-processor boards (e.g. VOXL2) chain companion builds automatically
|
||||||
|
# via existing cmake prerequisites.
|
||||||
|
%_deb:
|
||||||
|
@$(call cmake-build,$(subst _deb,_default,$@)$(BUILD_DIR_SUFFIX))
|
||||||
|
@cd "$(SRC_DIR)/build/$(subst _deb,_default,$@)" && cpack -G DEB
|
||||||
|
|
||||||
updateconfig:
|
updateconfig:
|
||||||
@./Tools/kconfig/updateconfig.py
|
@./Tools/kconfig/updateconfig.py
|
||||||
|
|
||||||
|
|||||||
@@ -207,6 +207,47 @@ for manufacturer in sorted(os.scandir(os.path.join(source_dir, '../boards')), ke
|
|||||||
if t not in companions
|
if t not in companions
|
||||||
]
|
]
|
||||||
|
|
||||||
|
# Append _deb targets for boards that have cmake/package.cmake
|
||||||
|
for manufacturer in sorted(os.scandir(os.path.join(source_dir, '../boards')), key=lambda e: e.name):
|
||||||
|
if not manufacturer.is_dir():
|
||||||
|
continue
|
||||||
|
if manufacturer.name in excluded_manufacturers:
|
||||||
|
continue
|
||||||
|
for board in sorted(os.scandir(manufacturer.path), key=lambda e: e.name):
|
||||||
|
if not board.is_dir():
|
||||||
|
continue
|
||||||
|
board_name = manufacturer.name + '_' + board.name
|
||||||
|
if board_name in excluded_boards:
|
||||||
|
continue
|
||||||
|
package_cmake = os.path.join(board.path, 'cmake', 'package.cmake')
|
||||||
|
if os.path.exists(package_cmake):
|
||||||
|
deb_target = board_name + '_deb'
|
||||||
|
if target_filter and not any(deb_target.startswith(f) for f in target_filter):
|
||||||
|
continue
|
||||||
|
# Determine the container and group for this board
|
||||||
|
container = default_container
|
||||||
|
if board_name in board_container_overrides:
|
||||||
|
container = board_container_overrides[board_name]
|
||||||
|
target_entry = {'target': deb_target, 'container': container}
|
||||||
|
if args.group:
|
||||||
|
# Find the group where this board's _default target already lives
|
||||||
|
default_target = board_name + '_default'
|
||||||
|
group = None
|
||||||
|
for g in grouped_targets:
|
||||||
|
targets_in_group = grouped_targets[g].get('manufacturers', {}).get(manufacturer.name, [])
|
||||||
|
if default_target in targets_in_group:
|
||||||
|
group = g
|
||||||
|
break
|
||||||
|
if group is None:
|
||||||
|
group = 'base'
|
||||||
|
target_entry['arch'] = group
|
||||||
|
if group not in grouped_targets:
|
||||||
|
grouped_targets[group] = {'container': container, 'manufacturers': {}}
|
||||||
|
if manufacturer.name not in grouped_targets[group]['manufacturers']:
|
||||||
|
grouped_targets[group]['manufacturers'][manufacturer.name] = []
|
||||||
|
grouped_targets[group]['manufacturers'][manufacturer.name].append(deb_target)
|
||||||
|
build_configs.append(target_entry)
|
||||||
|
|
||||||
if(verbose):
|
if(verbose):
|
||||||
import pprint
|
import pprint
|
||||||
print("============================")
|
print("============================")
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
mkdir artifacts
|
mkdir artifacts
|
||||||
cp **/**/*.px4 artifacts/ 2>/dev/null || true
|
cp **/**/*.px4 artifacts/ 2>/dev/null || true
|
||||||
cp **/**/*.elf artifacts/ 2>/dev/null || true
|
cp **/**/*.elf artifacts/ 2>/dev/null || true
|
||||||
|
cp **/**/*.deb artifacts/ 2>/dev/null || true
|
||||||
for build_dir_path in build/*/ ; do
|
for build_dir_path in build/*/ ; do
|
||||||
build_dir_path=${build_dir_path::${#build_dir_path}-1}
|
build_dir_path=${build_dir_path::${#build_dir_path}-1}
|
||||||
build_dir=${build_dir_path#*/}
|
build_dir=${build_dir_path#*/}
|
||||||
|
|||||||
84
boards/modalai/voxl2/cmake/install.cmake
Normal file
84
boards/modalai/voxl2/cmake/install.cmake
Normal file
@@ -0,0 +1,84 @@
|
|||||||
|
############################################################################
|
||||||
|
#
|
||||||
|
# Copyright (c) 2024 PX4 Development Team. All rights reserved.
|
||||||
|
#
|
||||||
|
# Redistribution and use in source and binary forms, with or without
|
||||||
|
# modification, are permitted provided that the following conditions
|
||||||
|
# are met:
|
||||||
|
#
|
||||||
|
# 1. Redistributions of source code must retain the above copyright
|
||||||
|
# notice, this list of conditions and the following disclaimer.
|
||||||
|
# 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
# notice, this list of conditions and the following disclaimer in
|
||||||
|
# the documentation and/or other materials provided with the
|
||||||
|
# distribution.
|
||||||
|
# 3. Neither the name PX4 nor the names of its contributors may be
|
||||||
|
# used to endorse or promote products derived from this software
|
||||||
|
# without specific prior written permission.
|
||||||
|
#
|
||||||
|
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||||
|
# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
|
# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
|
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||||
|
# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||||
|
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||||
|
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
# POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
#
|
||||||
|
############################################################################
|
||||||
|
|
||||||
|
# VOXL2 board-specific install rules for .deb packaging
|
||||||
|
# Included from platforms/posix/CMakeLists.txt where the px4 target exists
|
||||||
|
|
||||||
|
# SLPI companion build output directory
|
||||||
|
set(VOXL2_SLPI_BUILD_DIR "${PX4_SOURCE_DIR}/build/modalai_voxl2-slpi_default")
|
||||||
|
|
||||||
|
# Apps processor binary
|
||||||
|
install(TARGETS px4 RUNTIME DESTINATION bin)
|
||||||
|
|
||||||
|
# px4-alias.sh (generated during build into bin/ subdirectory)
|
||||||
|
install(PROGRAMS ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/px4-alias.sh DESTINATION bin)
|
||||||
|
|
||||||
|
# Startup scripts from board target directory
|
||||||
|
install(PROGRAMS
|
||||||
|
${PX4_BOARD_DIR}/target/voxl-px4
|
||||||
|
${PX4_BOARD_DIR}/target/voxl-px4-start
|
||||||
|
${PX4_BOARD_DIR}/target/voxl-px4-hitl
|
||||||
|
${PX4_BOARD_DIR}/target/voxl-px4-hitl-start
|
||||||
|
DESTINATION bin
|
||||||
|
)
|
||||||
|
|
||||||
|
# DSP firmware blob from companion SLPI build
|
||||||
|
install(FILES ${VOXL2_SLPI_BUILD_DIR}/platforms/qurt/libpx4.so
|
||||||
|
DESTINATION lib/rfsa/adsp
|
||||||
|
OPTIONAL
|
||||||
|
)
|
||||||
|
|
||||||
|
# Configuration files
|
||||||
|
install(FILES
|
||||||
|
${PX4_BOARD_DIR}/target/voxl-px4-fake-imu-calibration.config
|
||||||
|
${PX4_BOARD_DIR}/target/voxl-px4-hitl-set-default-parameters.config
|
||||||
|
DESTINATION ../etc/modalai
|
||||||
|
)
|
||||||
|
|
||||||
|
# Systemd service file
|
||||||
|
install(FILES ${PX4_BOARD_DIR}/debian/voxl-px4.service
|
||||||
|
DESTINATION ../etc/systemd/system
|
||||||
|
)
|
||||||
|
|
||||||
|
# Component metadata JSON files
|
||||||
|
install(FILES
|
||||||
|
${PX4_BINARY_DIR}/actuators.json.xz
|
||||||
|
${PX4_BINARY_DIR}/component_general.json.xz
|
||||||
|
${PX4_BINARY_DIR}/parameters.json.xz
|
||||||
|
DESTINATION ../data/px4/etc/extras
|
||||||
|
OPTIONAL
|
||||||
|
)
|
||||||
|
install(FILES ${PX4_BINARY_DIR}/events/all_events.json.xz
|
||||||
|
DESTINATION ../data/px4/etc/extras
|
||||||
|
OPTIONAL
|
||||||
|
)
|
||||||
63
boards/modalai/voxl2/cmake/package.cmake
Normal file
63
boards/modalai/voxl2/cmake/package.cmake
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
############################################################################
|
||||||
|
#
|
||||||
|
# Copyright (c) 2024 PX4 Development Team. All rights reserved.
|
||||||
|
#
|
||||||
|
# Redistribution and use in source and binary forms, with or without
|
||||||
|
# modification, are permitted provided that the following conditions
|
||||||
|
# are met:
|
||||||
|
#
|
||||||
|
# 1. Redistributions of source code must retain the above copyright
|
||||||
|
# notice, this list of conditions and the following disclaimer.
|
||||||
|
# 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
# notice, this list of conditions and the following disclaimer in
|
||||||
|
# the documentation and/or other materials provided with the
|
||||||
|
# distribution.
|
||||||
|
# 3. Neither the name PX4 nor the names of its contributors may be
|
||||||
|
# used to endorse or promote products derived from this software
|
||||||
|
# without specific prior written permission.
|
||||||
|
#
|
||||||
|
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||||
|
# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
|
# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
|
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||||
|
# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||||
|
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||||
|
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
# POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
#
|
||||||
|
############################################################################
|
||||||
|
|
||||||
|
# VOXL2 board-specific CPack overrides
|
||||||
|
# Loaded after cmake/package.cmake sets up CPack defaults
|
||||||
|
|
||||||
|
# Derive Debian-compatible version from git tag (e.g. v1.17.0-alpha1-42-gabcdef -> 1.17.0~alpha1.42.gabcdef)
|
||||||
|
string(REGEX REPLACE "^v" "" _deb_ver "${PX4_GIT_TAG}")
|
||||||
|
string(REGEX REPLACE "-" "~" _deb_ver "${_deb_ver}" )
|
||||||
|
string(REGEX REPLACE "~([0-9]+)~" ".\\1." _deb_ver "${_deb_ver}")
|
||||||
|
|
||||||
|
# VOXL2 is always aarch64 regardless of build host
|
||||||
|
set(CPACK_DEBIAN_ARCHITECTURE "arm64")
|
||||||
|
set(CPACK_DEBIAN_PACKAGE_NAME "voxl-px4")
|
||||||
|
set(CPACK_DEBIAN_FILE_NAME "voxl-px4_${_deb_ver}_arm64.deb")
|
||||||
|
set(CPACK_PACKAGING_INSTALL_PREFIX "/usr")
|
||||||
|
set(CPACK_INSTALL_PREFIX "/usr")
|
||||||
|
set(CPACK_SET_DESTDIR true)
|
||||||
|
|
||||||
|
set(CPACK_DEBIAN_PACKAGE_DEPENDS "voxl-platform, librc-symlinks")
|
||||||
|
set(CPACK_DEBIAN_PACKAGE_CONFLICTS "px4-rb5-flight")
|
||||||
|
set(CPACK_DEBIAN_PACKAGE_REPLACES "px4-rb5-flight")
|
||||||
|
set(CPACK_DEBIAN_PACKAGE_DESCRIPTION "PX4 Autopilot for ModalAI VOXL2")
|
||||||
|
set(CPACK_DEBIAN_PACKAGE_MAINTAINER "ModalAI <support@modalai.com>")
|
||||||
|
|
||||||
|
# Disable shlibdeps for cross-compiled boards
|
||||||
|
set(CPACK_DEBIAN_PACKAGE_SHLIBDEPS OFF)
|
||||||
|
|
||||||
|
set(CPACK_DEBIAN_PACKAGE_CONTROL_EXTRA
|
||||||
|
"${PX4_BOARD_DIR}/debian/postinst;${PX4_BOARD_DIR}/debian/prerm")
|
||||||
|
|
||||||
|
# Install rules are in boards/modalai/voxl2/cmake/install.cmake,
|
||||||
|
# included from platforms/posix/CMakeLists.txt where the px4 target exists.
|
||||||
36
boards/modalai/voxl2/debian/postinst
Executable file
36
boards/modalai/voxl2/debian/postinst
Executable file
@@ -0,0 +1,36 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
set -e
|
||||||
|
|
||||||
|
# Create px4-* symlinks from px4-alias.sh
|
||||||
|
# The alias format is: alias <module>='px4-<module> --instance $px4_instance'
|
||||||
|
# We extract the px4-<module> command name and symlink it to the px4 binary
|
||||||
|
if [ -f /usr/bin/px4-alias.sh ]; then
|
||||||
|
grep "^alias " /usr/bin/px4-alias.sh | \
|
||||||
|
sed -n "s/.*'\(px4-[a-zA-Z0-9_]*\).*/\1/p" | while read cmd; do
|
||||||
|
ln -sf px4 "/usr/bin/${cmd}"
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Detect platform and generate DSP test signature if needed
|
||||||
|
if ! /bin/ls /usr/lib/rfsa/adsp/testsig-*.so &> /dev/null; then
|
||||||
|
echo "[INFO] Generating DSP test signature..."
|
||||||
|
if [ -f /share/modalai/qcs6490-slpi-test-sig/generate-test-sig.sh ]; then
|
||||||
|
/share/modalai/qcs6490-slpi-test-sig/generate-test-sig.sh || true
|
||||||
|
elif [ -f /share/modalai/qrb5165-slpi-test-sig/generate-test-sig.sh ]; then
|
||||||
|
/share/modalai/qrb5165-slpi-test-sig/generate-test-sig.sh || true
|
||||||
|
else
|
||||||
|
echo "[WARNING] Could not find DSP signature generation script"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Create required data directories
|
||||||
|
mkdir -p /data/px4/param
|
||||||
|
mkdir -p /data/px4/etc/extras
|
||||||
|
chown -R root:root /data/px4
|
||||||
|
|
||||||
|
# Reload systemd if available
|
||||||
|
if command -v systemctl > /dev/null 2>&1; then
|
||||||
|
systemctl daemon-reload
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "voxl-px4 installed successfully"
|
||||||
14
boards/modalai/voxl2/debian/prerm
Executable file
14
boards/modalai/voxl2/debian/prerm
Executable file
@@ -0,0 +1,14 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
set -e
|
||||||
|
|
||||||
|
# Stop voxl-px4 service if running
|
||||||
|
if command -v systemctl > /dev/null 2>&1; then
|
||||||
|
systemctl stop voxl-px4 2>/dev/null || true
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Remove px4-* symlinks
|
||||||
|
for f in /usr/bin/px4-*; do
|
||||||
|
if [ -L "$f" ] && [ "$(readlink "$f")" = "px4" ]; then
|
||||||
|
rm -f "$f"
|
||||||
|
fi
|
||||||
|
done
|
||||||
14
boards/modalai/voxl2/debian/voxl-px4.service
Normal file
14
boards/modalai/voxl2/debian/voxl-px4.service
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
[Unit]
|
||||||
|
Description=PX4 Autopilot for VOXL2
|
||||||
|
After=sscrpcd.service
|
||||||
|
Requires=sscrpcd.service
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=simple
|
||||||
|
ExecStart=/usr/bin/voxl-px4
|
||||||
|
ExecStopPost=/usr/bin/voxl-reset-slpi
|
||||||
|
Restart=on-failure
|
||||||
|
RestartSec=5
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
@@ -97,4 +97,9 @@ else()
|
|||||||
set(CPACK_GENERATOR "ZIP")
|
set(CPACK_GENERATOR "ZIP")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
# Board-specific overrides (loaded after defaults are set)
|
||||||
|
if(EXISTS "${PX4_BOARD_DIR}/cmake/package.cmake")
|
||||||
|
include(${PX4_BOARD_DIR}/cmake/package.cmake)
|
||||||
|
endif()
|
||||||
|
|
||||||
include(CPack)
|
include(CPack)
|
||||||
|
|||||||
@@ -476,6 +476,7 @@
|
|||||||
- [Flight Controller Porting Guide](hardware/porting_guide.md)
|
- [Flight Controller Porting Guide](hardware/porting_guide.md)
|
||||||
- [PX4 Board Configuration (kconfig)](hardware/porting_guide_config.md)
|
- [PX4 Board Configuration (kconfig)](hardware/porting_guide_config.md)
|
||||||
- [NuttX Board Porting Guide](hardware/porting_guide_nuttx.md)
|
- [NuttX Board Porting Guide](hardware/porting_guide_nuttx.md)
|
||||||
|
- [Board Firmware Packaging (.deb)](hardware/board_packaging.md)
|
||||||
- [Serial Port Mapping](hardware/serial_port_mapping.md)
|
- [Serial Port Mapping](hardware/serial_port_mapping.md)
|
||||||
- [Airframes](dev_airframes/index.md)
|
- [Airframes](dev_airframes/index.md)
|
||||||
- [Adding a New Airframe](dev_airframes/adding_a_new_frame.md)
|
- [Adding a New Airframe](dev_airframes/adding_a_new_frame.md)
|
||||||
|
|||||||
298
docs/en/hardware/board_packaging.md
Normal file
298
docs/en/hardware/board_packaging.md
Normal file
@@ -0,0 +1,298 @@
|
|||||||
|
# Board Firmware Packaging
|
||||||
|
|
||||||
|
PX4 supports building distributable firmware packages for Linux-based (POSIX) boards.
|
||||||
|
While NuttX boards produce `.px4` firmware files that are flashed via QGroundControl, POSIX boards can produce `.deb` (Debian) packages that are installed using standard Linux package management tools (`dpkg`, `apt`).
|
||||||
|
|
||||||
|
This page covers how manufacturers can add `.deb` packaging to their boards, with examples for both single-processor and multi-processor architectures.
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
The packaging framework uses [CMake CPack](https://cmake.org/cmake/help/latest/module/CPack.html) with the DEB generator.
|
||||||
|
It is built on two extension points in the PX4 build system:
|
||||||
|
|
||||||
|
- **`boards/<vendor>/<board>/cmake/package.cmake`**: CPack variable overrides (package name, version, dependencies, architecture, maintainer info). Loaded during CMake configure.
|
||||||
|
- **`boards/<vendor>/<board>/cmake/install.cmake`**: `install()` rules that define what goes into the package (binaries, scripts, config files, service files). Loaded from `platforms/posix/CMakeLists.txt` where build targets are available.
|
||||||
|
|
||||||
|
When a board provides these files, CI automatically discovers and builds the `_deb` target alongside the normal firmware build.
|
||||||
|
|
||||||
|
## Build Command
|
||||||
|
|
||||||
|
For any board with packaging support:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
make <vendor>_<board>_deb
|
||||||
|
```
|
||||||
|
|
||||||
|
For example:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
make modalai_voxl2_deb
|
||||||
|
```
|
||||||
|
|
||||||
|
This builds the `_default` configuration (and any companion builds for multi-processor boards), then runs `cpack -G DEB` in the build directory.
|
||||||
|
The resulting `.deb` file is placed in `build/<vendor>_<board>_default/`.
|
||||||
|
|
||||||
|
## Adding Packaging to a Board
|
||||||
|
|
||||||
|
### File Structure
|
||||||
|
|
||||||
|
```
|
||||||
|
boards/<vendor>/<board>/
|
||||||
|
cmake/
|
||||||
|
package.cmake # CPack configuration (required)
|
||||||
|
install.cmake # Install rules (required)
|
||||||
|
debian/
|
||||||
|
postinst # Post-install script (optional)
|
||||||
|
prerm # Pre-remove script (optional)
|
||||||
|
<name>.service # Systemd unit file (optional)
|
||||||
|
```
|
||||||
|
|
||||||
|
### Step 1: CPack Configuration (package.cmake)
|
||||||
|
|
||||||
|
This file sets CPack variables that control the `.deb` metadata.
|
||||||
|
It is included from `cmake/package.cmake` after the base CPack defaults are configured.
|
||||||
|
|
||||||
|
```cmake
|
||||||
|
# boards/<vendor>/<board>/cmake/package.cmake
|
||||||
|
|
||||||
|
# Derive Debian-compatible version from git tag
|
||||||
|
# v1.17.0-alpha1-42-gabcdef -> 1.17.0~alpha1.42.gabcdef
|
||||||
|
# v1.17.0 -> 1.17.0
|
||||||
|
string(REGEX REPLACE "^v" "" _deb_ver "${PX4_GIT_TAG}")
|
||||||
|
string(REGEX REPLACE "-" "~" _deb_ver "${_deb_ver}")
|
||||||
|
string(REGEX REPLACE "~([0-9]+)~" ".\\1." _deb_ver "${_deb_ver}")
|
||||||
|
|
||||||
|
# Target architecture (use the target arch, not the build host)
|
||||||
|
set(CPACK_DEBIAN_ARCHITECTURE "arm64")
|
||||||
|
|
||||||
|
# Package identity
|
||||||
|
set(CPACK_DEBIAN_PACKAGE_NAME "my-px4-board")
|
||||||
|
set(CPACK_DEBIAN_FILE_NAME "my-px4-board_${_deb_ver}_arm64.deb")
|
||||||
|
|
||||||
|
# Install prefix
|
||||||
|
set(CPACK_PACKAGING_INSTALL_PREFIX "/usr")
|
||||||
|
set(CPACK_INSTALL_PREFIX "/usr")
|
||||||
|
set(CPACK_SET_DESTDIR true)
|
||||||
|
|
||||||
|
# Package metadata
|
||||||
|
set(CPACK_DEBIAN_PACKAGE_DESCRIPTION "PX4 Autopilot for My Board")
|
||||||
|
set(CPACK_DEBIAN_PACKAGE_MAINTAINER "Vendor <support@vendor.com>")
|
||||||
|
set(CPACK_DEBIAN_PACKAGE_DEPENDS "some-dependency (>= 1.0)")
|
||||||
|
set(CPACK_DEBIAN_PACKAGE_CONFLICTS "")
|
||||||
|
set(CPACK_DEBIAN_PACKAGE_REPLACES "")
|
||||||
|
|
||||||
|
# Disable shlibdeps for cross-compiled boards
|
||||||
|
set(CPACK_DEBIAN_PACKAGE_SHLIBDEPS OFF)
|
||||||
|
|
||||||
|
# Include post-install and pre-remove scripts (optional)
|
||||||
|
set(CPACK_DEBIAN_PACKAGE_CONTROL_EXTRA
|
||||||
|
"${PX4_BOARD_DIR}/debian/postinst;${PX4_BOARD_DIR}/debian/prerm")
|
||||||
|
```
|
||||||
|
|
||||||
|
**Key variables:**
|
||||||
|
|
||||||
|
| Variable | Purpose |
|
||||||
|
|---|---|
|
||||||
|
| `CPACK_DEBIAN_ARCHITECTURE` | Target architecture. Set explicitly for cross-compiled boards since `dpkg --print-architecture` reports the build host, not the target. |
|
||||||
|
| `CPACK_DEBIAN_PACKAGE_NAME` | Package name as it appears in `dpkg -l`. |
|
||||||
|
| `CPACK_DEBIAN_FILE_NAME` | Output `.deb` filename. |
|
||||||
|
| `CPACK_DEBIAN_PACKAGE_DEPENDS` | Runtime dependencies (comma-separated, Debian format). |
|
||||||
|
| `CPACK_DEBIAN_PACKAGE_SHLIBDEPS` | Set to `OFF` for cross-compiled boards where `dpkg-shlibdeps` cannot inspect target binaries. |
|
||||||
|
|
||||||
|
### Step 2: Install Rules (install.cmake)
|
||||||
|
|
||||||
|
This file defines what files are packaged in the `.deb`.
|
||||||
|
It is included from `platforms/posix/CMakeLists.txt` where the `px4` build target is available.
|
||||||
|
|
||||||
|
All paths are relative to `CPACK_PACKAGING_INSTALL_PREFIX` (typically `/usr`). Use `../` to install outside the prefix (e.g., `../etc/` installs to `/etc/`).
|
||||||
|
|
||||||
|
**Minimal example (single-processor board):**
|
||||||
|
|
||||||
|
```cmake
|
||||||
|
# boards/<vendor>/<board>/cmake/install.cmake
|
||||||
|
|
||||||
|
# PX4 binary
|
||||||
|
install(TARGETS px4 RUNTIME DESTINATION bin)
|
||||||
|
|
||||||
|
# Module alias script (generated during build)
|
||||||
|
install(PROGRAMS ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/px4-alias.sh DESTINATION bin)
|
||||||
|
|
||||||
|
# Startup scripts
|
||||||
|
install(PROGRAMS
|
||||||
|
${PX4_BOARD_DIR}/target/my-px4-start
|
||||||
|
DESTINATION bin
|
||||||
|
)
|
||||||
|
|
||||||
|
# Configuration files
|
||||||
|
install(FILES
|
||||||
|
${PX4_BOARD_DIR}/target/my-config.conf
|
||||||
|
DESTINATION ../etc/my-board
|
||||||
|
)
|
||||||
|
|
||||||
|
# Systemd service
|
||||||
|
install(FILES ${PX4_BOARD_DIR}/debian/my-px4.service
|
||||||
|
DESTINATION ../etc/systemd/system
|
||||||
|
)
|
||||||
|
|
||||||
|
# Component metadata
|
||||||
|
install(FILES
|
||||||
|
${PX4_BINARY_DIR}/actuators.json.xz
|
||||||
|
${PX4_BINARY_DIR}/parameters.json.xz
|
||||||
|
DESTINATION ../data/px4/etc/extras
|
||||||
|
OPTIONAL
|
||||||
|
)
|
||||||
|
install(FILES ${PX4_BINARY_DIR}/events/all_events.json.xz
|
||||||
|
DESTINATION ../data/px4/etc/extras
|
||||||
|
OPTIONAL
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
### Step 3: Debian Scripts (optional)
|
||||||
|
|
||||||
|
#### postinst
|
||||||
|
|
||||||
|
Runs after the package is installed. Common tasks:
|
||||||
|
|
||||||
|
- Create `px4-*` module symlinks from `px4-alias.sh`
|
||||||
|
- Set up required directories with correct ownership
|
||||||
|
- Run `systemctl daemon-reload` to pick up the service file
|
||||||
|
- Board-specific setup (e.g., DSP signature generation)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
#!/bin/bash
|
||||||
|
set -e
|
||||||
|
|
||||||
|
# Create px4-* symlinks
|
||||||
|
if [ -f /usr/bin/px4-alias.sh ]; then
|
||||||
|
grep "^alias " /usr/bin/px4-alias.sh | \
|
||||||
|
sed "s/alias \(px4-[a-zA-Z0-9_]*\)=.*/\1/" | while read cmd; do
|
||||||
|
ln -sf px4 "/usr/bin/${cmd}"
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Create data directories
|
||||||
|
mkdir -p /data/px4/param
|
||||||
|
mkdir -p /data/px4/etc/extras
|
||||||
|
|
||||||
|
# Reload systemd
|
||||||
|
if command -v systemctl > /dev/null 2>&1; then
|
||||||
|
systemctl daemon-reload
|
||||||
|
fi
|
||||||
|
```
|
||||||
|
|
||||||
|
#### prerm
|
||||||
|
|
||||||
|
Runs before the package is removed:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
#!/bin/bash
|
||||||
|
set -e
|
||||||
|
|
||||||
|
# Stop the service
|
||||||
|
if command -v systemctl > /dev/null 2>&1; then
|
||||||
|
systemctl stop my-px4 2>/dev/null || true
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Remove px4-* symlinks
|
||||||
|
for f in /usr/bin/px4-*; do
|
||||||
|
if [ -L "$f" ] && [ "$(readlink "$f")" = "px4" ]; then
|
||||||
|
rm -f "$f"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
```
|
||||||
|
|
||||||
|
Both scripts must be executable (`chmod +x`).
|
||||||
|
|
||||||
|
## Multi-Processor Boards
|
||||||
|
|
||||||
|
Some boards run PX4 across multiple processors, for example the ModalAI VOXL2 which has a POSIX apps processor (ARM) and a Hexagon DSP (SLPI).
|
||||||
|
These produce two separate CMake builds, but the `.deb` must contain artifacts from both.
|
||||||
|
|
||||||
|
### How It Works
|
||||||
|
|
||||||
|
1. The `_default` build (POSIX/apps processor) owns the `.deb`.
|
||||||
|
2. The Makefile `%_deb` target builds `_default`, which chains any companion builds as CMake prerequisites.
|
||||||
|
3. The `install.cmake` pulls companion build artifacts via absolute path to the sibling build directory.
|
||||||
|
4. CPack runs in the `_default` build tree and produces a single `.deb`.
|
||||||
|
|
||||||
|
### Companion Build Artifacts
|
||||||
|
|
||||||
|
In `install.cmake`, reference the companion build output by absolute path:
|
||||||
|
|
||||||
|
```cmake
|
||||||
|
# DSP firmware blob from companion SLPI build
|
||||||
|
set(SLPI_BUILD_DIR "${PX4_SOURCE_DIR}/build/<vendor>_<board>-slpi_default")
|
||||||
|
|
||||||
|
install(FILES ${SLPI_BUILD_DIR}/platforms/qurt/libpx4.so
|
||||||
|
DESTINATION lib/rfsa/adsp
|
||||||
|
OPTIONAL
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
The `OPTIONAL` keyword allows the `.deb` to build even when the companion build hasn't run (useful for development/testing of just the apps-processor side).
|
||||||
|
|
||||||
|
### VOXL2 Reference
|
||||||
|
|
||||||
|
The VOXL2 board is a complete working example of multi-processor packaging:
|
||||||
|
|
||||||
|
```
|
||||||
|
boards/modalai/voxl2/
|
||||||
|
cmake/
|
||||||
|
package.cmake # CPack config: voxl-px4, arm64, deps, shlibdeps off
|
||||||
|
install.cmake # px4 binary, SLPI libpx4.so, scripts, configs, metadata
|
||||||
|
debian/
|
||||||
|
postinst # Symlinks, DSP signature, directory setup
|
||||||
|
prerm # Stop service, remove symlinks
|
||||||
|
voxl-px4.service # Systemd unit (after sscrpcd, restart on-failure)
|
||||||
|
target/
|
||||||
|
voxl-px4 # Main startup wrapper
|
||||||
|
voxl-px4-start # PX4 module startup script
|
||||||
|
```
|
||||||
|
|
||||||
|
The resulting `.deb` installs:
|
||||||
|
|
||||||
|
| Path | Contents |
|
||||||
|
|---|---|
|
||||||
|
| `/usr/bin/px4` | Apps processor PX4 binary |
|
||||||
|
| `/usr/bin/px4-alias.sh` | Module alias script |
|
||||||
|
| `/usr/bin/voxl-px4` | Startup wrapper |
|
||||||
|
| `/usr/bin/voxl-px4-start` | Module startup script |
|
||||||
|
| `/usr/lib/rfsa/adsp/libpx4.so` | DSP firmware (from SLPI build) |
|
||||||
|
| `/etc/modalai/*.config` | Board configuration files |
|
||||||
|
| `/etc/systemd/system/voxl-px4.service` | Systemd service |
|
||||||
|
| `/data/px4/etc/extras/*.json.xz` | Component metadata |
|
||||||
|
|
||||||
|
## CI Integration
|
||||||
|
|
||||||
|
### Automatic Discovery
|
||||||
|
|
||||||
|
The CI system (`Tools/ci/generate_board_targets_json.py`) automatically discovers boards with `cmake/package.cmake` and adds a `<vendor>_<board>_deb` target to the board's existing CI group.
|
||||||
|
No manual CI configuration is needed.
|
||||||
|
|
||||||
|
### Artifact Collection
|
||||||
|
|
||||||
|
The `Tools/ci/package_build_artifacts.sh` script collects `.deb` files alongside `.px4` and `.elf` artifacts.
|
||||||
|
On tagged releases, `.deb` files are uploaded to both S3 and GitHub Releases.
|
||||||
|
|
||||||
|
## Version Format
|
||||||
|
|
||||||
|
The `.deb` version is derived from `PX4_GIT_TAG` using Debian-compatible formatting:
|
||||||
|
|
||||||
|
| Git Tag | Debian Version | Notes |
|
||||||
|
|---|---|---|
|
||||||
|
| `v1.17.0` | `1.17.0` | Stable release |
|
||||||
|
| `v1.17.0-beta1` | `1.17.0~beta1` | Pre-release (`~` sorts before release) |
|
||||||
|
| `v1.17.0-alpha1-42-gabcdef` | `1.17.0~alpha1.42.gabcdef` | Development build |
|
||||||
|
|
||||||
|
The `~` prefix in Debian versioning ensures pre-releases sort lower than the final release: `1.17.0~beta1 < 1.17.0`.
|
||||||
|
|
||||||
|
## Checklist for New Boards
|
||||||
|
|
||||||
|
1. Create `boards/<vendor>/<board>/cmake/package.cmake` with CPack variables
|
||||||
|
2. Create `boards/<vendor>/<board>/cmake/install.cmake` with install rules
|
||||||
|
3. (Optional) Create `boards/<vendor>/<board>/debian/postinst` and `prerm`
|
||||||
|
4. (Optional) Create `boards/<vendor>/<board>/debian/<name>.service`
|
||||||
|
5. Test locally: `make <vendor>_<board>_deb`
|
||||||
|
6. Verify: `dpkg-deb --info build/<vendor>_<board>_default/<name>_*.deb`
|
||||||
|
7. Verify: `dpkg-deb --contents build/<vendor>_<board>_default/<name>_*.deb`
|
||||||
|
8. CI picks it up automatically on the next push
|
||||||
@@ -80,7 +80,8 @@ target_link_libraries(px4 PRIVATE uORB)
|
|||||||
# install
|
# install
|
||||||
#
|
#
|
||||||
|
|
||||||
# TODO: extend to snapdragon
|
# Generic install rules (skipped when board provides its own install.cmake)
|
||||||
|
if(NOT EXISTS "${PX4_BOARD_DIR}/cmake/install.cmake")
|
||||||
|
|
||||||
# px4 dirs
|
# px4 dirs
|
||||||
install(
|
install(
|
||||||
@@ -94,6 +95,8 @@ install(
|
|||||||
USE_SOURCE_PERMISSIONS
|
USE_SOURCE_PERMISSIONS
|
||||||
)
|
)
|
||||||
|
|
||||||
|
endif() # NOT board install.cmake
|
||||||
|
|
||||||
# Module Symlinks
|
# Module Symlinks
|
||||||
px4_posix_generate_symlinks(
|
px4_posix_generate_symlinks(
|
||||||
MODULE_LIST ${module_libraries}
|
MODULE_LIST ${module_libraries}
|
||||||
@@ -112,6 +115,11 @@ if(EXISTS "${PX4_BOARD_DIR}/cmake/upload.cmake")
|
|||||||
include(${PX4_BOARD_DIR}/cmake/upload.cmake)
|
include(${PX4_BOARD_DIR}/cmake/upload.cmake)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
# board defined install rules for .deb packaging
|
||||||
|
if(EXISTS "${PX4_BOARD_DIR}/cmake/install.cmake")
|
||||||
|
include(${PX4_BOARD_DIR}/cmake/install.cmake)
|
||||||
|
endif()
|
||||||
|
|
||||||
# board defined link libraries
|
# board defined link libraries
|
||||||
if(EXISTS "${PX4_BOARD_DIR}/cmake/link_libraries.cmake")
|
if(EXISTS "${PX4_BOARD_DIR}/cmake/link_libraries.cmake")
|
||||||
include(${PX4_BOARD_DIR}/cmake/link_libraries.cmake)
|
include(${PX4_BOARD_DIR}/cmake/link_libraries.cmake)
|
||||||
|
|||||||
Reference in New Issue
Block a user