Script to download & build Configurations (#20992)

Co-authored-by: Scott Lahteine <thinkyhead@users.noreply.github.com>
This commit is contained in:
X-Ryl669
2021-02-15 12:48:11 +01:00
committed by GitHub
parent 79ee2fa20a
commit d86910ce94
3 changed files with 97 additions and 0 deletions

View File

@@ -0,0 +1,62 @@
#!/usr/bin/env bash
echo "This script will attempt to build Marlin for all known configurations."
echo "In case of failure, the current configuration remains in your repository."
echo "To revert to your current version, run 'git checkout -f'."
self=`basename "$0"`
HERE=`dirname "$0"`
# Check dependencies
which curl 1>/dev/null 2>&1 || { echo "curl not found, please install it"; exit ; }
which git 1>/dev/null 2>&1 || { echo "git not found, please install it"; exit ; }
if [ -z "$1" ]; then
echo ""
echo "ERROR: "
echo " Expected parameter: $self base_branch [resume_point]"
echo " with:"
echo " base_branch The branch in the Configuration repository to use"
echo " resume_point If not empty, resume building from this board"
exit
fi
# Check if called in the right folder
if [ ! -e "Marlin/src" ]; then
echo "This script must be called from the root folder of a Marlin repository, please navigate to this folder and call:"
echo "buildroot/ci-check/$self $1"
exit
fi
# Check if the current repository has unmerged changes
if [ -z "$2" ]; then
git diff --quiet || { echo "Your current repository is not clean. Either commit your change or stash them, and re-run this script"; exit ; }
else
echo "Resuming from $2"
fi
TMPDIR=`mktemp -d`
# Ok, let's do our stuff now
# First extract the current temporary folder
echo "Fetching configuration repository"
if [ ! -e "$TMPDIR/README.md" ]; then
git clone --single-branch --branch "$1" https://github.com/MarlinFirmware/Configurations.git "$TMPDIR" || { echo "Failed to clone the configuration repository"; exit ; }
rm -r $TMPDIR/.git
fi
echo
echo "Start building now..."
echo "====================="
shopt -s nullglob
for config in $TMPDIR/config/examples/*/; do
[ -d "${config}" ] || continue
base=`basename "$config"`
if [ ! -z "$2" ] && [ "$2" != "$base" ]; then
echo "Skipping $base..."
continue
fi
"$HERE/build_example" "internal" "$TMPDIR" "$base" || { echo "Failed to build $base"; exit ; }
done
rm -r "$TMPDIR"

35
buildroot/bin/build_example Executable file
View File

@@ -0,0 +1,35 @@
#!/usr/bin/env bash
if [ "$1" != "internal" ]; then
echo "Don't call this script directly, use build_all_examples instead."
exit 1
fi
SED=$(which gsed || which sed)
HERE=`dirname "$0"`
echo "Testing $3:"
shopt -s nullglob
for sub in find $2/config/examples/$3 -type d; do
[[ -d $sub ]] || continue
base=`basename "$sub"`
if [[ ! -f $sub/Configuration.h ]] && [[ ! -f $sub/Configuration_adv.h ]]; then
echo "No configuration files found in $sub"
continue
fi
echo "Getting configuration files from $sub"
cp "$2/config/default"/*.h Marlin/
cp "$sub"/Configuration.h Marlin/ 2>/dev/null
cp "$sub"/Configuration_adv.h Marlin/ 2>/dev/null
cp "$sub"/_Bootscreen.h Marlin/ 2>/dev/null
cp "$sub"/_Statusscreen.h Marlin/ 2>/dev/null
echo "Building the firmware now..."
echo "$HERE/mftest" -a || exit 1
done
echo "Success"
exit 0

313
buildroot/bin/mftest Executable file
View File

@@ -0,0 +1,313 @@
#!/usr/bin/env bash
#
# mftest Select a test to apply and build
# mftest -b [#] Build the auto-detected environment
# mftest -u [#] Upload the auto-detected environment
# mftest [name] [index] [-y] Set config options and optionally build a test
#
MFINFO=$(mfinfo) || exit 1
[[ -d Marlin/src ]] || { echo "Please 'cd' to the Marlin repo root." ; exit 1 ; }
perror() { echo -e "$0: \033[0;31m$1 -- $2\033[0m" ; }
errout() { echo -e "\033[0;31m$1\033[0m" ; }
bugout() { ((DEBUG)) && echo -e "\033[0;32m$1\033[0m" ; }
usage() {
echo "
Usage: mftest [-t|--env=<env>] [-n|--num=<num>] [-m|--make] [-y|--build=<Y|n>]
mftest [-a|--autobuild]
mftest [-r|--rebuild]
mftest [-u|--autoupload] [-n|--num=<num>]
OPTIONS
-t --env The environment of the test to apply / run. (As named in platformio.ini.)
-n --num The index of the test to run. (In *-tests file order.)
-m --make Use the make / Docker method for the build.
-y --build Skip 'Do you want to build this test?' and assume YES.
-h --help Print this help.
-a --autobuild PIO Build using the MOTHERBOARD environment.
-u --autoupload PIO Upload using the MOTHERBOARD environment.
-v --verbose Extra output for debugging.
env shortcuts: tree due esp lin lpc|lpc8 lpc9 m128 m256|mega stm|f1 f4 f7 s6 teensy|t31|t32 t35|t36 t40|t41
"
}
TESTPATH=buildroot/tests
STATE_FILE=$( echo ./.pio/.mftestrc )
SED=$(which gsed || which sed)
shopt -s extglob nocasematch
# Matching patterns
ISNUM='^[0-9]+$'
ISCMD='^(restore|opt|exec|use|pins|env)_'
ISEXEC='^exec_'
ISCONT='\\ *$'
# Get environment, test number, etc. from the command
TESTENV='-'
CHOICE=0
DEBUG=0
while getopts 'abhmruvyn:t:-:' OFLAG; do
case "${OFLAG}" in
a) AUTO_BUILD=1 ; bugout "Auto-Build target..." ;;
h) EXIT_USAGE=1 ;;
m) USE_MAKE=1 ; bugout "Using make with Docker..." ;;
n) case "$OPTARG" in
*[!0-9]*) perror "option requires a number" $OFLAG ; EXIT_USAGE=1 ;;
*) CHOICE="$OPTARG" ; bugout "Got a number: $CHOICE" ;;
esac
;;
r) REBUILD=1 ; bugout "Rebuilding previous..." ;;
t) TESTENV="$OPTARG" ; bugout "Got a target: $TESTENV" ;;
u) AUTO_BUILD=2 ; bugout "Auto-Upload target..." ;;
v) DEBUG=1 ; bugout "Debug ON" ;;
y) BUILD_YES='Y' ; bugout "Build will initiate..." ;;
-) IFS="=" read -r ONAM OVAL <<< "$OPTARG"
case "$ONAM" in
help) [[ -z "$OVAL" ]] || perror "option can't take value $OVAL" $ONAM ; EXIT_USAGE=1 ;;
autobuild) AUTO_BUILD=1 ; bugout "Auto-Build target..." ;;
autoupload) AUTO_BUILD=2 ; bugout "Auto-Upload target..." ;;
env) case "$OVAL" in
'') perror "option requires a value" $ONAM ; EXIT_USAGE=1 ;;
*) TESTENV="$OVAL" ; bugout "Got a target: $TESTENV" ;;
esac
;;
num) case "$OVAL" in
[0-9]+) CHOICE="$OVAL" ; bugout "Got a number: $CHOICE" ;;
*) perror "option requires a value" $ONAM ; EXIT_USAGE=1 ;;
esac
;;
rebuild) REBUILD=1 ; bugout "Rebuilding previous..." ;;
make) USE_MAKE=1 ; bugout "Using make with Docker..." ;;
debug|verbose) DEBUG=1 ; bugout "Debug ON" ;;
build) case "$OVAL" in
''|y|yes) BUILD_YES='Y' ;;
n|no) BUILD_YES='N' ;;
*) perror "option value must be y, n, yes, or no" $ONAM ; EXIT_USAGE=1 ;;
esac
bugout "Build will initiate? ($BUILD_YES)"
;;
*) perror "Unknown flag" "$OPTARG" ; EXIT_USAGE=1 ;;
esac
;;
esac
done
((EXIT_USAGE)) && { usage ; exit 1 ; }
if ((REBUILD)); then
bugout "Rebuilding previous..."
# Build with the last-built env
[[ -f "$STATE_FILE" ]] || { errout "No previous (-r) build state found." ; exit 1 ; }
read TESTENV <"$STATE_FILE"
pio run -d . -e $TESTENV
exit
fi
case $TESTENV in
tree) pio run -d . -e include_tree ; exit 1 ;;
due) TESTENV='DUE' ;;
esp) TESTENV='esp32' ;;
lin*) TESTENV='linux_native' ;;
lp8|lpc8) TESTENV='LPC1768' ;;
lp9|lpc9) TESTENV='LPC1769' ;;
m128) TESTENV='mega1280' ;;
m256) TESTENV='mega2560' ;;
mega) TESTENV='mega2560' ;;
stm) TESTENV='STM32F103RE' ;;
f1) TESTENV='STM32F103RE' ;;
f4) TESTENV='STM32F4' ;;
f7) TESTENV='STM32F7' ;;
s6) TESTENV='FYSETC_S6' ;;
teensy) TESTENV='teensy31' ;;
t31) TESTENV='teensy31' ;;
t32) TESTENV='teensy31' ;;
t35) TESTENV='teensy35' ;;
t36) TESTENV='teensy35' ;;
t40) TESTENV='teensy41' ;;
t41) TESTENV='teensy41' ;;
[1-9][1-9]|[1-9]) TESTNUM=$TESTENV ; TESTENV=- ;;
esac
if ((AUTO_BUILD)); then
#
# List environments that apply to the current MOTHERBOARD.
#
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
echo ; echo -n "Auto " ; ((AUTO_BUILD == 2)) && echo "Upload..." || echo "Build..."
MB=$( grep -E "^\s*#define MOTHERBOARD" Marlin/Configuration.h | awk '{ print $3 }' | $SED 's/BOARD_//' )
[[ -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" )
BDESC=$( $SED -E 's/^.+\/\/ *(.+)$/\1/' <<<"$BLINE" )
[[ -z $BNUM ]] && { echo "Error - Can't find $MB in boards list." ; 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[*]}
if [[ $ECOUNT == 1 ]]; then
TARGET=$ENVS
else
if [[ $CHOICE == 0 ]]; then
# List env names and numbers. Get selection.
echo "Available targets for \"$BDESC\" | $MB ($BNUM):"
IND=0 ; for ENV in "${ENVS[@]}"; do let IND++ ; echo " $IND) $ENV" ; done
if [[ $ECOUNT > 1 ]]; then
for (( ; ; ))
do
read -p "Select a target for '$MB' (1-$ECOUNT) : " CHOICE
[[ -z "$CHOICE" ]] && { echo '(canceled)' ; exit 1 ; }
[[ $CHOICE =~ $ISNUM ]] && ((CHOICE >= 1 && CHOICE <= ECOUNT)) && break
errout ">>> Invalid environment choice '$CHOICE'."
done
echo
fi
else
echo "Detected \"$BDESC\" | $MB ($BNUM)."
[[ $CHOICE > $ECOUNT ]] && { echo "Environment selection out of range." ; exit 1 ; }
fi
TARGET="${ENVS[$CHOICE-1]}"
echo "Selected $TARGET"
fi
echo "$TARGET" >"$STATE_FILE"
if ((AUTO_BUILD == 2)); then
echo "Uploading environment $TARGET for board $MB ($BNUM)..." ; echo
pio run -t upload -e $TARGET
else
echo "Building environment $TARGET for board $MB ($BNUM)..." ; echo
pio run -e $TARGET
fi
exit
fi
#
# List available tests and ask for selection
#
if [[ $TESTENV == '-' ]]; then
IND=0
NAMES=()
for FILE in $( ls -1 $TESTPATH/*-tests )
do
let IND++
TNAME=${FILE/-tests/}
TNAME=${TNAME/$TESTPATH\//}
NAMES+=($TNAME)
(( IND < 10 )) && echo -n " "
echo " $IND) $TNAME"
done
echo
for (( ; ; ))
do
if [[ $TESTNUM -gt 0 ]]; then
NAMEIND=$TESTNUM
else
read -p "Select a test to apply (1-$IND) : " NAMEIND
fi
[[ -z $NAMEIND ]] && { errout "(canceled)" ; exit 1 ; }
TESTENV=${NAMES[$NAMEIND-1]}
[[ $TESTNUM -gt 0 ]] && { echo "Preselected test $TESTNUM ... ($TESTENV)" ; TESTNUM='' ; }
[[ $NAMEIND =~ $ISNUM ]] && ((NAMEIND >= 1 && NAMEIND <= IND)) && { TESTENV=${NAMES[$NAMEIND-1]} ; echo ; break ; }
errout "Invalid selection."
done
fi
# Get the contents of the test file
OUT=$( cat $TESTPATH/$TESTENV-tests 2>/dev/null ) || { errout "Can't find test '$TESTENV'." ; exit 1 ; }
# Count up the number of tests
TESTCOUNT=$( awk "/$ISEXEC/{a++}END{print a}" <<<"$OUT" )
# User entered a number?
(( CHOICE && CHOICE > TESTCOUNT )) && { errout "Invalid test selection '$CHOICE' (1-$TESTCOUNT)." ; exit 1 ; }
if [[ $CHOICE == 0 ]]; then
#
# List test descriptions with numbers and get selection
#
echo "Available '$TESTENV' tests:" ; echo "$OUT" | {
IND=0
while IFS= read -r LINE
do
if [[ $LINE =~ $ISEXEC ]]; then
DESC=$( "$SED" -E 's/^exec_test \$1 \$2 "([^"]+)".*$/\1/g' <<<"$LINE" )
(( ++IND < 10 )) && echo -n " "
echo " $IND) $DESC"
fi
done
}
CHOICE=1
if [[ $TESTCOUNT > 1 ]]; then
for (( ; ; ))
do
read -p "Select a '$TESTENV' test (1-$TESTCOUNT) : " CHOICE
[[ -z "$CHOICE" ]] && { errout "(canceled)" ; exit 1 ; }
[[ $CHOICE =~ $ISNUM ]] && ((CHOICE >= 1 && CHOICE <= TESTCOUNT)) && break
errout ">>> Invalid test selection '$CHOICE'."
done
fi
fi
#
# Run the specified test lines
#
echo -ne "\033[0;33m"
echo "$OUT" | {
IND=0
GOTX=0
CMD=""
while IFS= read -r LINE
do
if [[ $LINE =~ $ISCMD || $GOTX == 1 ]]; then
((!IND)) && let IND++
if [[ $LINE =~ $ISEXEC ]]; then
((IND++ > CHOICE)) && break
else
((!HEADER)) && {
HEADER=1
echo -e "\n#\n# Test $TESTENV ($CHOICE) $DESC\n#"
}
((IND == CHOICE)) && {
GOTX=1
[[ $CMD == "" ]] && CMD="$LINE" || CMD=$( echo -e "$CMD$LINE" | $SED -e 's/\\//g' | $SED -E 's/ +/ /g' )
[[ $LINE =~ $ISCONT ]] || { echo "$CMD" ; eval "$CMD" ; CMD="" ; }
}
fi
fi
done
}
echo -ne "\033[0m"
# Make clear it's a TEST
opt_set CUSTOM_MACHINE_NAME "\"$TESTENV-tests ($CHOICE)\""
# Build the test too?
if [[ -z "$BUILD_YES" ]]; then
echo
read -p "Build $TESTENV test #$CHOICE (y/N) ? " BUILD_YES
fi
[[ $BUILD_YES == 'Y' || $BUILD_YES == 'Yes' ]] && {
((USE_MAKE)) && make tests-single-local TEST_TARGET=$TESTENV ONLY_TEST=$CHOICE
((USE_MAKE)) || pio run -d . -e $TESTENV
echo "$TESTENV" >"$STATE_FILE"
}