This repository builds and distributes Debian packages for the PiTrac golf ball tracking system. It creates .deb packages specifically for Raspberry Pi 5 (arm64 architecture) targeting both Debian 12 (Bookworm) and Debian 13 (Trixie), and hosts them through an APT repository on GitHub Pages.
The build system handles two distinct challenges:
- Building external dependencies (lgpio, msgpack, opencv, onnxruntime) that aren't available in standard repositories with the right versions or configurations
- Packaging the PiTrac application itself from its separate source repository
- Managing distribution-specific variations (Bookworm uses ONNX Runtime 1.17.3, Trixie uses 1.22.1 with Eigen hash fix)
Raspberry Pi development typically involves compiling from source on the device itself, which takes hours for large projects like OpenCV. This repository solves that by providing pre-built packages that install in seconds. The packages are built with specific optimizations for the Pi 5's hardware and include only the features PiTrac needs.
The separation between this packaging repository and the main PiTrac source repository follows standard Debian packaging practices where packaging metadata and build scripts live separately from the application source.
packages/ # This repository
├── docker/ # Dockerfiles for cross-compilation
│ ├── Dockerfile.lgpio # GPIO library builder
│ ├── Dockerfile.msgpack # MessagePack C++ builder
│ ├── Dockerfile.activemq # ActiveMQ-CPP builder
│ ├── Dockerfile.opencv # OpenCV with DNN/ONNX support
│ └── Dockerfile.pitrac # Main application builder
├── scripts/ # Build automation
│ ├── build-package.sh # Docker build orchestrator (with distro param)
│ ├── build-*-native-pi.sh # Native Pi build scripts (with distro param)
│ ├── incremental-build.sh # Change detection builds
│ ├── version-manager.sh # Version and changelog management
│ ├── repo-init.sh # Repository initialization
│ ├── repo-update.sh # Package inclusion (multi-distro aware)
│ └── setup-gpg.sh # GPG key management
├── conf/ # APT repository configuration
│ └── distributions # reprepro configuration (bookworm + trixie)
├── build/ # Build outputs (gitignored)
│ ├── debs/ # Built packages by distribution
│ │ ├── bookworm/arm64/ # Debian 12 packages
│ │ └── trixie/arm64/ # Debian 13 packages
│ └── repo/ # Local APT repository
├── dists/ # APT repository metadata
│ ├── bookworm/ # Debian 12 distribution
│ └── trixie/ # Debian 13 distribution
├── pool/ # APT repository packages (shared)
└── Makefile # Primary build interface
The packages must be built in this order due to dependencies:
lgpio (0.2.2) → msgpack (7.0.0) → activemq (3.9.5) → opencv (4.11.0) → pitrac
↓ ↓ ↓ ↓ ↓
GPIO access Serialization Message Queue Computer vision Application
↓
ONNX Runtime (1.17.3/1.22.1)
(independent, version varies by distro)
Distribution-Specific Versions:
- Bookworm (Debian 12): ONNX Runtime 1.17.3
- Trixie (Debian 13): ONNX Runtime 1.22.1 (includes Eigen hash fix)
The system supports two build approaches, each with specific use cases:
1. Docker Cross-Compilation (Primary Method)
- Uses QEMU emulation to build arm64 packages on any host
- Consistent, reproducible builds in clean environments
- Suitable for CI/CD and most packages
- Slower but more portable
2. Native Raspberry Pi Builds (When Required)
- Builds directly on Pi hardware
- Required when QEMU can't handle specific ARM instructions
- Faster for large C++ projects like OpenCV
- Provides full hardware optimization support
On your build machine (can be x86_64 or arm64):
# Install required tools
sudo apt update
sudo apt install -y docker.io reprepro gpg dpkg-dev git make
# Add user to docker group (logout/login after)
sudo usermod -aG docker $USER
# Verify Docker
docker --version# Clone the repository
git clone https://github.com/YOUR_USERNAME/pitrac-packages.git
cd pitrac-packages
# Setup build environment
make setup
make check-docker
# Build all packages for both distributions (uses Docker/QEMU)
make build-all # Builds for both bookworm and trixie
# Or build for specific distribution
make build-all-bookworm # Debian 12 only
make build-all-trixie # Debian 13 only
# Initialize APT repository
make repo-init
# Add packages to repository (processes both distros)
make repo-update# Build specific package for both distributions
make build-lgpio # GPIO library (bookworm + trixie)
make build-msgpack # Serialization library (bookworm + trixie)
make build-activemq # ActiveMQ-CPP (bookworm + trixie)
make build-opencv # Computer vision (4+ hours with QEMU per distro)
make build-pitrac # Main application (bookworm + trixie)
# Build for specific distribution only
make build-lgpio-bookworm # Debian 12 only
make build-opencv-trixie # Debian 13 only
make build-pitrac-bookworm # Debian 12 only
# Build with specific source (for PiTrac development)
make build-pitrac PITRAC_REPO=file:///path/to/local/PiTrac
# Build from specific branch/tag
make build-pitrac PITRAC_BRANCH=v1.2.3Note: ONNX Runtime is only built natively on Raspberry Pi hardware due to complexity. See Native Pi Builds section below.
When QEMU emulation fails or is too slow, build directly on a Raspberry Pi. The native build scripts now support multi-distro builds:
# On a Raspberry Pi 5
cd pitrac-packages/scripts
# Build OpenCV natively for Bookworm (2-3 hours vs 4+ with QEMU)
./build-opencv-native-pi.sh bookworm
# Build OpenCV for Trixie
./build-opencv-native-pi.sh trixie
# Build ActiveMQ-CPP for specific distro
./build-activemq-native-pi.sh bookworm
# Build ONNX Runtime (auto-selects version based on distro)
# Bookworm: 1.17.3, Trixie: 1.22.1
./build-onnxruntime-xnnpack-fixed.sh 1.17.3 bookworm
./build-onnxruntime-xnnpack-fixed.sh 1.22.1 trixie
# Build all packages natively for a specific distribution
./build-all-native-pi.sh -d bookworm all
./build-all-native-pi.sh -d trixie all
# Build only OpenCV for Trixie with clean build
./build-all-native-pi.sh -d trixie -c opencv
# Copy resulting packages to build machine (distro-specific paths)
scp ~/pitrac-packages/bookworm/arm64/*.deb user@buildmachine:~/pitrac-packages/build/debs/bookworm/arm64/
scp ~/pitrac-packages/trixie/arm64/*.deb user@buildmachine:~/pitrac-packages/build/debs/trixie/arm64/The native build scripts detect the Pi model and apply appropriate optimizations:
- Pi 5: Cortex-A76 optimizations, NEON SIMD
- Pi 4: Cortex-A72 optimizations
- Others: Generic ARMv8 optimizations
ONNX Runtime Version Selection:
- Bookworm builds use ONNX Runtime 1.17.3 (stable, known working)
- Trixie builds use ONNX Runtime 1.22.1 (includes Eigen hash mismatch fix)
The incremental build system only rebuilds packages that have changed:
# Detect and build only changed packages
./scripts/incremental-build.sh
# Force rebuild specific packages if changed
./scripts/incremental-build.sh opencv pitrac
# The system tracks changes via:
# - Source file MD5 hashes
# - Dockerfile modifications
# - Dependency updatesPackage versions follow different strategies:
# Show current versions
./scripts/version-manager.sh show
# Dependencies use semantic versioning
./scripts/version-manager.sh set lgpio 0.2.3
./scripts/version-manager.sh increment opencv minor
# PiTrac uses date-based versioning
# Automatically: 2024.01.15-1
./scripts/version-manager.sh release pitrac revision "Camera optimizations"Package signing ensures authenticity. Generate a signing key:
# Interactive setup with menu
./scripts/setup-gpg.sh
# Options:
# 1. Generate new key
# 2. Export public key (for users)
# 3. Export private key (backup)
# 4. List keys
# 5. Configure reprepro
# 6. Complete setup (does everything)
# The public key will be saved as:
# - pitrac-repo.asc (for distribution)
# - conf/apt-key.asc (for reprepro)For CI/CD, export the private key and add to GitHub Secrets:
gpg --armor --export-secret-keys YOUR_KEY_ID > private.key
# Add contents to GitHub secret: SIGNING_KEY# Initialize repository structure (creates bookworm and trixie)
make repo-init
# Add built packages to repository (processes both distributions)
make repo-update
# Add individual package manually to specific distribution
reprepro -Vb . includedeb bookworm build/debs/bookworm/arm64/package_1.0_arm64.deb
reprepro -Vb . includedeb trixie build/debs/trixie/arm64/package_1.0_arm64.deb
# List repository contents for each distribution
make repo-list
reprepro list bookworm # List Debian 12 packages
reprepro list trixie # List Debian 13 packages
# Remove package from specific distribution
reprepro remove bookworm package-name
reprepro remove trixie package-name
# Check repository integrity (checks all distributions)
reprepro check
# Clean unreferenced files (cleans across all distributions)
reprepro deleteunreferencedThe APT repository follows standard Debian layout with multi-distribution support:
dists/
├── bookworm/ # Debian 12 (Bookworm) codename
│ ├── Release # Repository metadata
│ ├── Release.gpg # Signature
│ └── main/ # Component
│ └── binary-arm64/ # Architecture
│ ├── Packages # Package index
│ └── Packages.gz # Compressed index
└── trixie/ # Debian 13 (Trixie) codename
├── Release # Repository metadata
├── Release.gpg # Signature
└── main/ # Component
└── binary-arm64/ # Architecture
├── Packages # Package index
└── Packages.gz # Compressed index
pool/
└── main/ # Component (shared between distributions)
└── [a-z]/ # First letter of package
└── package/ # Package name
└── *.deb # Package files
Note: Packages in pool/ are shared between distributions where appropriate. Distribution-specific packages (like ONNX Runtime with different versions) have distinct filenames.
The repository automatically deploys to GitHub Pages:
-
Enable GitHub Pages
- Repository Settings → Pages
- Source: Deploy from branch
- Branch: main, / (root)
-
Automatic Deployment
# Commits to main trigger deployment git add . git commit -m "Add opencv 4.11.0 packages" git push origin main
-
Access Repository
https://YOUR_USERNAME.github.io/pitrac-packages/
For custom hosting:
# Sync repository to web server
rsync -av --delete dists/ pool/ server:/var/www/apt/
rsync -av pitrac-repo.asc server:/var/www/apt/
# Or use GitHub releases
gh release create v1.0 build/debs/arm64/*.debOn Raspberry Pi systems, choose the repository matching your Debian version:
For Debian 12 (Bookworm):
# Add repository to APT sources
echo "deb [arch=arm64 signed-by=/usr/share/keyrings/pitrac.gpg] \
https://YOUR_USERNAME.github.io/pitrac-packages bookworm main" | \
sudo tee /etc/apt/sources.list.d/pitrac.list
# Add repository signing key
curl -fsSL https://YOUR_USERNAME.github.io/pitrac-packages/pitrac-repo.asc | \
sudo gpg --dearmor -o /usr/share/keyrings/pitrac.gpg
# Update package index
sudo apt updateFor Debian 13 (Trixie):
# Add repository to APT sources
echo "deb [arch=arm64 signed-by=/usr/share/keyrings/pitrac.gpg] \
https://YOUR_USERNAME.github.io/pitrac-packages trixie main" | \
sudo tee /etc/apt/sources.list.d/pitrac.list
# Add repository signing key
curl -fsSL https://YOUR_USERNAME.github.io/pitrac-packages/pitrac-repo.asc | \
sudo gpg --dearmor -o /usr/share/keyrings/pitrac.gpg
# Update package index
sudo apt updateCheck your Debian version:
cat /etc/debian_version # Shows 12.x for Bookworm, 13.x for Trixie
lsb_release -cs # Shows codename: bookworm or trixie# Install everything (automatically gets correct versions for your distro)
sudo apt install pitrac
# Install specific components (same commands for both distros)
sudo apt install liblgpio1 liblgpio-dev # GPIO library
sudo apt install libmsgpack-cxx-dev # MessagePack headers
sudo apt install libactivemq-cpp libactivemq-cpp-dev # ActiveMQ-CPP
sudo apt install libopencv4.11 # OpenCV runtime
sudo apt install libopencv-dev # OpenCV development
# ONNX Runtime (version depends on your distribution)
# Bookworm: libonnxruntime1.17.3
# Trixie: libonnxruntime1.22.1
sudo apt install libonnxruntime1.17.3 # If on Bookworm
sudo apt install libonnxruntime1.22.1 # If on Trixie
# The pitrac package pulls in all dependencies automaticallyNote: The APT repository automatically provides the correct package versions for your distribution. Bookworm users get ONNX Runtime 1.17.3, Trixie users get 1.22.1 with the Eigen hash fix.
To prevent unwanted upgrades:
# Pin specific version
echo "Package: pitrac
Pin: version 2024.01.15-1
Pin-Priority: 1001" | sudo tee /etc/apt/preferences.d/pitrac
# Hold package at current version
sudo apt-mark hold pitracThe .github/workflows/build-packages.yml workflow:
-
Triggers
- Push to main/develop branches
- Pull requests
- Manual workflow dispatch
- Repository dispatch from PiTrac repo
-
Build Matrix
- Builds all packages for arm64
- Parallel builds where possible
- Caches Docker layers
-
Deployment
- Updates APT repository
- Commits to main branch
- GitHub Pages publishes automatically
Link package builds to PiTrac releases:
# In PiTrac repo: .github/workflows/trigger-packages.yml
name: Trigger Package Build
on:
push:
tags: ['v*']
jobs:
trigger:
runs-on: ubuntu-latest
steps:
- uses: peter-evans/repository-dispatch@v2
with:
token: ${{ secrets.PACKAGES_TOKEN }}
repository: YOUR_USERNAME/pitrac-packages
event-type: build-release
client-payload: '{"tag": "${{ github.ref_name }}"}'Speed up CI builds:
# Use GitHub Actions cache
- uses: actions/cache@v3
with:
path: build/cache
key: ${{ runner.os }}-build-${{ hashFiles('docker/**') }}
# Parallel builds in workflow
strategy:
matrix:
package: [lgpio, msgpack, opencv, pitrac]Lightweight GPIO library for Raspberry Pi:
- Replaces deprecated wiringPi
- Kernel-based GPIO access via /dev/gpiochip
- No sudo required with proper permissions
- Packages:
liblgpio1(runtime),liblgpio-dev(headers)
High-performance binary serialization:
- Header-only C++ library
- Zero-copy operations
- Smaller than JSON, faster than Protocol Buffers
- Epoch prefix ensures priority over Debian packages
- Includes pkg-config file (missing in official Debian package)
- Package:
libmsgpack-cxx-dev
Computer vision optimized for PiTrac:
- DNN module for YOLO object detection
- ONNX runtime support
- Video I/O with V4L2 and GStreamer
- Removed: Python bindings, Java, unnecessary modules
- Build time: 2-3 hours native per distro, 4+ hours with QEMU per distro
- Packages:
libopencv4.11(runtime),libopencv-dev(development) - Same version across both Bookworm and Trixie
High-performance ML inference with XNNPACK:
- Bookworm: ONNX Runtime 1.17.3 (stable, tested)
- Trixie: ONNX Runtime 1.22.1 (includes Eigen dependency hash fix)
- XNNPACK execution provider for 2-4x speedup on Pi 5
- Built natively only (too complex for QEMU cross-compilation)
- Build time: 60-90 minutes on Pi 5
- Packages:
libonnxruntime1.17.3orlibonnxruntime1.22.1
Main application package:
- Pulls source from GitHub.com/PiTracLM/PiTrac
- Includes systemd service files
- Web interface on port 8080
- Configuration in /etc/pitrac/
- Logs to /var/log/pitrac/
- Package:
pitrac
build-package.sh
./scripts/build-package.sh <package> <arch> <version> <distro>
# Examples:
# ./scripts/build-package.sh opencv arm64 4.11.0-1 bookworm
# ./scripts/build-package.sh pitrac arm64 2024.01.15-1 trixiebuild-all-native-pi.sh
# Run on Raspberry Pi for native builds
./scripts/build-all-native-pi.sh [OPTIONS] [PACKAGES]
# Options:
# -d, --distro <distro> Target distribution (bookworm or trixie)
# -o, --output <dir> Base output directory
# -c, --clean Clean before building
# Examples:
# ./scripts/build-all-native-pi.sh -d bookworm all
# ./scripts/build-all-native-pi.sh -d trixie opencv
# ./scripts/build-all-native-pi.sh -d trixie -c onnxruntimebuild-opencv-native-pi.sh
./scripts/build-opencv-native-pi.sh [distro]
# Examples:
# ./scripts/build-opencv-native-pi.sh bookworm
# ./scripts/build-opencv-native-pi.sh trixiebuild-activemq-native-pi.sh
./scripts/build-activemq-native-pi.sh [distro]
# Examples:
# ./scripts/build-activemq-native-pi.sh bookworm
# ./scripts/build-activemq-native-pi.sh trixiebuild-onnxruntime-xnnpack-fixed.sh
./scripts/build-onnxruntime-xnnpack-fixed.sh [version] [distro]
# Examples:
# ./scripts/build-onnxruntime-xnnpack-fixed.sh 1.17.3 bookworm
# ./scripts/build-onnxruntime-xnnpack-fixed.sh 1.22.1 trixieincremental-build.sh
# Build only changed packages
./scripts/incremental-build.sh [package1] [package2]repo-init.sh
# Initialize APT repository structure
./scripts/repo-init.sh <repo_dir> <gpg_key_id>repo-update.sh
# Add packages to repository (processes all distributions)
./scripts/repo-update.sh <repo_dir> <debs_dir>
# Example:
# ./scripts/repo-update.sh build/repo build/debs
# Processes:
# build/debs/bookworm/arm64/*.deb → bookworm distribution
# build/debs/trixie/arm64/*.deb → trixie distributionadd-package.sh
# Add single package
./scripts/add-package.sh <deb_file> [component]version-manager.sh
# Version management
./scripts/version-manager.sh <command> [args]
# Commands: show, set, increment, releasetest-packages.sh
# Validate built packages
./scripts/test-packages.sh <debs_dir>setup-gpg.sh
# GPG key management menu
./scripts/setup-gpg.shDocker build fails with "exec format error"
# QEMU not setup properly
docker run --rm --privileged multiarch/qemu-user-static --reset -p yes
make check-dockerOpenCV build crashes or hangs
# QEMU can't handle some AVX instructions
# Solution: Build natively on Raspberry Pi
ssh pi@raspberrypi
cd pitrac-packages/scripts
./build-opencv-native-pi.shOut of space during build
# Docker uses lots of space
docker system prune -a
# Increase Docker storage in settings
# Or use external volume for builds"The repository does not have a Release file"
# Repository not initialized
make repo-init
make repo-update
# Check GitHub Pages is enabledGPG signature verification failed
# Key mismatch or not installed
curl -fsSL https://YOUR_USERNAME.github.io/pitrac-packages/pitrac-repo.asc | \
sudo gpg --dearmor -o /usr/share/keyrings/pitrac.gpg
# Update sources.list to reference correct keyPackage conflicts during installation
# Check installed versions
dpkg -l | grep -E "lgpio|msgpack|opencv|pitrac"
# Remove conflicting packages
sudo apt remove --purge conflicting-package
# Force overwrite (careful)
sudo dpkg -i --force-overwrite package.debChanges not reflected in build
# Docker caching issue
make clean
docker build --no-cache -f docker/Dockerfile.pitrac .
# Or force rebuild
./scripts/incremental-build.sh --force pitracCan't access local PiTrac source
# File URL must be absolute
make build-pitrac PITRAC_REPO=file://$PWD/../PiTrac # Wrong
make build-pitrac PITRAC_REPO=file:///home/user/PiTrac # CorrectNative Pi build missing dependencies
# Install build dependencies first
sudo apt build-dep opencv
# Or manually install from script
grep "apt-get install" build-opencv-native-pi.shTypical build times on different systems:
| Package | Docker/QEMU (x86) | Docker (ARM) | Native Pi 5 | Native Pi 4 |
|---|---|---|---|---|
| lgpio | 2 min | 1 min | 30 sec | 45 sec |
| msgpack | 1 min | 30 sec | 20 sec | 30 sec |
| opencv | 4-5 hours | 2 hours | 2-3 hours | 4-5 hours |
| pitrac | 10 min | 5 min | 5 min | 8 min |
- Use Native Builds for OpenCV: QEMU emulation makes OpenCV builds extremely slow
- Parallel Builds: The Makefile supports parallel package builds
- Incremental Builds: Only rebuild what changed
- Docker Layer Caching: Dockerfiles are structured to maximize cache hits
- ccache: Native builds can use ccache to speed up recompilation
- Build environment: 20GB minimum
- Each OpenCV build: 8-10GB temporary
- Final packages: ~200MB total
- APT repository: ~250MB with all packages
All packages are GPG signed:
- Signature verification happens automatically during apt update
- Users must add the public key to their keyring
- Private key should never be in the repository
Docker provides build isolation:
- Each build runs in a clean container
- No host system contamination
- Reproducible builds
The build system verifies:
- Source tarball checksums (where applicable)
- Git commit hashes for source checkouts
- Package dependencies during build
# Update package versions
./scripts/version-manager.sh increment opencv patch
make build-opencv
make repo-update
# Update dependencies in Dockerfiles
vim docker/Dockerfile.opencv
# Change version numbers, test build
# Regenerate repository metadata
cd build/repo
reprepro export# Check build cache size
du -sh build/cache/
# Clean old packages from repository
reprepro --delete clearvanished
# Remove old Docker images
docker image prune -aImportant files to backup:
- GPG private key (keep secure, offline)
- conf/distributions (repository configuration)
- Package build logs (for debugging)
- Custom Dockerfiles modifications
To move to a new host:
# Export repository
tar czf pitrac-repo-backup.tar.gz dists/ pool/ conf/ *.asc
# On new host
tar xzf pitrac-repo-backup.tar.gz
reprepro --delete clearvanished
reprepro export- Create Dockerfile:
# docker/Dockerfile.newpackage
FROM debian:bookworm-slim
# Build instructions...- Add to Makefile:
NEWPACKAGE_VERSION := 1.0.0-1
PACKAGES := lgpio msgpack opencv pitrac newpackage-
Update dependency chain if needed
-
Test build:
make build-newpackage- Optimize Dockerfiles for better caching
- Add ccache support for C++ builds
- Implement distributed builds
- Use BuildKit features
- Update this README with new features
- Document any new dependencies
- Add examples for new use cases
- Keep troubleshooting section current
The build scripts and packaging files in this repository are provided under the MIT License. Individual packages maintain their original licenses:
- lgpio: Unlicense (public domain)
- msgpack: Boost Software License
- OpenCV: Apache 2.0
- PiTrac: See main repository
For issues related to:
- Packaging and builds: Open issue in this repository
- PiTrac application: Use main PiTrac repository
- Dependency problems: Check individual package documentation
- Repository hosting: Verify GitHub Pages status