#!/bin/sh -e # The only purpose of the above shebang is to orient shellcheck right. # To make CI scripts maintenance simpler, copies of this file in the # libpcap, tcpdump and tcpslice git repositories should be identical. # Please mind that Solaris /bin/sh before 11 does not support the $() # command substitution syntax, hence the "-e SC2006" flag in Makefile. # A poor man's mktemp(1) for OSes that don't have one (e.g. AIX 7, Solaris 9). mktempdir_diy() { while true; do # /bin/sh implements $RANDOM in AIX 7, but not in Solaris before 11, # thus use dd and od instead. mktempdir_diy_suffix=`dd if=/dev/urandom bs=4 count=1 2>/dev/null | od -t x -A n | head -1 | tr -d '\t '` [ -z "$mktempdir_diy_suffix" ] && return 1 mktempdir_diy_path="${TMPDIR:-/tmp}/${1:?}.${mktempdir_diy_suffix}" # "test -e" would be more appropriate, but it is not available in # Solaris /bin/sh before 11. if [ ! -d "$mktempdir_diy_path" ]; then mkdir "$mktempdir_diy_path" chmod go= "$mktempdir_diy_path" echo "$mktempdir_diy_path" break fi # Try again (very unlikely, just in case). done } mktempdir() { mktempdir_prefix=${1:-tmp} case `os_id` in Darwin-*|FreeBSD-*|NetBSD-*) # In these operating systems mktemp(1) always appends an implicit # ".XXXXXXXX" suffix to the requested template when creating a # temporary directory. mktemp -d -t "$mktempdir_prefix" ;; SunOS-5.10|SunOS-5.11) # Although the suffix is optional, specify it for consistent results. mktemp -d -t "${mktempdir_prefix}.XXXXXXXX" ;; SunOS-*|AIX-*) mktempdir_diy "$mktempdir_prefix" ;; *) # At least Haiku, Linux and OpenBSD implementations require explicit # trailing X'es in the template, so make it the same suffix as above. mktemp -d -t "${mktempdir_prefix}.XXXXXXXX" ;; esac } print_sysinfo() { uname -a printf 'OS identification: ' os_id date } # Try to make the current C compiler print its version information (usually # multi-line) to stdout. cc_version_nocache() { : "${CC:?}" case `basename "$CC"` in gcc*|egcc*|clang*) # GCC and Clang recognize --version, print to stdout and exit with 0. "$CC" --version ;; xl*) # XL C 12.1 and 13.1 recognize "-qversion", print to stdout and exit # with 0. XL C 12.1 on an unknown command-line flag displays its man # page and waits. # XL C 16.1 recognizes "-qversion" and "--version", prints to stdout # and exits with 0. Community Edition also prints a banner to stderr. "$CC" -qversion 2>/dev/null ;; sun*) # Sun compilers recognize -V, print to stderr and exit with an error. "$CC" -V 2>&1 || : ;; cc) case `os_id` in SunOS-*) # Most likely Sun C. "$CC" -V 2>&1 || : ;; Darwin-*) # Most likely Clang. "$CC" --version ;; Linux-*|FreeBSD-*|NetBSD-*|OpenBSD-*) # Most likely Clang or GCC. "$CC" --version ;; esac ;; *) "$CC" --version || "$CC" -V || : ;; esac } cc_version() { echo "${cc_version_cached:=`cc_version_nocache`}" } print_cc_version() { cc_version printf 'Compiler identification: ' cc_id } # For the current C compiler try to print a short and uniform identification # string (such as "gcc-9.3.0") that is convenient to use in a case statement. cc_id_nocache() { cc_id_firstline=`cc_version | head -1` : "${cc_id_firstline:?}" cc_id_guessed=`echo "$cc_id_firstline" | sed 's/^.*clang version \([0-9\.]*\).*$/clang-\1/'` if [ "$cc_id_firstline" != "$cc_id_guessed" ]; then echo "$cc_id_guessed" return fi cc_id_guessed=`echo "$cc_id_firstline" | sed 's/^IBM XL C.*, V\([0-9\.]*\).*$/xlc-\1/'` if [ "$cc_id_firstline" != "$cc_id_guessed" ]; then echo "$cc_id_guessed" return fi cc_id_guessed=`echo "$cc_id_firstline" | sed 's/^.* Sun C \([0-9\.]*\) .*$/suncc-\1/'` if [ "$cc_id_firstline" != "$cc_id_guessed" ]; then echo "$cc_id_guessed" return fi # OpenBSD default GCC: # "gcc (GCC) 4.2.1 20070719" # RedHat GCC: # "gcc (GCC) 8.3.1 20190223 (Red Hat 8.3.1-2)" # "gcc (GCC) 10.3.1 20210422 (Red Hat 10.3.1-1)" # other GCC packages: # "sparc-sun-solaris2.9-gcc (GCC) 4.2.0 (gccfss)" # "gcc (GCC) 5.5.0" # "gcc (nb4 20200810) 7.5.0" # "gcc (OpenIndiana 7.5.0-il-0) 7.5.0" # "gcc (Debian 8.3.0-6) 8.3.0" # "gcc (Raspbian 8.3.0-6+rpi1) 8.3.0" # "egcc (GCC) 8.4.0" # "gcc (Ubuntu 9.3.0-17ubuntu1~20.04) 9.3.0" # "gcc (FreeBSD Ports Collection) 10.3.0" cc_id_guessed=`echo "$cc_id_firstline" | sed 's/^.* (.*) \([0-9\.]*\).*$/gcc-\1/'` if [ "$cc_id_firstline" != "$cc_id_guessed" ]; then echo "$cc_id_guessed" return fi } cc_id() { echo "${cc_id_cached:=`cc_id_nocache`}" } # Call this function each time CC has changed. discard_cc_cache() { cc_version_cached= cc_id_cached= } # For the current C compiler try to print CFLAGS value that tells to treat # warnings as errors. cc_werr_cflags() { case `cc_id` in gcc-*|clang-*) echo '-Werror' ;; xlc-*) # XL C 12.1 and 13.1 recognize "-qhalt=w". XL C 16.1 recognizes that # and "-Werror". echo '-qhalt=w' ;; suncc-*) echo '-errwarn=%all' ;; esac } # Tell whether "gcc" is a symlink to Clang (this is the case on macOS). gcc_is_clang_in_disguise() { case `cc_id`/`basename "${CC:?}"` in clang-*/gcc) return 0 ;; esac return 1 } os_id() { # OS does not change between builds or in the middle of a build, so it is # fine to cache uname output. : "${os_id_sysname:=`uname -s`}" printf '%s-' "$os_id_sysname" : "${os_id_release:=`uname -r`}" case "$os_id_sysname" in AIX) : "${os_id_version:=`uname -v`}" echo "${os_id_version}.${os_id_release}" ;; Darwin|NetBSD|OpenBSD|SunOS) echo "$os_id_release" ;; FreeBSD|Linux) # Meaningful version is usually the substring before the first dash. echo "$os_id_release" | sed 's/^\([0-9\.]*\).*$/\1/' ;; Haiku) # Meaningful version is the substring before the plus sign. # "hrev55181" stands for "R1/beta3". # "hrev54154" stands for "R1/beta2". : "${os_id_version:=`uname -v`}" echo "$os_id_version" | sed 's/^\(hrev.*\)+.*$/\1/' ;; *) echo 'UNKNOWN' ;; esac } increment() { # No arithmetic expansion in Solaris /bin/sh before 11. echo "${1:?} + 1" | bc } # Display text in magenta. echo_magenta() { # ANSI magenta, the imploded text, ANSI reset, newline. printf '\033[35;1m%s\033[0m\n' "$*" } # Run a command after displaying it. run_after_echo() { : "${1:?}" # Require at least one argument. printf '$ %s\n' "$*" "$@" } print_so_deps() { case `os_id` in Darwin-*) run_after_echo otool -L "${1:?}" ;; *) run_after_echo ldd "${1:?}" ;; esac } # Beware that setting MATRIX_DEBUG for tcpdump or tcpslice will produce A LOT # of additional output there and in any nested libpcap builds. Multiplied by # the matrix size, the full output log size might exceed limits of some CI # systems (as it had previously happened with Travis CI). Use with caution on # a reduced matrix. handle_matrix_debug() { [ "$MATRIX_DEBUG" != yes ] && return echo '$ cat Makefile [...]' sed '/^# DO NOT DELETE THIS LINE -- mkdep uses it.$/q'