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>
170 lines
6.2 KiB
Bash
Executable File
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
|