xref: /aosp_15_r20/external/tcpdump/build_common.sh (revision 05b00f6010a2396e3db2409989fc67270046269f)
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