Files
StarPilot/build
T
firestar5683 694b460f80 Developer Tools
Provide laptop and device build entry points, cache compatibility checks and developer tooling. Keep distribution assets and model packaging available before runtime consumers.

Co-authored-by: Danny <dannyirwin31@yahoo.com>
Co-authored-by: Prabhaav Pillai <prabhaav@msu.edu>
Co-authored-by: dirwin31 <83434411+dirwin31@users.noreply.github.com>
Co-authored-by: firestarsdog <229254897+firestarsdog@users.noreply.github.com>

Co-authored-by: prabhaavp <prabhaav@msu.edu>
2026-10-14 20:02:39 -05:00

157 lines
5.2 KiB
Python
Executable File

#!/usr/bin/env bash
# Project build shortcuts. AGNOS builds natively; laptops use the ARM64 container.
set -euo pipefail
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
if [[ "${1:-}" == -h || "${1:-}" == --help ]]; then
cat <<'EOF'
Usage: ./build [jobs] [scons options]
./build [--params] [--cereal] [--panda] [jobs] [scons options]
./build --mapd
./build --check-startup <Params root or namespace> <recovery storage>
On AGNOS/aarch64, builds run natively. On laptops, builds use a Linux/ARM64 container.
--params builds libparams_c.so; --cereal builds cereal outputs; --panda
builds signed panda (C3), panda_h7 and body_h7 firmware only. Numeric jobs become -jN.
RELEASE and CERT are environment variables, not trailing SCons arguments:
RELEASE=1 CERT=/path/to/certificate ./build --panda 4
CERT must name a readable certificate file. Omit RELEASE for DEBUG firmware.
--mapd explicitly packages the pinned offline Linux/ARM64 Go provider; it
does not fetch map regions or participate in the default build.
Run scripts/laptop_device_build.sh doctor to check local prerequisites.
Full laptop builds require a source-matched QCOM artifact package in
.cache/qcom-artifact-package; device builds still compile models natively.
--check-startup checks retained settings admission read-only using the local
native developer runtime. Supply a matching Params namespace and recovery
storage. A relocated copy can fail its path-bound profile marker.
EOF
exit 0
fi
if [[ "${1:-}" == --check-startup ]]; then
if [[ $# -ne 3 ]]; then
echo "Usage: ./build --check-startup <Params root or namespace> <recovery storage>" >&2
exit 2
fi
exec "${ROOT_DIR}/dev" python "${ROOT_DIR}/tools/check_startup.py" "$2" "$3"
fi
for arg in "$@"; do
case "${arg}" in
RELEASE=*|CERT=*)
echo "ERROR: RELEASE and CERT must be environment variables, not SCons arguments." >&2
echo "Use: RELEASE=1 CERT=/path/to/certificate ./build --panda 4" >&2
exit 2
;;
esac
done
build_helper="${ROOT_DIR}/scripts/laptop_device_build.sh"
if [[ -f /AGNOS && "$(uname -s)" == Linux && "$(uname -m)" == aarch64 ]]; then
build_helper="${ROOT_DIR}/scripts/native_device_build.sh"
fi
if [[ $# -eq 1 && "$1" == --mapd ]]; then
exec "${ROOT_DIR}/scripts/build_mapd_provider.sh"
fi
if [[ $# -gt 0 ]]; then
for arg in "$@"; do
if [[ "$arg" == --mapd ]]; then
echo "ERROR: --mapd is a standalone package operation; use ./build --mapd" >&2
exit 2
fi
done
fi
shortcut_targets=()
passthrough_args=()
default_args=()
jobs_arg=""
shortcut_includes_panda=0
panda_generated_files=(panda/board/obj/gitversion.h panda/board/obj/version)
while [[ $# -gt 0 ]]; do
case "$1" in
--params|-params|-param)
shortcut_targets+=(openpilot/common/libparams_c.so)
;;
--panda|-panda)
shortcut_includes_panda=1
shortcut_targets+=(panda/board/obj/panda.bin.signed panda/board/obj/panda_h7.bin.signed panda/board/obj/body_h7.bin.signed)
;;
--cereal|-cereal)
shortcut_targets+=(openpilot/cereal/libcereal.a openpilot/cereal/libsocketmaster.a
openpilot/cereal/messaging/bridge openpilot/cereal/services.h)
;;
-j|--jobs)
passthrough_args+=("$1")
default_args+=("$1")
if [[ $# -gt 1 ]]; then
passthrough_args+=("$2")
default_args+=("$2")
shift
fi
;;
*)
if [[ "$1" =~ ^[0-9]+$ ]]; then
if [[ "$1" =~ ^0+$ ]]; then
echo "ERROR: jobs must be positive" >&2
exit 2
fi
jobs_arg="$1"
passthrough_args+=("-j$1")
else
passthrough_args+=("$1")
default_args+=("$1")
fi
;;
esac
shift
done
if [[ "${#shortcut_targets[@]}" -gt 0 ]]; then
scons_args=(--no-scrub "${shortcut_targets[@]}")
if [[ ${passthrough_args[0]+present} ]]; then
scons_args+=("${passthrough_args[@]}")
fi
if [[ "$shortcut_includes_panda" -eq 1 ]]; then
exec "${build_helper}" scons "${scons_args[@]}"
fi
# Panda/SConscript updates these even for unrelated targets. Restore their
# prior bytes for the non-firmware shortcuts, including on build failure.
tmpdir="$(mktemp -d)"
restore_panda_metadata() {
local path safe
for path in "${panda_generated_files[@]}"; do
safe="${path//\//__}"
if [[ -e "${tmpdir}/${safe}.missing" ]]; then
rm -f "${ROOT_DIR}/${path}"
else
cp -p "${tmpdir}/${safe}" "${ROOT_DIR}/${path}"
fi
done
rm -rf "${tmpdir}"
}
trap restore_panda_metadata EXIT
for path in "${panda_generated_files[@]}"; do
safe="${path//\//__}"
if [[ -e "${ROOT_DIR}/${path}" ]]; then
cp -p "${ROOT_DIR}/${path}" "${tmpdir}/${safe}"
else
touch "${tmpdir}/${safe}.missing"
fi
done
"${build_helper}" scons "${scons_args[@]}"
exit $?
fi
python3 "${ROOT_DIR}/tools/release/stage_mapd_provider.py" --source "${ROOT_DIR}" --require-tracked
if [[ -n "${jobs_arg}" ]]; then
if [[ ${default_args[0]+present} ]]; then
exec "${build_helper}" build "${jobs_arg}" "${default_args[@]}"
fi
exec "${build_helper}" build "${jobs_arg}"
fi
if [[ ${default_args[0]+present} ]]; then
exec "${build_helper}" build "${default_args[@]}"
fi
exec "${build_helper}" build