Files
pi-pm3/ci/build-pm3.sh
michael a9acdb85ce Build optimization: pre-built PM3 binaries, ARM64 CI, base image caching
Replace PM3 compile-from-source in pi-gen with pre-built tarball extraction
(saves 43-58 min). Merge stagePM3 into stageDangerousPi as 02-pm3-install
substage, renumber all subsequent substages. Switch CI PM3 build to native
ARM64 runner (ubuntu-24.04-arm64) eliminating QEMU overhead. Add weekly
base-image workflow for pre-baking stages 0-2. Support PM3_TARBALL,
BASE_IMAGE, and APT_PROXY env vars in build-image.sh.

Also includes prior Phase 5 work: theme system, design system integration,
component update system, OS updates, CI build pipeline, and test results.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-04 12:01:01 -08:00

170 lines
6.2 KiB
Bash
Executable File

#!/usr/bin/env bash
# Build Proxmark3 client + firmware + Python bindings for aarch64.
# Designed to run inside an aarch64 Docker container (via QEMU on CI).
#
# Environment variables:
# PYTHON_VERSION - e.g. "3.12" (default: auto-detect)
# PM3_REPO - upstream repo (default: RfidResearchGroup/proxmark3)
# OUTPUT_DIR - where to write the tarball (default: ./dist)
#
# Reads patches from pi-gen/stageDangerousPi/02-pm3-install/ in the workspace.
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
WORKSPACE="${SCRIPT_DIR}/.."
PYTHON_VERSION="${PYTHON_VERSION:-$(python3 -c 'import sys; print(f"{sys.version_info.major}.{sys.version_info.minor}")')}"
PYTHON_ABI="cp$(echo "$PYTHON_VERSION" | tr -d '.')"
PM3_REPO="${PM3_REPO:-https://github.com/RfidResearchGroup/proxmark3}"
OUTPUT_DIR="${OUTPUT_DIR:-${WORKSPACE}/dist}"
ARCH="$(uname -m)" # aarch64 when in container
BUILD_DIR="/tmp/pm3-build"
echo "=== Dangerous Pi PM3 Build ==="
echo "Python: ${PYTHON_VERSION} (${PYTHON_ABI})"
echo "Arch: ${ARCH}"
echo "Repo: ${PM3_REPO}"
# -----------------------------------------------------------------------
# 1. Install build dependencies
# -----------------------------------------------------------------------
echo "--- Installing build dependencies ---"
apt-get update -qq
apt-get install -y -qq \
cmake python3-dev swig build-essential \
libreadline-dev libusb-1.0-0-dev liblz4-dev libbz2-dev \
libjansson-dev libc6-dev pkg-config git \
gcc-arm-none-eabi libnewlib-dev \
ca-certificates libssl-dev libbluetooth-dev libgd-dev
# -----------------------------------------------------------------------
# 2. Clone and patch
# -----------------------------------------------------------------------
echo "--- Cloning Proxmark3 ---"
rm -rf "$BUILD_DIR"
git clone --depth 1 "$PM3_REPO" "$BUILD_DIR"
cd "$BUILD_DIR"
PATCH_DIR="${WORKSPACE}/pi-gen/stageDangerousPi/02-pm3-install"
# Apply LED PWM control patch
if [ -f "${PATCH_DIR}/led-pwm-control-fixed.patch" ]; then
echo "Applying LED PWM control patch (fixed)..."
patch -p1 < "${PATCH_DIR}/led-pwm-control-fixed.patch" || \
echo "Warning: LED PWM patch failed, continuing"
elif [ -f "${PATCH_DIR}/led-pwm-control.patch" ]; then
echo "Applying LED PWM control patch..."
patch -p1 < "${PATCH_DIR}/led-pwm-control.patch" || \
echo "Warning: LED PWM patch failed, continuing"
fi
# Apply HF booster detection patch
if [ -f "${PATCH_DIR}/hf-booster-detection.patch" ]; then
echo "Applying HF booster detection patch..."
patch -p1 < "${PATCH_DIR}/hf-booster-detection.patch" || \
echo "Warning: HF booster patch failed, continuing"
fi
# DangerousPi version branding
sed -i 's/^fullgitinfo="Iceman"$/fullgitinfo="Iceman\/DangerousPi"/' tools/mkversion.sh 2>/dev/null || true
# -----------------------------------------------------------------------
# 3. Configure platform
# -----------------------------------------------------------------------
cat > Makefile.platform << EOF
PLATFORM=PM3GENERIC
LED_ORDER=PM3EASY
EOF
# -----------------------------------------------------------------------
# 4. Build firmware (bootrom + fullimage)
# -----------------------------------------------------------------------
echo "--- Building firmware ---"
make -j"$(nproc)" bootrom fullimage
# -----------------------------------------------------------------------
# 5. Build client
# -----------------------------------------------------------------------
echo "--- Building client ---"
make -j"$(nproc)" client
# -----------------------------------------------------------------------
# 6. Build Python bindings (SWIG)
# -----------------------------------------------------------------------
echo "--- Building Python bindings ---"
# Fix CMakeLists.txt for experimental_lib (add missing sources)
if [ -f client/experimental_lib/CMakeLists.txt ]; then
sed -i '/TARGET_SOURCES.*pm3rrg_rdv4_experimental/,/)/s|\(${PM3_ROOT}/client/src/wiegand_formatutils.c\)|\1\n ${PM3_ROOT}/client/src/qrcode/qrcode.c|' \
client/experimental_lib/CMakeLists.txt 2>/dev/null || true
sed -i 's|\(${PM3_ROOT}/client/src/pm3\.c\)|${PM3_ROOT}/client/src/pla.c\n \1|' \
client/experimental_lib/CMakeLists.txt 2>/dev/null || true
fi
mkdir -p client/build && cd client/build
cmake .. -DBUILD_PYTHON_LIB=ON
make -j"$(nproc)"
cd ../..
# Build SWIG library
if [ -f client/experimental_lib/00make_swig.sh ]; then
cd client/experimental_lib
./00make_swig.sh
./01make_lib.sh
cd ../..
fi
# -----------------------------------------------------------------------
# 7. Package artifacts
# -----------------------------------------------------------------------
echo "--- Packaging ---"
PM3_VERSION="$(git describe --always --tags 2>/dev/null || echo unknown)"
STAGING="/tmp/pm3-staging/pm3"
rm -rf /tmp/pm3-staging
mkdir -p "${STAGING}/client/pyscripts" \
"${STAGING}/firmware" \
"${STAGING}/patches" \
"${STAGING}/scripts"
# Client binary
cp client/build/proxmark3 "${STAGING}/client/"
# Python bindings
cp client/experimental_lib/build/libpm3rrg_rdv4.so "${STAGING}/client/pyscripts/" 2>/dev/null || true
cp client/pyscripts/*.py "${STAGING}/client/pyscripts/" 2>/dev/null || true
cd "${STAGING}/client/pyscripts" && ln -sf libpm3rrg_rdv4.so _pm3.so && cd "$BUILD_DIR"
# Firmware
cp bootrom/obj/bootrom.elf "${STAGING}/firmware/"
cp armsrc/obj/fullimage.elf "${STAGING}/firmware/"
# Flash utilities
cp pm3-flash-all pm3-flash-bootrom pm3-flash-fullimage "${STAGING}/" 2>/dev/null || true
chmod +x "${STAGING}"/pm3-flash-* 2>/dev/null || true
# Patches (for rebuild-from-source fallback)
cp "${PATCH_DIR}"/*.patch "${STAGING}/patches/" 2>/dev/null || true
# Version metadata
cat > "${STAGING}/COMPONENT_VERSION" << VEOF
{
"component_id": "pm3",
"version": "${PM3_VERSION}",
"platform": "${ARCH}-linux",
"python_version": "${PYTHON_VERSION}",
"python_abi": "${PYTHON_ABI}",
"build_date": "$(date -u +"%Y-%m-%dT%H:%M:%SZ")",
"upstream_commit": "$(git rev-parse --short HEAD 2>/dev/null || echo unknown)"
}
VEOF
# Create tarball
mkdir -p "$OUTPUT_DIR"
TARBALL="pm3-${PM3_VERSION}-${ARCH}-linux-${PYTHON_ABI}.tar.gz"
cd /tmp/pm3-staging
tar -czf "${OUTPUT_DIR}/${TARBALL}" pm3/
echo "✅ Built: ${OUTPUT_DIR}/${TARBALL}"
# Cleanup
rm -rf "$BUILD_DIR" /tmp/pm3-staging