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