I've reviewed testbuild.sh (the active document) as well as the related cibuild.sh script, and I've found a few significant issues. Here are the main problems with the code:
In tools/ci/cibuild.sh, the script claims to support all testbuild.sh options via the -* catch-all. However, the while loop completely breaks on any option that requires an argument (like -j 4 or -a appsdir).
# cibuild.sh
-* )
options+="$1 "
;;
* )
builds=( "$@" )
break
;;If you run ./cibuild.sh -j 4 testlist, the script captures -j into options, but on the next iteration, $1 becomes 4. Since 4 doesn't start with -, it falls into the * ) case, stopping argument parsing completely and treating "4" and "testlist" as the target build files.
This eventually results in cibuild.sh running testbuild.sh -j -e ... 4 testlist, which will fail with a "Garbage at the end of line" error.
Fix: cibuild.sh needs a more robust argument parsing block (or getopts) that explicitly shifts the argument for known flags like -j, -a, -t, etc.
In testbuild.sh, the -e flag allows you to pass extra compiler flags. However, the concatenation lacks a space:
# testbuild.sh
-e )
shift
EXTRA_FLAGS+="$1"
;;If a user runs testbuild.sh -e "-Wno-cpp" -e "-Werror", the variable becomes EXTRAFLAGS=-Wno-cpp-Werror (no space), resulting in an invalid flag that the compiler won't understand.
Fix: Change it to EXTRA_FLAGS+=" $1".
In testbuild.sh, if a critical step fails, the script sets fail=1 but does not exit the current flow. For example, in configure_default:
# testbuild.sh
if ! ./tools/configure.sh ${HOPTION} ${STORE} $config ${JOPTION} 1>/dev/null; then
fail=1
fi
# ... continues running instead of returning ...
kconfig-tweak --file $nuttx/.config -e $toolchainIf ./tools/configure.sh fails, the .config file is never generated. However, the script continues to run kconfig-tweak and eventually calls make, throwing dozens of secondary errors about a missing configuration.
Fix: The functions (distclean, configure, build, etc.) should return early if fail=1 is hit to avoid misleading error logs.
In testbuild.sh, if a configuration fails 4 times (the default maxbuilds), it triggers this logic inside retrytest:
# testbuild.sh
# If this is Final Retry: Don't retry subsequent builds
if [ $i -eq $maxbuilds ]; then
maxbuilds=1
break
fiWhile the comment implies it's intentional to avoid wasting CI time if the environment is broken, overwriting a global variable inside a loop alters the execution flow for all subsequent configurations in the entire test file. If a single unrelated target fails, the remaining hundreds of targets will now only have 1 attempt instead of 4.
Fix: If the intent is to give up entirely on retries, it is more explicit to define a separate GIVE_UP_RETRIES=1 flag and check it, rather than mutating the initial configuration state.
Would you like me to go ahead and patch these files to fix these issues?