diff --git a/buildroot/bin/build_all_examples b/buildroot/bin/build_all_examples index c2b0007b0c2f..595cfad839fd 100755 --- a/buildroot/bin/build_all_examples +++ b/buildroot/bin/build_all_examples @@ -11,6 +11,7 @@ # [-f|--nofail] - Don't stop on a failed build # [-h|--help] - Print usage and exit # [-l|--limit=#] - Limit the number of builds in this run +# [-m|--many] - Build all the environments for each example # [-n|--nobuild] - Don't actually build anything # [-o|--output] - Redirect export / archiving to another location # (By default export to origin config folders) @@ -38,6 +39,7 @@ build_all_examples [-a|--archive] - Copy the binary to the export locati [-f|--nofail] - Don't stop on a failed build [-h|--help] - Print usage and exit [-l|--limit=#] - Limit the number of builds in this run + [-m|--many] - Build all the environments for each example [-n|--nobuild] - Don't actually build anything [-o|--output] - Redirect export / archiving to another location (By default export to origin config folders) @@ -53,7 +55,7 @@ unset FIRST_CONF EXIT_USAGE= LIMIT=1000 -while getopts 'aB:b:cde:fhl:no:pr:sv-:' OFLAG; do +while getopts 'aB:b:cde:fhl:mno:pr:sv-:' OFLAG; do case "${OFLAG}" in a) ARCHIVE=1 ; bugout "Archiving" ;; B) CBASE=${OPTARG%/} ; bugout "Base: $CBASE" ;; @@ -64,6 +66,7 @@ while getopts 'aB:b:cde:fhl:no:pr:sv-:' OFLAG; do f) NOFAIL=1 ; bugout "Continue on Fail" ;; h) EXIT_USAGE=1 ; break ;; l) LIMIT=$OPTARG ; bugout "Limit to $LIMIT build(s)" ;; + m) MANY=1 ; bugout "Many Envs" ;; n) DRYRUN=1 ; bugout "Dry Run" ;; o) OUTBASE="${OPTARG%/}" ; bugout "Archive to $OUTBASE" ;; p) PURGE=1 ; bugout "Purge stat file" ;; @@ -74,6 +77,7 @@ while getopts 'aB:b:cde:fhl:no:pr:sv-:' OFLAG; do archive) ARCHIVE=1 ; bugout "Archiving" ;; base) CBASE=${OVAL%/} ; bugout "Base: $CBASE" ;; branch) BRANCH=$OVAL ; bugout "Branch: $BRANCH" ;; + many) MANY=1 ; bugout "Many Envs" ;; nofail) NOFAIL=1 ; bugout "Continue on Fail" ;; resume) ISRES=1 ; FIRST_CONF=$OVAL ; bugout "Resume: $FIRST_CONF" ;; continue) CONTINUE=1 ; bugout "Continue" ;; @@ -179,6 +183,9 @@ find -ds "$CBASE"/config/examples -type d -name 'Configuration.h' -o -name 'Conf # Exporting? Add -e argument ((CEXPORT)) && CARGS+=("-e" "$CEXPORT") + # Build many environments? Add -m argument + ((NOFAIL)) && CARGS+=("-m") + # Continue on fail? Add -f argument ((NOFAIL)) && CARGS+=("-f") diff --git a/buildroot/bin/build_example b/buildroot/bin/build_example index 566919abd665..623da8ac84c1 100755 --- a/buildroot/bin/build_example +++ b/buildroot/bin/build_example @@ -5,6 +5,7 @@ # build_example -b|--base= - Configurations root folder (e.g., ./.pio/build-BRANCH) # -c|--config= - Sub-path of the configs to build (within config/examples) # [-n|--index=N] - Which environment to build, by index (Based on pins.h comments) +# [-m|--many] - Build all the board's environments listed in pins.h # [-e|--export=N] - Use CONFIG_EXPORT N to export the config to the export location # [-a|--archive] - Archive the build (to the export location) # [-o|--output] - Redirect export / archiving to another location @@ -21,6 +22,7 @@ usage() { echo "Usage: build_example -b|--base= - Configurations root folder (e.g., ./.pio/build-BRANCH) -c|--config= - Sub-path of the configs to build (within config/examples) [-n|--index=N] - Which environment to build, by index (Based on pins.h comments) + [-m|--many] - Build all the board's environments listed in pins.h [-e|--export=N] - Use CONFIG_EXPORT N to export the config to the export location [-a|--archive] - Archive the build (to the export location) [-o|--output] - Redirect export / archiving to another location @@ -53,8 +55,9 @@ EXPNUM= NOFAIL= OUTBASE= BUILDINDEX=1 +MANY= -while getopts 'ab:c:e:fhn:o:r-:' OFLAG; do +while getopts 'ab:c:e:fhmn:o:r-:' OFLAG; do case "${OFLAG}" in a) ARCHIVE=1 ;; b) BASE="${OPTARG%/}" ;; @@ -62,6 +65,7 @@ while getopts 'ab:c:e:fhn:o:r-:' OFLAG; do e) EXPNUM="$OPTARG" ;; f) NOFAIL=1 ;; h) EXIT_USAGE=1 ; break ;; + m) MANY=1 ;; n) BUILDINDEX="$OPTARG" ;; o) OUTBASE="${OPTARG%/}" ;; r) REVEAL=1 ;; @@ -71,6 +75,7 @@ while getopts 'ab:c:e:fhn:o:r-:' OFLAG; do allow) ALLOW=1 ;; base) BASE="${OVAL%/}" ;; config) CONFIG="${OVAL%/}" ;; + many) MANY=1 ;; index) BUILDINDEX="$OVAL" ;; export) EXPNUM="$OVAL" ;; output) OUTBASE="${OVAL%/}" ;; @@ -178,68 +183,107 @@ fi ((ARCHIVE)) && find "$BUILD" -type f \( "${BNAME[@]}" \) -exec rm "{}" \; -set +e +echo "Building example $CONFIG..." + +# If doing many builds get a list of all environment names, +# which also gives us the number of environments. +if ((MANY)); then + ENVLIST=$(mfenvs) # BOARD_NAME_STRING (1234): [ env1 env2 env3 ... ] + ENVLIST=${ENVLIST##*: [ } + ENVARRAY=(${ENVLIST% ]}) + ENVCOUNT=${#ENVARRAY[*]} + ((ENVCOUNT)) || { alrt "mfenvs failed for this board." ; exit 1 ; } + echo "Found $ENVCOUNT environment(s): ${ENVARRAY[*]}" +fi -echo "Building example $CONFIG ..." -mftest -s -a -n$BUILDINDEX ; ERR=$? +# Run one or more builds based on --many +# Build all from BUILDINDEX onward (usually 1) meaning ALL. +# MANY with a BUILDINDEX may be useful for continuing an interrupted build. -((ERR)) && alrt "Failed ($ERR)" || annc "Success" +while ((1)); do + set +e -set -e + echo "Building example $CONFIG ($BUILDINDEX)..." + + # Run a build and record the error number + mftest -s -a -n$BUILDINDEX ; ERR=$? + + # "Index out of range" can fail without an error + ((MANY)) && ((ERR == 66)) && ERR=0 && break # "index out of range" + + # Short message reporting Error or Success + ((ERR)) && alrt "Failed ($ERR)" || annc "Success" + + set -e -if [[ $ERR -gt 0 ]]; then + if [[ $ERR -gt 0 ]]; then + + # Error? For --nofail simply log. Otherwise return the error. + if [[ -n $NOFAIL ]]; then + date +"%F %T [FAIL] $CONFIG" >>./.pio/error-log.txt + else + exit $ERR + fi - # Error? For --nofail simply log. Otherwise return the error. - if [[ -n $NOFAIL ]]; then - date +"%F %T [FAIL] $CONFIG" >>./.pio/error-log.txt else - exit $ERR - fi -else + # Copy exports back to the configs + if [[ -n $EXPNUM ]]; then + annc "Exporting $EXPNUM" + [[ -f Marlin/Config-export.h ]] && { cp Marlin/Config-export.h "$ARCSUB"/Config.h ; } + find "$BUILD" -type f \( "${ENAME[@]}" \) -exec cp "{}" "$ARCSUB" \; + fi + + # When building many, create sub-folders for each build env name + if [[ -n $MANY && $ENVCOUNT -gt 1 ]]; then + ENV=${ENVARRAY[BUILDINDEX-1]} + ARCENVSUB="$ARCSUB/$ENV" + else + ARCENVSUB="$ARCSUB" + fi + + # Copy potential firmware files into the config folder + # TODO: Consider firmware that needs an STM32F4_UPDATE folder. + # Currently only BOARD_CREALITY_F401RE env:STM32F401RE_creality + if ((ARCHIVE)); then + annc "Archiving" + find "$BUILD" -type f \( "${BNAME[@]}" \) -exec sh -c ' + ARCDIR="$1" ; CONFIG="$2" ; FILE="$3" ; shift 3 + NAME=${FILE##*/} ; SHRT=${NAME%.*} ; DIR=${FILE%/*} + ZIPX= + if [[ $CONFIG == *Simulator* ]]; then + case $(uname | tr '[:upper:]' '[:lower:]') in + darwin) SUB="macOS" ; ZIPX="-X" ;; + *linux) SUB="Linux" ;; + win*) SUB="Windows" ;; + msys*) SUB="Windows" ;; + cygwin*) SUB="Windows" ;; + mingw*) SUB="Windows" ;; + *) SUB='Unix' ;; + esac + ARCH=$(uname -m | tr '[:lower:]' '[:upper:]') + ARCDIR="$ARCDIR/$SUB-$ARCH" + fi + mkdir -p "$ARCDIR" + rm -f "$ARCDIR"/*.zip "$ARCDIR"/*.sha256.txt + cd "$DIR" + SHASUM=$(sha256sum "$NAME" | cut -d" " -f1) + echo "$CONFIG\n$SHASUM" > "$ARCDIR/$NAME.sha256.txt" + zip $ZIPX "$ARCDIR/$SHRT.zip" "$NAME" && rm "$NAME" + cd - >/dev/null + ' sh "$ARCENVSUB" "$CONFIG" {} + + fi + + # Reveal the configs after the build, if requested + ((REVEAL)) && { annc "Revealing $ARCENVSUB" ; open "$ARCENVSUB" ; } - # Copy exports back to the configs - if [[ -n $EXPNUM ]]; then - annc "Exporting $EXPNUM" - [[ -f Marlin/Config-export.h ]] && { cp Marlin/Config-export.h "$ARCSUB"/Config.h ; } - find "$BUILD" -type f \( "${ENAME[@]}" \) -exec cp "{}" "$ARCSUB" \; fi - # Copy potential firmware files into the config folder - # TODO: Consider firmware that needs an STM32F4_UPDATE folder. - # Currently only BOARD_CREALITY_F401RE env:STM32F401RE_creality - if ((ARCHIVE)); then - annc "Archiving" - find "$BUILD" -type f \( "${BNAME[@]}" \) -exec sh -c ' - ARCSUB="$1" ; CONFIG="$2" ; FILE="$3" ; shift 3 - NAME=${FILE##*/} ; SHRT=${NAME%.*} ; DIR=${FILE%/*} - ZIPX= - if [[ $CONFIG == *Simulator* ]]; then - case $(uname | tr '[:upper:]' '[:lower:]') in - darwin) SUB="macOS" ; ZIPX="-X" ;; - *linux) SUB="Linux" ;; - win*) SUB="Windows" ;; - msys*) SUB="Windows" ;; - cygwin*) SUB="Windows" ;; - mingw*) SUB="Windows" ;; - *) SUB='Unix' ;; - esac - ARCH=$(uname -m | tr '[:lower:]' '[:upper:]') - ARCSUB="$ARCSUB/$SUB-$ARCH" - fi - mkdir -p "$ARCSUB" - rm -f "$ARCSUB"/*.zip "$ARCSUB"/*.sha256.txt - cd "$DIR" - SHASUM=$(sha256sum "$NAME" | cut -d" " -f1) - echo "$CONFIG\n$SHASUM" > "$ARCSUB/$NAME.sha256.txt" - zip $ZIPX "$ARCSUB/$SHRT.zip" "$NAME" && rm "$NAME" - cd - >/dev/null - ' sh "$ARCSUB" "$CONFIG" {} + - fi + ((MANY)) || break # Only one build if not --many - # Reveal the configs after the build, if requested - ((REVEAL)) && { annc "Revealing $ARCSUB" ; open "$ARCSUB" ; } + # Set up for the next build, if there is one + ((++BUILDINDEX > ENVCOUNT)) && break -fi +done exit 0 diff --git a/buildroot/bin/mfenvs b/buildroot/bin/mfenvs new file mode 100755 index 000000000000..3c726af53c8d --- /dev/null +++ b/buildroot/bin/mfenvs @@ -0,0 +1,33 @@ +#!/usr/bin/env bash +# +# mfenvs Print the current board and environment information +# Output -> "SHORT_NAME (###): [ env1 env2 env3 ... ]" +# + +[[ -d Marlin/src ]] || { echo "Please 'cd' to the Marlin repo root." ; exit 1 ; } +which pio >/dev/null || { echo "Make sure 'pio' is in your execution PATH." ; exit 1 ; } + +errout() { echo -e "\033[0;31m$1\033[0m" ; } + +case $(uname | tr '[:upper:]' '[:lower:]') in + darwin) SYS='mac' ;; + *linux) SYS='lin' ;; + win*) SYS='win' ;; + msys*) SYS='win' ;; + cygwin*) SYS='win' ;; + mingw*) SYS='win' ;; + *) SYS='uni' ;; +esac + +ACODE='/^[[:space:]]*#define[[:space:]]MOTHERBOARD[[:space:]]/ { sub(/^BOARD_/, "", $3); print $3 }' +MB=$(awk "$ACODE" Marlin/Configuration.h 2>/dev/null) +[[ -z $MB ]] && MB=$(awk "$ACODE" Marlin/Config.h 2>/dev/null) +[[ -z $MB ]] && { echo "Error - Can't read MOTHERBOARD setting." ; exit 1 ; } +BLINE=$( grep -E "define\s+BOARD_$MB\b" Marlin/src/core/boards.h ) +BNUM=$( sed -E 's/^.+BOARD_[^ ]+ +([0-9]+).+$/\1/' <<<"$BLINE" ) +[[ -z $BNUM ]] && { echo "Error - Can't find BOARD_$MB in core/boards.h." ; exit 1 ; } +ENVS=( $( grep -EA1 "MB\(.*\b$MB\b.*\)" Marlin/src/pins/pins.h | grep -E "#include.+//.+(env|$SYS):[^ ]+" | grep -oE "(env|$SYS):[^ ]+" | sed -E "s/(env|$SYS)://" ) ) +[[ -z $ENVS ]] && { errout "Error - Can't find target(s) for $MB ($BNUM)." ; exit 1 ; } +ECOUNT=${#ENVS[*]} +[[ $ECOUNT == 1 ]] && EOUT=$ENVS || EOUT="${ENVS[@]}" +echo "$MB ($BNUM): [ $EOUT ]" diff --git a/buildroot/bin/mftest b/buildroot/bin/mftest index 57aa95400cec..07601654aa91 100755 --- a/buildroot/bin/mftest +++ b/buildroot/bin/mftest @@ -196,7 +196,7 @@ if ((AUTO_BUILD)); then fi else echo "Detected \"$BDESC\" | $MB ($BNUM)." - [[ $CHOICE > $ECOUNT ]] && { echo "Environment selection out of range." ; exit 1 ; } + [[ $CHOICE > $ECOUNT ]] && { echo "Environment selection out of range." ; exit 66 ; } fi TARGET="${ENVS[$CHOICE-1]}" if [[ $MB == 'SIMULATED' && $TARGET == 'linux_native' ]]; then diff --git a/buildroot/share/git/mfhelp b/buildroot/share/git/mfhelp index cbdd6ec4ef95..bbf713a9267c 100755 --- a/buildroot/share/git/mfhelp +++ b/buildroot/share/git/mfhelp @@ -12,6 +12,7 @@ Marlin Firmware Commands: mfadd ....... Fetch a remote branch from any Marlin fork mfclean ..... Attempt to clean up merged and deleted branches mfdoc ....... Build the website, serve locally, and browse + mfenvs ...... Get current board SHORT_NAME (###): [ env1 env2 ... ] mffp ........ Push new commits directly to MarlinFirmware mfinfo ...... Provide branch information (for the other scripts) mfinit ...... Create an 'upstream' remote for 'MarlinFirmare'