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>
This commit is contained in:
169
ci/build-pm3.sh
Executable file
169
ci/build-pm3.sh
Executable file
@@ -0,0 +1,169 @@
|
||||
#!/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
|
||||
Reference in New Issue
Block a user