1#!/bin/sh -e 2 3# The only purpose of the above shebang is to orient shellcheck right. 4# To make CI scripts maintenance simpler, copies of this file in the 5# libpcap, tcpdump and tcpslice git repositories should be identical. 6# Please mind that Solaris /bin/sh before 11 does not support the $() 7# command substitution syntax, hence the "-e SC2006" flag in Makefile. 8 9# A poor man's mktemp(1) for OSes that don't have one (e.g. AIX 7, Solaris 9). 10mktempdir_diy() { 11 while true; do 12 # /bin/sh implements $RANDOM in AIX 7, but not in Solaris before 11, 13 # thus use dd and od instead. 14 mktempdir_diy_suffix=`dd if=/dev/urandom bs=4 count=1 2>/dev/null | od -t x -A n | head -1 | tr -d '\t '` 15 [ -z "$mktempdir_diy_suffix" ] && return 1 16 mktempdir_diy_path="${TMPDIR:-/tmp}/${1:?}.${mktempdir_diy_suffix}" 17 # "test -e" would be more appropriate, but it is not available in 18 # Solaris /bin/sh before 11. 19 if [ ! -d "$mktempdir_diy_path" ]; then 20 mkdir "$mktempdir_diy_path" 21 chmod go= "$mktempdir_diy_path" 22 echo "$mktempdir_diy_path" 23 break 24 fi 25 # Try again (very unlikely, just in case). 26 done 27} 28 29mktempdir() { 30 mktempdir_prefix=${1:-tmp} 31 case `os_id` in 32 Darwin-*|FreeBSD-*|NetBSD-*) 33 # In these operating systems mktemp(1) always appends an implicit 34 # ".XXXXXXXX" suffix to the requested template when creating a 35 # temporary directory. 36 mktemp -d -t "$mktempdir_prefix" 37 ;; 38 SunOS-5.10|SunOS-5.11) 39 # Although the suffix is optional, specify it for consistent results. 40 mktemp -d -t "${mktempdir_prefix}.XXXXXXXX" 41 ;; 42 SunOS-*|AIX-*) 43 mktempdir_diy "$mktempdir_prefix" 44 ;; 45 *) 46 # At least Haiku, Linux and OpenBSD implementations require explicit 47 # trailing X'es in the template, so make it the same suffix as above. 48 mktemp -d -t "${mktempdir_prefix}.XXXXXXXX" 49 ;; 50 esac 51} 52 53print_sysinfo() { 54 uname -a 55 printf 'OS identification: ' 56 os_id 57 date 58} 59 60# Try to make the current C compiler print its version information (usually 61# multi-line) to stdout. 62cc_version_nocache() { 63 : "${CC:?}" 64 case `basename "$CC"` in 65 gcc*|egcc*|clang*) 66 # GCC and Clang recognize --version, print to stdout and exit with 0. 67 "$CC" --version 68 ;; 69 xl*) 70 # XL C 12.1 and 13.1 recognize "-qversion", print to stdout and exit 71 # with 0. XL C 12.1 on an unknown command-line flag displays its man 72 # page and waits. 73 # XL C 16.1 recognizes "-qversion" and "--version", prints to stdout 74 # and exits with 0. Community Edition also prints a banner to stderr. 75 "$CC" -qversion 2>/dev/null 76 ;; 77 sun*) 78 # Sun compilers recognize -V, print to stderr and exit with an error. 79 "$CC" -V 2>&1 || : 80 ;; 81 cc) 82 case `os_id` in 83 SunOS-*) 84 # Most likely Sun C. 85 "$CC" -V 2>&1 || : 86 ;; 87 Darwin-*) 88 # Most likely Clang. 89 "$CC" --version 90 ;; 91 Linux-*|FreeBSD-*|NetBSD-*|OpenBSD-*) 92 # Most likely Clang or GCC. 93 "$CC" --version 94 ;; 95 esac 96 ;; 97 *) 98 "$CC" --version || "$CC" -V || : 99 ;; 100 esac 101} 102 103cc_version() { 104 echo "${cc_version_cached:=`cc_version_nocache`}" 105} 106 107print_cc_version() { 108 cc_version 109 printf 'Compiler identification: ' 110 cc_id 111} 112 113# For the current C compiler try to print a short and uniform identification 114# string (such as "gcc-9.3.0") that is convenient to use in a case statement. 115cc_id_nocache() { 116 cc_id_firstline=`cc_version | head -1` 117 : "${cc_id_firstline:?}" 118 119 cc_id_guessed=`echo "$cc_id_firstline" | sed 's/^.*clang version \([0-9\.]*\).*$/clang-\1/'` 120 if [ "$cc_id_firstline" != "$cc_id_guessed" ]; then 121 echo "$cc_id_guessed" 122 return 123 fi 124 125 cc_id_guessed=`echo "$cc_id_firstline" | sed 's/^IBM XL C.*, V\([0-9\.]*\).*$/xlc-\1/'` 126 if [ "$cc_id_firstline" != "$cc_id_guessed" ]; then 127 echo "$cc_id_guessed" 128 return 129 fi 130 131 cc_id_guessed=`echo "$cc_id_firstline" | sed 's/^.* Sun C \([0-9\.]*\) .*$/suncc-\1/'` 132 if [ "$cc_id_firstline" != "$cc_id_guessed" ]; then 133 echo "$cc_id_guessed" 134 return 135 fi 136 137 # OpenBSD default GCC: 138 # "gcc (GCC) 4.2.1 20070719" 139 # RedHat GCC: 140 # "gcc (GCC) 8.3.1 20190223 (Red Hat 8.3.1-2)" 141 # "gcc (GCC) 10.3.1 20210422 (Red Hat 10.3.1-1)" 142 # other GCC packages: 143 # "sparc-sun-solaris2.9-gcc (GCC) 4.2.0 (gccfss)" 144 # "gcc (GCC) 5.5.0" 145 # "gcc (nb4 20200810) 7.5.0" 146 # "gcc (OpenIndiana 7.5.0-il-0) 7.5.0" 147 # "gcc (Debian 8.3.0-6) 8.3.0" 148 # "gcc (Raspbian 8.3.0-6+rpi1) 8.3.0" 149 # "egcc (GCC) 8.4.0" 150 # "gcc (Ubuntu 9.3.0-17ubuntu1~20.04) 9.3.0" 151 # "gcc (FreeBSD Ports Collection) 10.3.0" 152 cc_id_guessed=`echo "$cc_id_firstline" | sed 's/^.* (.*) \([0-9\.]*\).*$/gcc-\1/'` 153 if [ "$cc_id_firstline" != "$cc_id_guessed" ]; then 154 echo "$cc_id_guessed" 155 return 156 fi 157} 158 159cc_id() { 160 echo "${cc_id_cached:=`cc_id_nocache`}" 161} 162 163# Call this function each time CC has changed. 164discard_cc_cache() { 165 cc_version_cached= 166 cc_id_cached= 167} 168 169# For the current C compiler try to print CFLAGS value that tells to treat 170# warnings as errors. 171cc_werr_cflags() { 172 case `cc_id` in 173 gcc-*|clang-*) 174 echo '-Werror' 175 ;; 176 xlc-*) 177 # XL C 12.1 and 13.1 recognize "-qhalt=w". XL C 16.1 recognizes that 178 # and "-Werror". 179 echo '-qhalt=w' 180 ;; 181 suncc-*) 182 echo '-errwarn=%all' 183 ;; 184 esac 185} 186 187# Tell whether "gcc" is a symlink to Clang (this is the case on macOS). 188gcc_is_clang_in_disguise() { 189 case `cc_id`/`basename "${CC:?}"` in 190 clang-*/gcc) 191 return 0 192 ;; 193 esac 194 return 1 195} 196 197os_id() { 198 # OS does not change between builds or in the middle of a build, so it is 199 # fine to cache uname output. 200 : "${os_id_sysname:=`uname -s`}" 201 printf '%s-' "$os_id_sysname" 202 : "${os_id_release:=`uname -r`}" 203 case "$os_id_sysname" in 204 AIX) 205 : "${os_id_version:=`uname -v`}" 206 echo "${os_id_version}.${os_id_release}" 207 ;; 208 Darwin|NetBSD|OpenBSD|SunOS) 209 echo "$os_id_release" 210 ;; 211 FreeBSD|Linux) 212 # Meaningful version is usually the substring before the first dash. 213 echo "$os_id_release" | sed 's/^\([0-9\.]*\).*$/\1/' 214 ;; 215 Haiku) 216 # Meaningful version is the substring before the plus sign. 217 # "hrev55181" stands for "R1/beta3". 218 # "hrev54154" stands for "R1/beta2". 219 : "${os_id_version:=`uname -v`}" 220 echo "$os_id_version" | sed 's/^\(hrev.*\)+.*$/\1/' 221 ;; 222 *) 223 echo 'UNKNOWN' 224 ;; 225 esac 226} 227 228increment() { 229 # No arithmetic expansion in Solaris /bin/sh before 11. 230 echo "${1:?} + 1" | bc 231} 232 233# Display text in magenta. 234echo_magenta() { 235 # ANSI magenta, the imploded text, ANSI reset, newline. 236 printf '\033[35;1m%s\033[0m\n' "$*" 237} 238 239# Run a command after displaying it. 240run_after_echo() { 241 : "${1:?}" # Require at least one argument. 242 printf '$ %s\n' "$*" 243 "$@" 244} 245 246print_so_deps() { 247 case `os_id` in 248 Darwin-*) 249 run_after_echo otool -L "${1:?}" 250 ;; 251 *) 252 run_after_echo ldd "${1:?}" 253 ;; 254 esac 255} 256 257# Beware that setting MATRIX_DEBUG for tcpdump or tcpslice will produce A LOT 258# of additional output there and in any nested libpcap builds. Multiplied by 259# the matrix size, the full output log size might exceed limits of some CI 260# systems (as it had previously happened with Travis CI). Use with caution on 261# a reduced matrix. 262handle_matrix_debug() { 263 [ "$MATRIX_DEBUG" != yes ] && return 264 echo '$ cat Makefile [...]' 265 sed '/^# DO NOT DELETE THIS LINE -- mkdep uses it.$/q' <Makefile 266 run_after_echo cat config.h 267 [ "$CMAKE" = yes ] || run_after_echo cat config.log 268} 269 270purge_directory() { 271 if [ "`os_id`" = SunOS-5.11 ]; then 272 # In Solaris 11 /bin/sh the pathname expansion of "*" always includes 273 # "." and "..", so the straightforward rm would always fail. 274 ( 275 cd "${1:?}" 276 for pd_each in *; do 277 if [ "$pd_each" != . ] && [ "$pd_each" != .. ]; then 278 rm -rf "$pd_each" 279 fi 280 done 281 ) 282 else 283 rm -rf "${1:?}"/* 284 fi 285} 286 287# vi: set tabstop=4 softtabstop=0 expandtab shiftwidth=4 smarttab autoindent : 288