Skip to content

Instantly share code, notes, and snippets.

@lupyuen
Last active May 20, 2026 07:27
Show Gist options
  • Select an option

  • Save lupyuen/27995eb21a57a733ac5bc274744d1059 to your computer and use it in GitHub Desktop.

Select an option

Save lupyuen/27995eb21a57a733ac5bc274744d1059 to your computer and use it in GitHub Desktop.
Gemini 3.1 Pro: Are there any issues with this code: `testbuild.sh` https://github.com/apache/nuttx/issues/18562#issuecomment-4301679279

Gemini 3.1 Pro: Are there any issues with this code: testbuild.sh

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:

1. cibuild.sh Incorrectly Parses Arguments Passed to testbuild.sh

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.

2. Missing Space when Accumulating Compiler Flags

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".

3. Cascading Failures Without Early Exits

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 $toolchain

If ./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.

4. Overwriting the Global maxbuilds Variable

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
    fi

While 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?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment