build_example 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229
  1. #!/usr/bin/env bash
  2. #
  3. # Usage:
  4. #
  5. # build_example -b|--base=<path> - Configurations root folder (e.g., ./.pio/build-BRANCH)
  6. # -c|--config=<rel> - Sub-path of the configs to build (within config/examples)
  7. # [-e|--export=N] - Use CONFIG_EXPORT N to export the config to the export location
  8. # [-a|--archive] - Archive the build (to the export location)
  9. # [-o|--output] - Redirect export / archiving to another location
  10. # (By default export to origin config folder)
  11. # [-f|--nofail] - Don't stop on a failed build
  12. # [-w|--nowarn] - Suppress warnings with extra config options
  13. # [-r|--reveal] - Reveal the config/export folder after the build
  14. # [-h|--help] - Print usage and exit
  15. # [--allow] - Allow this script to run standalone
  16. #
  17. usage() { echo "Usage:
  18. build_example -b|--base=<path> - Configurations root folder (e.g., ./.pio/build-BRANCH)
  19. -c|--config=<rel> - Sub-path of the configs to build (within config/examples)
  20. [-e|--export=N] - Use CONFIG_EXPORT N to export the config to the export location
  21. [-a|--archive] - Archive the build (to the export location)
  22. [-o|--output] - Redirect export / archiving to another location
  23. (By default export to origin config folder)
  24. [-f|--nofail] - Don't stop on a failed build
  25. [-w|--nowarn] - Suppress warnings with extra config options
  26. [-r|--reveal] - Reveal the config/export folder after the build
  27. [-h|--help] - Print usage and exit
  28. [--allow] - Allow this script to run standalone
  29. "
  30. }
  31. HERE=`dirname $0`
  32. PATH="$HERE:$PATH"
  33. . mfutil
  34. annc() { echo -e "\033[0;32m$1\033[0m" ; }
  35. alrt() { echo -e "\033[0;31m$1\033[0m" ; }
  36. # Get arguments
  37. BUILD=./.pio/build
  38. CLEANER=
  39. ALLOW=
  40. ARCHIVE=
  41. BASE=
  42. CONFIG=
  43. REVEAL=
  44. EXPNUM=
  45. NOFAIL=
  46. OUTBASE=
  47. while getopts 'ab:c:e:fhio:r-:' OFLAG; do
  48. case "${OFLAG}" in
  49. a) ARCHIVE=1 ;;
  50. b) BASE="${OPTARG%/}" ;;
  51. c) CONFIG="${OPTARG%/}" ;;
  52. e) EXPNUM="$OPTARG" ;;
  53. o) OUTBASE="${OPTARG%/}" ;;
  54. h) EXIT_USAGE=1 ; break ;;
  55. f) NOFAIL=1 ;;
  56. r) REVEAL=1 ;;
  57. -) ONAM="${OPTARG%%=*}" ; OVAL="${OPTARG#*=}"
  58. case "$ONAM" in
  59. archive) ARCHIVE=1 ;;
  60. allow) ALLOW=1 ;;
  61. base) BASE="${OVAL%/}" ;;
  62. config) CONFIG="${OVAL%/}" ;;
  63. export) EXPNUM="$OVAL" ;;
  64. output) OUTBASE="${OVAL%/}" ;;
  65. help) EXIT_USAGE=1 ; break ;;
  66. nofail) NOFAIL=1 ;;
  67. reveal) REVEAL=1 ;;
  68. *) EXIT_USAGE=2 ; echo "$SELF: unrecognized option \`--$ONAM'" ; break ;;
  69. esac
  70. ;;
  71. *) EXIT_USAGE=2 ; break ;;
  72. esac
  73. done
  74. shift $((OPTIND - 1))
  75. # Must be called from another script (or with --allow)
  76. [[ $ALLOW || $SHLVL -gt 2 ]] || { echo "Don't call this script directly, use build_all_examples instead." ; exit 1 ; }
  77. # Exit with helpful usage information
  78. ((EXIT_USAGE)) && { usage ; let EXIT_USAGE-- ; exit $EXIT_USAGE ; }
  79. # -b|--base and -c|--config are required
  80. [[ -z $BASE ]] && { echo "-b|--base is required" ; exit 1 ; }
  81. [[ -z $CONFIG ]] && { echo "-c|--config is required" ; exit 1 ; }
  82. # Expand ~ to $HOME in provided arguments
  83. BASE=${BASE/#\~/$HOME}
  84. CONFIG=${CONFIG/#\~/$HOME}
  85. # Make sure the examples exist
  86. SUB1="$BASE/config/examples"
  87. [[ -d "$SUB1" ]] || { echo "-b|--base $BASE doesn't contain config/examples" ; exit 1 ; }
  88. # Make sure the specific config folder exists
  89. SUB="$SUB1/$CONFIG"
  90. [[ -d "$SUB" ]] || { echo "-c|--config $CONFIG doesn't exist" ; exit 1 ; }
  91. # ...and contains Configuration.h or Configuration_adv.h
  92. [[ -f "$SUB"/Configuration.h || -f "$SUB"/Configuration_adv.h ]] || { echo "No configuration files found in $SUB" ; exit 1 ; }
  93. # Get the location for exports and archives
  94. if [[ -n $OUTBASE ]]; then
  95. ARCSUB="${OUTBASE/#\~/$HOME}/$CONFIG"
  96. mkdir -p "$ARCSUB"
  97. else
  98. ARCSUB="$SUB"
  99. fi
  100. # Delete any config files from previous builds
  101. rm -f Marlin/_Bootscreen.h Marlin/_Statusscreen.h
  102. # Copy configurations into the Marlin folder
  103. echo "Getting configuration files from $SUB"
  104. cp "$BASE"/config/default/*.h Marlin/
  105. cp "$SUB"/*.h Marlin/
  106. rm -f Marlin/Config.h Marlin/Config-export.h
  107. set -e
  108. # Strip #error lines from Configuration.h using
  109. awk 'NR < 20 || NR > 30 || !/#error/' Marlin/Configuration.h > Marlin/Configuration.h~
  110. mv Marlin/Configuration.h~ Marlin/Configuration.h
  111. # Hide several warnings when not exporting
  112. [[ -z $EXPNUM ]] && CLEANER=1
  113. # Suppress fatal warnings
  114. if ((CLEANER)); then
  115. opt_add NO_CONTROLLER_CUSTOM_WIRING_WARNING
  116. opt_add NO_AUTO_ASSIGN_WARNING
  117. opt_add NO_CREALITY_DRIVER_WARNING
  118. opt_add DIAG_JUMPERS_REMOVED
  119. opt_add DIAG_PINS_REMOVED
  120. opt_add NO_MK3_FAN_PINS_WARNING
  121. opt_add NO_USER_FEEDBACK_WARNING
  122. opt_add NO_Z_SAFE_HOMING_WARNING
  123. opt_add NO_LCD_CONTRAST_WARNING
  124. opt_add NO_MICROPROBE_WARNING
  125. opt_add NO_CONFIGURATION_EMBEDDING_WARNING
  126. opt_add NO_HOMING_CURRENT_WARNING
  127. fi
  128. # Possible exported file names (in the build folder)
  129. ENAME=("-name" "marlin_config.json" \
  130. "-o" "-name" "config.ini" \
  131. "-o" "-name" "schema.json" \
  132. "-o" "-name" "schema.yml")
  133. # Possible built firmware names (in the build folder)
  134. BNAME=("-name" 'firmware*.hex' \
  135. "-o" "-name" "firmware*.bin" \
  136. "-o" "-name" "project*.bin" \
  137. "-o" "-name" "Robin*.bin" \
  138. "-o" "-name" "main_*.bin")
  139. mkdir -p "$BUILD"
  140. # If EXPNUM is set then apply to the config before build
  141. if [[ $EXPNUM ]]; then
  142. opt_set CONFIG_EXPORT $EXPNUM
  143. # Clean up old exports
  144. find "$BUILD" \( "${ENAME[@]}" \) -exec rm "{}" \;
  145. fi
  146. ((ARCHIVE)) && find "$BUILD" \( "${BNAME[@]}" \) -exec rm "{}" \;
  147. set +e
  148. echo "Building example $CONFIG ..."
  149. mftest -s -a -n1 ; ERR=$?
  150. ((ERR)) && alrt "Failed ($ERR)" || annc "Success"
  151. set -e
  152. if [[ $ERR -gt 0 ]]; then
  153. # Error? For --nofail simply log. Otherwise return the error.
  154. if [[ -n $NOFAIL ]]; then
  155. date +"%F %T [FAIL] $CONFIG" >>./.pio/error-log.txt
  156. else
  157. exit $ERR
  158. fi
  159. else
  160. # Copy exports back to the configs
  161. if [[ -n $EXPNUM ]]; then
  162. annc "Exporting $EXPNUM"
  163. [[ -f Marlin/Config-export.h ]] && { cp Marlin/Config-export.h "$ARCSUB"/Config.h ; }
  164. find "$BUILD" \( "${ENAME[@]}" \) -exec cp "{}" "$ARCSUB" \;
  165. fi
  166. # Copy potential firmware files into the config folder
  167. # TODO: Consider firmware that needs an STM32F4_UPDATE folder.
  168. # Currently only BOARD_CREALITY_F401RE env:STM32F401RE_creality
  169. if ((ARCHIVE)); then
  170. annc "Archiving"
  171. rm -f "$ARCSUB"/*.tar.gz "$ARCSUB"/*.sha256.txt
  172. find "$BUILD" \( "${BNAME[@]}" \) -exec sh -c '
  173. ARCSUB="$1"
  174. CONFIG="$2"
  175. shift 2
  176. for FILE in "$@"; do
  177. cd "${FILE%/*}"
  178. NAME=${FILE##*/}
  179. SHRT=${NAME%.*}
  180. SHASUM=$(sha256sum "$NAME" | cut -d" " -f1)
  181. tar -czf "$ARCSUB/$SHRT.tar.gz" "$NAME"
  182. echo "$CONFIG\n$SHASUM" > "$ARCSUB/$NAME.sha256.txt"
  183. rm "$NAME"
  184. cd - >/dev/null
  185. done
  186. ' sh "$ARCSUB" "$CONFIG" {} +
  187. fi
  188. # Reveal the configs after the build, if requested
  189. ((REVEAL)) && { annc "Revealing $ARCSUB" ; open "$ARCSUB" ; }
  190. fi
  191. exit 0