#!/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