| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335 |
- #!/usr/bin/env bash
- require_uv() {
- if ! command -v uv >/dev/null 2>&1; then
- echo "uv is required. Install it from https://docs.astral.sh/uv/" >&2
- exit 1
- fi
- }
- sync_python_tooling() {
- uv sync --locked --no-group docs >/dev/null
- uv venv --allow-existing --seed >/dev/null
- }
- run_python() {
- uv run --no-sync python "$@"
- }
- run_pio() {
- uv run --no-sync pio "$@"
- }
- global_usage() {
- cat - <<EOF
- Usage:
- sh build.sh <command> [target]
- Commands:
- help|usage|-h|--help: Shows this message.
- list|-l: List firmwares available to build.
- build-firmware <target>: Build the firmware for the given build target.
- build-firmwares: Build all firmwares for all targets.
- build-matching-firmwares <build-match-spec>: Build all firmwares for build targets containing the string given for <build-match-spec>.
- build-companion-firmwares: Build all companion firmwares for all build targets.
- build-companion-wifi-firmwares: Build all companion WiFi firmwares for all build targets.
- build-repeater-firmwares: Build all repeater firmwares for all build targets.
- build-repeater-mqtt-firmwares: Build all repeater MQTT firmwares for all build targets.
- build-room-server-firmwares: Build all chat room server firmwares for all build targets.
- Examples:
- Build firmware for the "RAK_4631_repeater" device target
- $ sh build.sh build-firmware RAK_4631_repeater
- Build all firmwares for device targets containing the string "RAK_4631"
- $ sh build.sh build-matching-firmwares <build-match-spec>
- Build all companion firmwares
- $ sh build.sh build-companion-firmwares
- Build all companion WiFi firmwares
- $ sh build.sh build-companion-wifi-firmwares
- Build all repeater firmwares
- $ sh build.sh build-repeater-firmwares
- Build all repeater MQTT firmwares
- $ sh build.sh build-repeater-mqtt-firmwares
- Build all chat room server firmwares
- $ sh build.sh build-room-server-firmwares
- Environment Variables:
- DISABLE_DEBUG=1: Disables all debug logging flags (MESH_DEBUG, MESH_PACKET_LOGGING, etc.)
- If not set, debug flags from variant platformio.ini files are used.
- Examples:
- Build without debug logging:
- $ export FIRMWARE_VERSION=v1.0.0
- $ export DISABLE_DEBUG=1
- $ sh build.sh build-firmware RAK_4631_repeater
- Build with debug logging (default, uses flags from variant files):
- $ export FIRMWARE_VERSION=v1.0.0
- $ sh build.sh build-firmware RAK_4631_repeater
- EOF
- }
- # get a list of pio env names that start with "env:"
- get_pio_envs() {
- run_pio project config | grep 'env:' | sed 's/env://'
- }
- # Catch cries for help before doing anything else.
- case $1 in
- help|usage|-h|--help)
- global_usage
- exit 1
- ;;
- list|-l)
- get_pio_envs
- exit 0
- ;;
- esac
- # cache project config json for use in get_platform_for_env()
- require_uv
- sync_python_tooling
- PIO_CONFIG_JSON=$(run_pio project config --json-output)
- # $1 should be the string to find (case insensitive)
- get_pio_envs_containing_string() {
- shopt -s nocasematch
- envs=($(get_pio_envs))
- for env in "${envs[@]}"; do
- if [[ "$env" == *${1}* ]]; then
- echo $env
- fi
- done
- }
- # $1 should be the string to find (case insensitive)
- get_pio_envs_ending_with_string() {
- shopt -s nocasematch
- envs=($(get_pio_envs))
- for env in "${envs[@]}"; do
- if [[ "$env" == *${1} ]]; then
- echo $env
- fi
- done
- }
- # get platform flag for a given environment
- # $1 should be the environment name
- get_platform_for_env() {
- local env_name=$1
- echo "$PIO_CONFIG_JSON" | run_python -c "
- import sys, json, re
- data = json.load(sys.stdin)
- for section, options in data:
- if section == 'env:$env_name':
- for key, value in options:
- if key == 'build_flags':
- for flag in value:
- match = re.search(r'(ESP32_PLATFORM|NRF52_PLATFORM|STM32_PLATFORM|RP2040_PLATFORM)', flag)
- if match:
- print(match.group(1))
- sys.exit(0)
- "
- }
- # disable all debug logging flags if DISABLE_DEBUG=1 is set
- disable_debug_flags() {
- if [ "$DISABLE_DEBUG" == "1" ]; then
- export PLATFORMIO_BUILD_FLAGS="${PLATFORMIO_BUILD_FLAGS} -UMESH_DEBUG -UBLE_DEBUG_LOGGING -UWIFI_DEBUG_LOGGING -UBRIDGE_DEBUG -UGPS_NMEA_DEBUG -UCORE_DEBUG_LEVEL -UESPNOW_DEBUG_LOGGING -UDEBUG_RP2040_WIRE -UDEBUG_RP2040_SPI -UDEBUG_RP2040_CORE -UDEBUG_RP2040_PORT -URADIOLIB_DEBUG_SPI -UCFG_DEBUG -URADIOLIB_DEBUG_BASIC -URADIOLIB_DEBUG_PROTOCOL"
- fi
- }
- # build firmware for the provided pio env in $1
- build_firmware() {
- # get env platform for post build actions
- ENV_PLATFORM=($(get_platform_for_env $1))
- # get git commit sha
- if [ -z "$COMMIT_HASH" ]; then
- COMMIT_HASH=$(git rev-parse --short HEAD)
- fi
- # set firmware build date
- FIRMWARE_BUILD_DATE=$(date '+%d-%b-%Y')
- # get FIRMWARE_VERSION, which should be provided by the environment
- if [ -z "$FIRMWARE_VERSION" ]; then
- echo "FIRMWARE_VERSION must be set in environment"
- exit 1
- fi
- # set artifact version string
- # e.g: v1.2.3-meshcoretel-v1.0.1-abcdef
- FIRMWARE_VERSION_BASE="${FIRMWARE_VERSION}"
- if [ -n "$MESHCORETEL_VERSION" ]; then
- FIRMWARE_VERSION_BASE="${FIRMWARE_VERSION_BASE}-vbart-meshcoretel-${MESHCORETEL_VERSION}"
- fi
- FIRMWARE_VERSION_STRING="${FIRMWARE_VERSION_BASE}-${COMMIT_HASH}"
- CLIENT_VERSION_STRING="meshcoretel-${COMMIT_HASH}"
- if [ -n "$MESHCORETEL_VERSION" ]; then
- CLIENT_VERSION_STRING="vbart-meshcoretel-${MESHCORETEL_VERSION}-${COMMIT_HASH}"
- fi
- # craft filename
- # e.g: RAK_4631_Repeater-v1.0.0-SHA
- FIRMWARE_FILENAME="$1-${FIRMWARE_VERSION_STRING}"
- # add build metadata to end of existing platformio build flags in environment vars
- export PLATFORMIO_BUILD_FLAGS="${PLATFORMIO_BUILD_FLAGS} -DFIRMWARE_BUILD_DATE='\"${FIRMWARE_BUILD_DATE}\"' -DFIRMWARE_VERSION='\"${FIRMWARE_VERSION_STRING}\"' -DCLIENT_VERSION='\"${CLIENT_VERSION_STRING}\"'"
- # disable debug flags if requested
- disable_debug_flags
- # build firmware target
- run_pio run -e $1
- # build merge-bin for esp32 fresh install, copy .bins to out folder (e.g: Heltec_v3_room_server-v1.0.0-SHA.bin)
- if [ "$ENV_PLATFORM" == "ESP32_PLATFORM" ]; then
- run_pio run -t mergebin -e $1
- cp .pio/build/$1/firmware.bin out/${FIRMWARE_FILENAME}.bin 2>/dev/null || true
- cp .pio/build/$1/firmware-merged.bin out/${FIRMWARE_FILENAME}-merged.bin 2>/dev/null || true
- fi
- # build .uf2 for nrf52 boards, copy .uf2 and .zip to out folder (e.g: RAK_4631_Repeater-v1.0.0-SHA.uf2)
- if [ "$ENV_PLATFORM" == "NRF52_PLATFORM" ]; then
- run_python bin/uf2conv/uf2conv.py .pio/build/$1/firmware.hex -c -o .pio/build/$1/firmware.uf2 -f 0xADA52840
- cp .pio/build/$1/firmware.uf2 out/${FIRMWARE_FILENAME}.uf2 2>/dev/null || true
- cp .pio/build/$1/firmware.zip out/${FIRMWARE_FILENAME}.zip 2>/dev/null || true
- fi
- # for stm32, copy .bin and .hex to out folder
- if [ "$ENV_PLATFORM" == "STM32_PLATFORM" ]; then
- cp .pio/build/$1/firmware.bin out/${FIRMWARE_FILENAME}.bin 2>/dev/null || true
- cp .pio/build/$1/firmware.hex out/${FIRMWARE_FILENAME}.hex 2>/dev/null || true
- fi
- # for rp2040, copy .bin and .uf2 to out folder
- if [ "$ENV_PLATFORM" == "RP2040_PLATFORM" ]; then
- cp .pio/build/$1/firmware.bin out/${FIRMWARE_FILENAME}.bin 2>/dev/null || true
- cp .pio/build/$1/firmware.uf2 out/${FIRMWARE_FILENAME}.uf2 2>/dev/null || true
- fi
- }
- # firmwares containing $1 will be built
- build_all_firmwares_matching() {
- envs=($(get_pio_envs_containing_string "$1"))
- for env in "${envs[@]}"; do
- build_firmware $env
- done
- }
- # firmwares ending with $1 will be built
- build_all_firmwares_by_suffix() {
- envs=($(get_pio_envs_ending_with_string "$1"))
- for env in "${envs[@]}"; do
- build_firmware $env
- done
- }
- build_repeater_firmwares() {
- # # build specific repeater firmwares
- # build_firmware "Heltec_v2_repeater"
- # build_firmware "Heltec_v3_repeater"
- # build_firmware "Xiao_C3_Repeater_sx1262"
- # build_firmware "Xiao_S3_WIO_Repeater"
- # build_firmware "LilyGo_T3S3_sx1262_Repeater"
- # build_firmware "RAK_4631_Repeater"
- # build all repeater firmwares
- build_all_firmwares_by_suffix "_repeater"
- }
- build_companion_firmwares() {
- # # build specific companion firmwares
- # build_firmware "Heltec_v2_companion_radio_usb"
- # build_firmware "Heltec_v2_companion_radio_ble"
- # build_firmware "Heltec_v3_companion_radio_usb"
- # build_firmware "Heltec_v3_companion_radio_ble"
- # build_firmware "Xiao_S3_WIO_companion_radio_ble"
- # build_firmware "LilyGo_T3S3_sx1262_companion_radio_usb"
- # build_firmware "LilyGo_T3S3_sx1262_companion_radio_ble"
- # build_firmware "RAK_4631_companion_radio_usb"
- # build_firmware "RAK_4631_companion_radio_ble"
- # build_firmware "t1000e_companion_radio_ble"
- # build all companion firmwares
- build_all_firmwares_by_suffix "_companion_radio_usb"
- build_all_firmwares_by_suffix "_companion_radio_ble"
- }
- build_companion_wifi_firmwares() {
- build_all_firmwares_by_suffix "_companion_radio_wifi"
- }
- build_repeater_mqtt_firmwares() {
- build_all_firmwares_by_suffix "_repeater_mqtt"
- }
- build_room_server_firmwares() {
- # # build specific room server firmwares
- # build_firmware "Heltec_v3_room_server"
- # build_firmware "RAK_4631_room_server"
- # build all room server firmwares
- build_all_firmwares_by_suffix "_room_server"
- }
- build_firmwares() {
- build_companion_firmwares
- build_repeater_firmwares
- build_room_server_firmwares
- }
- # clean build dir
- rm -rf out
- mkdir -p out
- # handle script args
- if [[ $1 == "build-firmware" ]]; then
- TARGETS=${@:2}
- if [ "$TARGETS" ]; then
- for env in $TARGETS; do
- build_firmware $env
- done
- else
- echo "usage: $0 build-firmware <target>"
- exit 1
- fi
- elif [[ $1 == "build-matching-firmwares" ]]; then
- if [ "$2" ]; then
- build_all_firmwares_matching $2
- else
- echo "usage: $0 build-matching-firmwares <build-match-spec>"
- exit 1
- fi
- elif [[ $1 == "build-firmwares" ]]; then
- build_firmwares
- elif [[ $1 == "build-companion-firmwares" ]]; then
- build_companion_firmwares
- elif [[ $1 == "build-companion-wifi-firmwares" ]]; then
- build_companion_wifi_firmwares
- elif [[ $1 == "build-repeater-firmwares" ]]; then
- build_repeater_firmwares
- elif [[ $1 == "build-repeater-mqtt-firmwares" ]]; then
- build_repeater_mqtt_firmwares
- elif [[ $1 == "build-room-server-firmwares" ]]; then
- build_room_server_firmwares
- fi
|