| #!/bin/bash |
| |
| # Copyright (C) 2023-2024 Free Software Foundation, Inc. |
| # This program is free software; you can redistribute it and/or modify |
| # it under the terms of the GNU General Public License as published by |
| # the Free Software Foundation; either version 3 of the License, or |
| # (at your option) any later version. |
| # |
| # This program is distributed in the hope that it will be useful, |
| # but WITHOUT ANY WARRANTY; without even the implied warranty of |
| # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| # GNU General Public License for more details. |
| # |
| # You should have received a copy of the GNU General Public License |
| # along with this program. If not, see <http://www.gnu.org/licenses/>. |
| |
| # Run make check with all boards from gdb/testsuite/boards. |
| |
| # It is recommended to create users on the local system that will act as |
| # "remote host" and "remote target", for the boards that use them. |
| # Pass their usernames to --host-user and --target-user. This helps |
| # because: |
| # |
| # - remote host/target boards will use $HOME and leave (potentially |
| # lots of) files behind, |
| # - it enables more strict checking of build/host/target file |
| # manipulations, |
| # - it prevents a command running on one "machine" to kill or send a |
| # signal to a process on another machine. |
| # |
| # Recommended usage example: |
| # |
| # bash$ cd $objdir/gdb/testsuite |
| # bash$ $srcdir/testsuite/gdb/make-check-all.sh \ |
| # --host-user remote-host \ |
| # --target-user remote-target \ |
| # gdb.base/advance.exp |
| |
| set -e |
| |
| # Boards that run the host tools (compiler, gdb) on a remote host. |
| remote_host_boards=( |
| local-remote-host |
| local-remote-host-notty |
| ) |
| |
| # Boards that use gdbserver to launch target executables on local target. |
| gdbserver_boards=( |
| native-extended-gdbserver |
| native-gdbserver |
| native-stdio-gdbserver |
| ) |
| |
| # Boards that use gdbserver to launch target executables on a remote target. |
| remote_gdbserver_boards=( |
| remote-gdbserver-on-localhost |
| remote-stdio-gdbserver |
| ) |
| |
| # Boards that run compiler, gdb and target executables on a remote machine |
| # that serves both as host and target. |
| host_target_boards=( |
| local-remote-host-native |
| ) |
| |
| # Boards that run everything on local target and local host. |
| target_boards=( |
| cc-with-gdb-index |
| cc-with-index-cache |
| cc-with-debug-names |
| cc-with-dwz |
| cc-with-dwz-m |
| cc-with-gnu-debuglink |
| debug-types |
| dwarf4-gdb-index |
| dwarf64 |
| fission |
| fission-dwp |
| gold |
| gold-gdb-index |
| readnow |
| stabs |
| ) |
| |
| # Get RUNTESTFLAGS needed for specific boards. |
| rtf_for_board () |
| { |
| local b |
| b="$1" |
| |
| case $b in |
| local-remote-host-native) |
| mkdir -p "$tmpdir/$b" |
| rtf=( |
| "${rtf[@]}" |
| "HOST_DIR=$tmpdir/$b" |
| ) |
| ;; |
| remote-stdio-gdbserver) |
| rtf=( |
| "${rtf[@]}" |
| "REMOTE_HOSTNAME=localhost" |
| ) |
| if [ "$target_user" != "" ]; then |
| rtf=( |
| "${rtf[@]}" |
| "REMOTE_USERNAME=$target_user" |
| ) |
| else |
| rtf=( |
| "${rtf[@]}" |
| "REMOTE_USERNAME=$USER" |
| ) |
| fi |
| ;; |
| remote-gdbserver-on-localhost) |
| if [ "$target_user" != "" ]; then |
| rtf=( |
| "${rtf[@]}" |
| "REMOTE_TARGET_USERNAME=$target_user" |
| ) |
| fi |
| ;; |
| local-remote-host|local-remote-host-notty) |
| if [ "$host_user" != "" ]; then |
| rtf=( |
| "${rtf[@]}" |
| "REMOTE_HOST_USERNAME=$host_user" |
| ) |
| else |
| rtf=( |
| "${rtf[@]}" |
| "REMOTE_HOST_USERNAME=$USER" |
| ) |
| fi |
| ;; |
| *) |
| ;; |
| esac |
| } |
| |
| # Summarize make check output. |
| summary () |
| { |
| if $verbose; then |
| cat |
| else |
| # We need the sort -u, because some items, for instance "# of expected |
| # passes" are output twice. |
| grep -E "^(#|FAIL:|ERROR:|WARNING:)" \ |
| | sort -u |
| fi |
| } |
| |
| # Run make check, and possibly save test results. |
| do_tests () |
| { |
| if $debug; then |
| echo "RTF: ${rtf[*]}" |
| fi |
| |
| if $dry_run; then |
| return |
| fi |
| |
| # Run make check. |
| make check \ |
| RUNTESTFLAGS="${rtf[*]} ${tests[*]}" \ |
| 2>&1 \ |
| | summary |
| |
| # Save test results. |
| if $keep_results; then |
| # Set cfg to identifier unique to host/target board combination. |
| if [ "$h" = "" ]; then |
| if [ "$b" = "" ]; then |
| cfg=local |
| else |
| cfg=$b |
| fi |
| else |
| cfg=$h-$b |
| fi |
| |
| local dir |
| dir="check-all/$cfg" |
| |
| mkdir -p "$dir" |
| cp gdb.sum gdb.log "$dir" |
| |
| # Record the 'make check' command to enable easy re-running. |
| echo "make check RUNTESTFLAGS=\"${rtf[*]} ${tests[*]}\"" \ |
| > "$dir/make-check.sh" |
| fi |
| } |
| |
| # Set default values for global vars and modify according to command line |
| # arguments. |
| parse_args () |
| { |
| # Default values. |
| debug=false |
| keep_results=false |
| keep_tmp=false |
| verbose=false |
| dry_run=false |
| |
| host_user="" |
| target_user="" |
| |
| # Parse command line arguments. |
| while [ $# -gt 0 ]; do |
| case "$1" in |
| --debug) |
| debug=true |
| ;; |
| --keep-results) |
| keep_results=true |
| ;; |
| --keep-tmp) |
| keep_tmp=true |
| ;; |
| --verbose) |
| verbose=true |
| ;; |
| --dry-run) |
| dry_run=true |
| ;; |
| --host-user) |
| shift |
| host_user="$1" |
| ;; |
| --target-user) |
| shift |
| target_user="$1" |
| ;; |
| *) |
| break |
| ;; |
| esac |
| shift |
| done |
| |
| tests=("$@") |
| } |
| |
| # Cleanup function, scheduled to run on exit. |
| cleanup () |
| { |
| if [ "$tmpdir" != "" ]; then |
| if $keep_tmp; then |
| echo "keeping tmp dir $tmpdir" |
| else |
| rm -Rf "$tmpdir" |
| fi |
| fi |
| } |
| |
| # Top-level function, called with command line arguments of the script. |
| main () |
| { |
| # Parse command line arguments. |
| parse_args "$@" |
| |
| # Create tmpdir and schedule cleanup. |
| tmpdir="" |
| trap cleanup EXIT |
| tmpdir=$(mktemp -d) |
| |
| if $debug; then |
| echo "TESTS: ${tests[*]}" |
| fi |
| |
| # Variables that point to current host (h) and target board (b) when |
| # executing do_tests. |
| h="" |
| b="" |
| |
| # For reference, run the tests without any explicit host or target board. |
| echo "LOCAL:" |
| rtf=() |
| do_tests |
| |
| # Run the boards for local host and local target. |
| for b in "${target_boards[@]}"; do |
| echo "TARGET BOARD: $b" |
| rtf=( |
| --target_board="$b" |
| ) |
| rtf_for_board "$b" |
| do_tests |
| done |
| |
| # Run the boards that use gdbserver, for local host, and for both local and |
| # remote target. |
| for b in "${gdbserver_boards[@]}" "${remote_gdbserver_boards[@]}"; do |
| echo "TARGET BOARD: $b" |
| rtf=( |
| --target_board="$b" |
| ) |
| rtf_for_board "$b" |
| do_tests |
| done |
| |
| # Run the boards that use remote host, in combination with boards that use |
| # gdbserver on remote target. |
| for h in "${remote_host_boards[@]}"; do |
| for b in "${remote_gdbserver_boards[@]}"; do |
| echo "HOST BOARD: $h, TARGET BOARD: $b" |
| rtf=( |
| --host_board="$h" |
| --target_board="$b" |
| ) |
| rtf_for_board "$h" |
| rtf_for_board "$b" |
| do_tests |
| done |
| done |
| h="" |
| |
| # Run the boards that function as both remote host and remote target. |
| for b in "${host_target_boards[@]}"; do |
| echo "HOST/TARGET BOARD: $b" |
| rtf=( |
| --host_board="$b" |
| --target_board="$b" |
| ) |
| rtf_for_board "$b" |
| do_tests |
| done |
| } |
| |
| # Call top-level function with command line arguments. |
| main "$@" |