build.sh 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278
  1. #!/usr/bin/env bash
  2. global_usage() {
  3. cat - <<EOF
  4. Usage:
  5. sh build.sh <command> [target]
  6. Commands:
  7. help|usage|-h|--help: Shows this message.
  8. list|-l: List firmwares available to build.
  9. build-firmware <target>: Build the firmware for the given build target.
  10. build-firmwares: Build all firmwares for all targets.
  11. build-matching-firmwares <build-match-spec>: Build all firmwares for build targets containing the string given for <build-match-spec>.
  12. build-companion-firmwares: Build all companion firmwares for all build targets.
  13. build-repeater-firmwares: Build all repeater firmwares for all build targets.
  14. build-room-server-firmwares: Build all chat room server firmwares for all build targets.
  15. Examples:
  16. Build firmware for the "RAK_4631_repeater" device target
  17. $ sh build.sh build-firmware RAK_4631_repeater
  18. Build all firmwares for device targets containing the string "RAK_4631"
  19. $ sh build.sh build-matching-firmwares <build-match-spec>
  20. Build all companion firmwares
  21. $ sh build.sh build-companion-firmwares
  22. Build all repeater firmwares
  23. $ sh build.sh build-repeater-firmwares
  24. Build all chat room server firmwares
  25. $ sh build.sh build-room-server-firmwares
  26. Environment Variables:
  27. DISABLE_DEBUG=1: Disables all debug logging flags (MESH_DEBUG, MESH_PACKET_LOGGING, etc.)
  28. If not set, debug flags from variant platformio.ini files are used.
  29. Examples:
  30. Build without debug logging:
  31. $ export FIRMWARE_VERSION=v1.0.0
  32. $ export DISABLE_DEBUG=1
  33. $ sh build.sh build-firmware RAK_4631_repeater
  34. Build with debug logging (default, uses flags from variant files):
  35. $ export FIRMWARE_VERSION=v1.0.0
  36. $ sh build.sh build-firmware RAK_4631_repeater
  37. EOF
  38. }
  39. # get a list of pio env names that start with "env:"
  40. get_pio_envs() {
  41. pio project config | grep 'env:' | sed 's/env://'
  42. }
  43. # Catch cries for help before doing anything else.
  44. case $1 in
  45. help|usage|-h|--help)
  46. global_usage
  47. exit 1
  48. ;;
  49. list|-l)
  50. get_pio_envs
  51. exit 0
  52. ;;
  53. esac
  54. # cache project config json for use in get_platform_for_env()
  55. PIO_CONFIG_JSON=$(pio project config --json-output)
  56. # $1 should be the string to find (case insensitive)
  57. get_pio_envs_containing_string() {
  58. shopt -s nocasematch
  59. envs=($(get_pio_envs))
  60. for env in "${envs[@]}"; do
  61. if [[ "$env" == *${1}* ]]; then
  62. echo $env
  63. fi
  64. done
  65. }
  66. # $1 should be the string to find (case insensitive)
  67. get_pio_envs_ending_with_string() {
  68. shopt -s nocasematch
  69. envs=($(get_pio_envs))
  70. for env in "${envs[@]}"; do
  71. if [[ "$env" == *${1} ]]; then
  72. echo $env
  73. fi
  74. done
  75. }
  76. # get platform flag for a given environment
  77. # $1 should be the environment name
  78. get_platform_for_env() {
  79. local env_name=$1
  80. echo "$PIO_CONFIG_JSON" | python3 -c "
  81. import sys, json, re
  82. data = json.load(sys.stdin)
  83. for section, options in data:
  84. if section == 'env:$env_name':
  85. for key, value in options:
  86. if key == 'build_flags':
  87. for flag in value:
  88. match = re.search(r'(ESP32_PLATFORM|NRF52_PLATFORM|STM32_PLATFORM|RP2040_PLATFORM)', flag)
  89. if match:
  90. print(match.group(1))
  91. sys.exit(0)
  92. "
  93. }
  94. # disable all debug logging flags if DISABLE_DEBUG=1 is set
  95. disable_debug_flags() {
  96. if [ "$DISABLE_DEBUG" == "1" ]; then
  97. 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"
  98. fi
  99. }
  100. # build firmware for the provided pio env in $1
  101. build_firmware() {
  102. # get env platform for post build actions
  103. ENV_PLATFORM=($(get_platform_for_env $1))
  104. # get git commit sha
  105. COMMIT_HASH=$(git rev-parse --short HEAD)
  106. # set firmware build date
  107. FIRMWARE_BUILD_DATE=$(date '+%d-%b-%Y')
  108. # get FIRMWARE_VERSION, which should be provided by the environment
  109. if [ -z "$FIRMWARE_VERSION" ]; then
  110. echo "FIRMWARE_VERSION must be set in environment"
  111. exit 1
  112. fi
  113. # set firmware version string
  114. # e.g: v1.0.0-abcdef
  115. FIRMWARE_VERSION_STRING="${FIRMWARE_VERSION}-${COMMIT_HASH}"
  116. # craft filename
  117. # e.g: RAK_4631_Repeater-v1.0.0-SHA
  118. FIRMWARE_FILENAME="$1-${FIRMWARE_VERSION_STRING}"
  119. # add firmware version info to end of existing platformio build flags in environment vars
  120. export PLATFORMIO_BUILD_FLAGS="${PLATFORMIO_BUILD_FLAGS} -DFIRMWARE_BUILD_DATE='\"${FIRMWARE_BUILD_DATE}\"' -DFIRMWARE_VERSION='\"${FIRMWARE_VERSION_STRING}\"'"
  121. # disable debug flags if requested
  122. disable_debug_flags
  123. # build firmware target
  124. pio run -e $1
  125. # build merge-bin for esp32 fresh install, copy .bins to out folder (e.g: Heltec_v3_room_server-v1.0.0-SHA.bin)
  126. if [ "$ENV_PLATFORM" == "ESP32_PLATFORM" ]; then
  127. pio run -t mergebin -e $1
  128. cp .pio/build/$1/firmware.bin out/${FIRMWARE_FILENAME}.bin 2>/dev/null || true
  129. cp .pio/build/$1/firmware-merged.bin out/${FIRMWARE_FILENAME}-merged.bin 2>/dev/null || true
  130. fi
  131. # build .uf2 for nrf52 boards, copy .uf2 and .zip to out folder (e.g: RAK_4631_Repeater-v1.0.0-SHA.uf2)
  132. if [ "$ENV_PLATFORM" == "NRF52_PLATFORM" ]; then
  133. python3 bin/uf2conv/uf2conv.py .pio/build/$1/firmware.hex -c -o .pio/build/$1/firmware.uf2 -f 0xADA52840
  134. cp .pio/build/$1/firmware.uf2 out/${FIRMWARE_FILENAME}.uf2 2>/dev/null || true
  135. cp .pio/build/$1/firmware.zip out/${FIRMWARE_FILENAME}.zip 2>/dev/null || true
  136. fi
  137. # for stm32, copy .bin and .hex to out folder
  138. if [ "$ENV_PLATFORM" == "STM32_PLATFORM" ]; then
  139. cp .pio/build/$1/firmware.bin out/${FIRMWARE_FILENAME}.bin 2>/dev/null || true
  140. cp .pio/build/$1/firmware.hex out/${FIRMWARE_FILENAME}.hex 2>/dev/null || true
  141. fi
  142. # for rp2040, copy .bin and .uf2 to out folder
  143. if [ "$ENV_PLATFORM" == "RP2040_PLATFORM" ]; then
  144. cp .pio/build/$1/firmware.bin out/${FIRMWARE_FILENAME}.bin 2>/dev/null || true
  145. cp .pio/build/$1/firmware.uf2 out/${FIRMWARE_FILENAME}.uf2 2>/dev/null || true
  146. fi
  147. }
  148. # firmwares containing $1 will be built
  149. build_all_firmwares_matching() {
  150. envs=($(get_pio_envs_containing_string "$1"))
  151. for env in "${envs[@]}"; do
  152. build_firmware $env
  153. done
  154. }
  155. # firmwares ending with $1 will be built
  156. build_all_firmwares_by_suffix() {
  157. envs=($(get_pio_envs_ending_with_string "$1"))
  158. for env in "${envs[@]}"; do
  159. build_firmware $env
  160. done
  161. }
  162. build_repeater_firmwares() {
  163. # # build specific repeater firmwares
  164. # build_firmware "Heltec_v2_repeater"
  165. # build_firmware "Heltec_v3_repeater"
  166. # build_firmware "Xiao_C3_Repeater_sx1262"
  167. # build_firmware "Xiao_S3_WIO_Repeater"
  168. # build_firmware "LilyGo_T3S3_sx1262_Repeater"
  169. # build_firmware "RAK_4631_Repeater"
  170. # build all repeater firmwares
  171. build_all_firmwares_by_suffix "_repeater"
  172. }
  173. build_companion_firmwares() {
  174. # # build specific companion firmwares
  175. # build_firmware "Heltec_v2_companion_radio_usb"
  176. # build_firmware "Heltec_v2_companion_radio_ble"
  177. # build_firmware "Heltec_v3_companion_radio_usb"
  178. # build_firmware "Heltec_v3_companion_radio_ble"
  179. # build_firmware "Xiao_S3_WIO_companion_radio_ble"
  180. # build_firmware "LilyGo_T3S3_sx1262_companion_radio_usb"
  181. # build_firmware "LilyGo_T3S3_sx1262_companion_radio_ble"
  182. # build_firmware "RAK_4631_companion_radio_usb"
  183. # build_firmware "RAK_4631_companion_radio_ble"
  184. # build_firmware "t1000e_companion_radio_ble"
  185. # build all companion firmwares
  186. build_all_firmwares_by_suffix "_companion_radio_usb"
  187. build_all_firmwares_by_suffix "_companion_radio_ble"
  188. }
  189. build_room_server_firmwares() {
  190. # # build specific room server firmwares
  191. # build_firmware "Heltec_v3_room_server"
  192. # build_firmware "RAK_4631_room_server"
  193. # build all room server firmwares
  194. build_all_firmwares_by_suffix "_room_server"
  195. }
  196. build_firmwares() {
  197. build_companion_firmwares
  198. build_repeater_firmwares
  199. build_room_server_firmwares
  200. }
  201. # clean build dir
  202. rm -rf out
  203. mkdir -p out
  204. # handle script args
  205. if [[ $1 == "build-firmware" ]]; then
  206. TARGETS=${@:2}
  207. if [ "$TARGETS" ]; then
  208. for env in $TARGETS; do
  209. build_firmware $env
  210. done
  211. else
  212. echo "usage: $0 build-firmware <target>"
  213. exit 1
  214. fi
  215. elif [[ $1 == "build-matching-firmwares" ]]; then
  216. if [ "$2" ]; then
  217. build_all_firmwares_matching $2
  218. else
  219. echo "usage: $0 build-matching-firmwares <build-match-spec>"
  220. exit 1
  221. fi
  222. elif [[ $1 == "build-firmwares" ]]; then
  223. build_firmwares
  224. elif [[ $1 == "build-companion-firmwares" ]]; then
  225. build_companion_firmwares
  226. elif [[ $1 == "build-repeater-firmwares" ]]; then
  227. build_repeater_firmwares
  228. elif [[ $1 == "build-room-server-firmwares" ]]; then
  229. build_room_server_firmwares
  230. fi