forked from networkupstools/nut
-
Notifications
You must be signed in to change notification settings - Fork 0
/
ci_build.sh
executable file
·438 lines (399 loc) · 17.3 KB
/
ci_build.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
#!/usr/bin/env bash
################################################################################
# This file is based on a template used by zproject, but isn't auto-generated. #
################################################################################
set -e
# Set this to enable verbose profiling
[ -n "${CI_TIME-}" ] || CI_TIME=""
case "$CI_TIME" in
[Yy][Ee][Ss]|[Oo][Nn]|[Tt][Rr][Uu][Ee])
CI_TIME="time -p " ;;
[Nn][Oo]|[Oo][Ff][Ff]|[Ff][Aa][Ll][Ss][Ee])
CI_TIME="" ;;
esac
# Set this to enable verbose tracing
[ -n "${CI_TRACE-}" ] || CI_TRACE="no"
case "$CI_TRACE" in
[Nn][Oo]|[Oo][Ff][Ff]|[Ff][Aa][Ll][Ss][Ee])
set +x ;;
[Yy][Ee][Ss]|[Oo][Nn]|[Tt][Rr][Uu][Ee])
set -x ;;
esac
configure_nut() {
local CONFIGURE_SCRIPT=./configure
if [[ "$TRAVIS_OS_NAME" == "windows" ]] ; then
find . -ls
CONFIGURE_SCRIPT=./configure.bat
fi
echo "=== CONFIGURING NUT: $CONFIGURE_SCRIPT ${CONFIG_OPTS[*]}"
echo "=== CC='$CC' CXX='$CXX' CPP='$CPP'"
$CI_TIME $CONFIGURE_SCRIPT "${CONFIG_OPTS[@]}" \
|| { RES=$?
echo "FAILED ($RES) to configure nut, will dump config.log in a second to help troubleshoot CI" >&2
echo " (or press Ctrl+C to abort now if running interactively)" >&2
sleep 5
echo "=========== DUMPING config.log :"; cat config.log || true ; echo "=========== END OF config.log"
echo "FATAL: FAILED ($RES) to ./configure ${CONFIG_OPTS[*]}" >&2
exit $RES
}
}
build_to_only_catch_errors() {
( echo "`date`: Starting the parallel build attempt (quietly to build what we can)..."; \
$CI_TIME make VERBOSE=0 -k -j8 all >/dev/null 2>&1 && echo "`date`: SUCCESS" ; ) || \
( echo "`date`: Starting the sequential build attempt (to list remaining files with errors considered fatal for this build configuration)..."; \
$CI_TIME make VERBOSE=1 all -k ) || return $?
echo "`date`: Starting a 'make check' for quick sanity test of the products built with the current compiler and standards"
$CI_TIME make VERBOSE=0 check \
&& echo "`date`: SUCCESS" \
|| return $?
return 0
}
echo "Processing BUILD_TYPE='${BUILD_TYPE}' ..."
case "$BUILD_TYPE" in
default|default-alldrv|default-all-errors|default-spellcheck|default-shellcheck|default-nodoc|default-withdoc|"default-tgt:"*)
LANG=C
LC_ALL=C
export LANG LC_ALL
if [ -d "./tmp/" ]; then
rm -rf ./tmp/
fi
if [ -d "./.inst/" ]; then
rm -rf ./.inst/
fi
mkdir -p tmp/ .inst/
BUILD_PREFIX=$PWD/tmp
INST_PREFIX=$PWD/.inst
echo "PATH='$PATH' before possibly applying CCACHE into the mix"
( echo "$PATH" | grep ccache ) >/dev/null && echo "WARNING: ccache is already in PATH"
if [ -n "$CC" ]; then
echo "CC='$CC' before possibly applying CCACHE into the mix"
$CC --version $CFLAGS || \
$CC --version || true
fi
if [ -n "$CXX" ]; then
echo "CXX='$CXX' before possibly applying CCACHE into the mix"
$CXX --version $CXXFLAGS || \
$CXX --version || true
fi
PATH="`echo "$PATH" | sed -e 's,^/usr/lib/ccache/?:,,' -e 's,:/usr/lib/ccache/?:,,' -e 's,:/usr/lib/ccache/?$,,' -e 's,^/usr/lib/ccache/?$,,'`"
CCACHE_PATH="$PATH"
CCACHE_DIR="${HOME}/.ccache"
export CCACHE_PATH CCACHE_DIR PATH
HAVE_CCACHE=no
if which ccache && ls -la /usr/lib/ccache ; then
HAVE_CCACHE=yes
fi
mkdir -p "${CCACHE_DIR}"/ || HAVE_CCACHE=no
if [ "$HAVE_CCACHE" = yes ] && [ -d "$CCACHE_DIR" ]; then
echo "CCache stats before build:"
ccache -s || true
fi
CONFIG_OPTS=()
COMMON_CFLAGS=""
EXTRA_CFLAGS=""
EXTRA_CPPFLAGS=""
EXTRA_CXXFLAGS=""
is_gnucc() {
if [ -n "$1" ] && "$1" --version 2>&1 | grep 'Free Software Foundation' > /dev/null ; then true ; else false ; fi
}
is_clang() {
if [ -n "$1" ] && "$1" --version 2>&1 | grep 'clang version' > /dev/null ; then true ; else false ; fi
}
COMPILER_FAMILY=""
if [ -n "$CC" -a -n "$CXX" ]; then
if is_gnucc "$CC" && is_gnucc "$CXX" ; then
COMPILER_FAMILY="GCC"
export CC CXX
elif is_clang "$CC" && is_clang "$CXX" ; then
COMPILER_FAMILY="CLANG"
export CC CXX
fi
else
if is_gnucc "gcc" && is_gnucc "g++" ; then
# Autoconf would pick this by default
COMPILER_FAMILY="GCC"
[ -n "$CC" ] || CC=gcc
[ -n "$CXX" ] || CXX=g++
export CC CXX
elif is_gnucc "cc" && is_gnucc "c++" ; then
COMPILER_FAMILY="GCC"
[ -n "$CC" ] || CC=cc
[ -n "$CXX" ] || CXX=c++
export CC CXX
elif is_clang "clang" && is_clang "clang++" ; then
# Autoconf would pick this by default
COMPILER_FAMILY="CLANG"
[ -n "$CC" ] || CC=clang
[ -n "$CXX" ] || CXX=clang++
export CC CXX
elif is_clang "cc" && is_clang "c++" ; then
COMPILER_FAMILY="CLANG"
[ -n "$CC" ] || CC=cc
[ -n "$CXX" ] || CXX=c++
export CC CXX
fi
fi
if [ -n "$CPP" ] ; then
[ -x "$CPP" ] && export CPP
else
if is_gnucc "cpp" ; then
CPP=cpp && export CPP
fi
fi
# Note: Potentially there can be spaces in entries for multiple
# *FLAGS here; this should be okay as long as entry expands to
# one token when calling shell (may not be the case for distcheck)
CONFIG_OPTS+=("CFLAGS=-I${BUILD_PREFIX}/include ${CFLAGS}")
CONFIG_OPTS+=("CPPFLAGS=-I${BUILD_PREFIX}/include ${CPPFLAGS}")
CONFIG_OPTS+=("CXXFLAGS=-I${BUILD_PREFIX}/include ${CXXFLAGS}")
CONFIG_OPTS+=("LDFLAGS=-L${BUILD_PREFIX}/lib")
if [ -n "$PKG_CONFIG_PATH" ] ; then
CONFIG_OPTS+=("PKG_CONFIG_PATH=${BUILD_PREFIX}/lib/pkgconfig:${PKG_CONFIG_PATH}")
else
CONFIG_OPTS+=("PKG_CONFIG_PATH=${BUILD_PREFIX}/lib/pkgconfig")
fi
CONFIG_OPTS+=("--prefix=${BUILD_PREFIX}")
CONFIG_OPTS+=("--sysconfdir=${BUILD_PREFIX}/etc/nut")
CONFIG_OPTS+=("--with-udev-dir=${BUILD_PREFIX}/etc/udev")
CONFIG_OPTS+=("--with-devd-dir=${BUILD_PREFIX}/etc/devd")
CONFIG_OPTS+=("--with-hotplug-dir=${BUILD_PREFIX}/etc/hotplug")
DO_DISTCHECK=yes
case "$BUILD_TYPE" in
"default-nodoc")
CONFIG_OPTS+=("--with-doc=no")
DO_DISTCHECK=no
;;
"default-spellcheck"|"default-shellcheck")
CONFIG_OPTS+=("--with-all=no")
CONFIG_OPTS+=("--with-libltdl=no")
CONFIG_OPTS+=("--with-doc=man=skip")
#TBD# CONFIG_OPTS+=("--with-shellcheck=yes")
DO_DISTCHECK=no
;;
"default-withdoc")
CONFIG_OPTS+=("--with-doc=yes")
;;
"default-all-errors")
# Do not build the docs as we are interested in binary code
CONFIG_OPTS+=("--with-doc=skip")
# Enable as many binaries to build as current worker setup allows
CONFIG_OPTS+=("--with-all=auto")
if [[ "$TRAVIS_OS_NAME" != "windows" ]] && [[ "$TRAVIS_OS_NAME" != "freebsd" ]] && [ "${BUILD_LIBGD_CGI-}" != "auto" ] ; then
# Currently --with-all implies this, but better be sure to
# really build everything we can to be certain it builds:
if pkg-config --exists libgd || pkg-config --exists libgd2 || pkg-config --exists libgd3 || pkg-config --exists gdlib ; then
CONFIG_OPTS+=("--with-cgi=yes")
else
# Note: CI-wise, our goal IS to test as much as we can
# with this build, so environments should be set up to
# facilitate that as much as feasible. But reality is...
echo "WARNING: Seems libgd{,2,3} is not present, CGI build may be skipped!" >&2
CONFIG_OPTS+=("--with-cgi=auto")
fi
else
# No prereq dll and headers on win so far
CONFIG_OPTS+=("--with-cgi=auto")
fi
;;
"default-alldrv")
# Do not build the docs and make possible a distcheck below
CONFIG_OPTS+=("--with-doc=skip")
CONFIG_OPTS+=("--with-all=yes")
;;
"default"|*)
# Do not build the docs and tell distcheck it is okay
CONFIG_OPTS+=("--with-doc=skip")
;;
esac
if [ "$HAVE_CCACHE" = yes ] && [ "${COMPILER_FAMILY}" = GCC -o "${COMPILER_FAMILY}" = CLANG ]; then
PATH="/usr/lib/ccache:$PATH"
export PATH
if [ -n "$CC" ]; then
if [ -x "/usr/lib/ccache/`basename "$CC"`" ]; then
case "$CC" in
*ccache*) ;;
*/*) DIR_CC="`dirname "$CC"`" && [ -n "$DIR_CC" ] && DIR_CC="`cd "$DIR_CC" && pwd `" && [ -n "$DIR_CC" ] && [ -d "$DIR_CC" ] || DIR_CC=""
[ -z "$CCACHE_PATH" ] && CCACHE_PATH="$DIR_CC" || \
if echo "$CCACHE_PATH" | egrep '(^'"$DIR_CC"':.*|^'"$DIR_CC"'$|:'"$DIR_CC"':|:'"$DIR_CC"'$)' ; then
CCACHE_PATH="$DIR_CC:$CCACHE_PATH"
fi
;;
esac
CC="/usr/lib/ccache/`basename "$CC"`"
else
CC="ccache $CC"
fi
fi
if [ -n "$CXX" ]; then
if [ -x "/usr/lib/ccache/`basename "$CXX"`" ]; then
case "$CXX" in
*ccache*) ;;
*/*) DIR_CXX="`dirname "$CXX"`" && [ -n "$DIR_CXX" ] && DIR_CXX="`cd "$DIR_CXX" && pwd `" && [ -n "$DIR_CXX" ] && [ -d "$DIR_CXX" ] || DIR_CXX=""
[ -z "$CCACHE_PATH" ] && CCACHE_PATH="$DIR_CXX" || \
if echo "$CCACHE_PATH" | egrep '(^'"$DIR_CXX"':.*|^'"$DIR_CXX"'$|:'"$DIR_CXX"':|:'"$DIR_CXX"'$)' ; then
CCACHE_PATH="$DIR_CXX:$CCACHE_PATH"
fi
;;
esac
CXX="/usr/lib/ccache/`basename "$CXX"`"
else
CXX="ccache $CXX"
fi
fi
if [ -n "$CPP" ] && [ -x "/usr/lib/ccache/`basename "$CPP"`" ]; then
case "$CPP" in
*ccache*) ;;
*/*) DIR_CPP="`dirname "$CPP"`" && [ -n "$DIR_CPP" ] && DIR_CPP="`cd "$DIR_CPP" && pwd `" && [ -n "$DIR_CPP" ] && [ -d "$DIR_CPP" ] || DIR_CPP=""
[ -z "$CCACHE_PATH" ] && CCACHE_PATH="$DIR_CPP" || \
if echo "$CCACHE_PATH" | egrep '(^'"$DIR_CPP"':.*|^'"$DIR_CPP"'$|:'"$DIR_CPP"':|:'"$DIR_CPP"'$)' ; then
CCACHE_PATH="$DIR_CPP:$CCACHE_PATH"
fi
;;
esac
CPP="/usr/lib/ccache/`basename "$CPP"`"
else
: # CPP="ccache $CPP"
fi
# Note: Potentially there can be spaces in entries for multiword
# "ccache gcc" here; this should be okay as long as entry expands to
# one token when calling shell (may not be the case for distcheck)
CONFIG_OPTS+=("CC=${CC}")
CONFIG_OPTS+=("CXX=${CXX}")
CONFIG_OPTS+=("CPP=${CPP}")
fi
# Build and check this project; note that zprojects always have an autogen.sh
[ -z "$CI_TIME" ] || echo "`date`: Starting build of currently tested project..."
CCACHE_BASEDIR="${PWD}"
export CCACHE_BASEDIR
if [ -n "${BUILD_WARNOPT-}" ]; then
CONFIG_OPTS+=("--enable-warnings=${BUILD_WARNOPT}")
fi
if [ -n "${BUILD_WARNFATAL-}" ]; then
CONFIG_OPTS+=("--enable-Werror=${BUILD_WARNFATAL}")
fi
# Note: modern auto(re)conf requires pkg-config to generate the configure
# script, so to stage the situation of building without one (as if on an
# older system) we have to remove it when we already have the script.
# This matches the use-case of distro-building from release tarballs that
# include all needed pre-generated files to rely less on OS facilities.
if [ "$TRAVIS_OS_NAME" = "windows" ] ; then
$CI_TIME ./autogen.sh || true
else
$CI_TIME ./autogen.sh ### 2>/dev/null
fi
if [ "$NO_PKG_CONFIG" == "true" ] && [ "$TRAVIS_OS_NAME" = "linux" ] ; then
echo "NO_PKG_CONFIG==true : BUTCHER pkg-config for this test case" >&2
sudo dpkg -r --force all pkg-config
fi
if [ "$BUILD_TYPE" != "default-all-errors" ] ; then
configure_nut
fi
case "$BUILD_TYPE" in
"default-tgt:"*) # Hook for matrix of custom distchecks primarily
BUILD_TGT="`echo "$BUILD_TYPE" | sed 's,^default-tgt:,,'`"
echo "`date`: Starting the sequential build attempt for singular target $BUILD_TGT..."
export DISTCHECK_CONFIGURE_FLAGS="${CONFIG_OPTS[@]}"
$CI_TIME make VERBOSE=1 DISTCHECK_CONFIGURE_FLAGS="$DISTCHECK_CONFIGURE_FLAGS" "$BUILD_TGT"
echo "=== Are GitIgnores good after 'make $BUILD_TGT'? (should have no output below)"
git status -s || true
echo "==="
if git status -s | egrep '\.dmf$' ; then
echo "FATAL: There are changes in DMF files listed above - tracked sources should be updated!" >&2
exit 1
fi
if [ "$HAVE_CCACHE" = yes ]; then
echo "CCache stats after build:"
ccache -s
fi
echo "=== Exiting after the custom-build target 'make $BUILD_TGT' succeeded OK"
exit 0
;;
"default-spellcheck")
[ -z "$CI_TIME" ] || echo "`date`: Trying to spellcheck documentation of the currently tested project..."
# Note: use the root Makefile's spellcheck recipe which goes into
# sub-Makefiles known to check corresponding directory's doc files.
( $CI_TIME make VERBOSE=1 SPELLCHECK_ERROR_FATAL=yes spellcheck )
exit 0
;;
"default-shellcheck")
[ -z "$CI_TIME" ] || echo "`date`: Trying to check shell script syntax validity of the currently tested project..."
### Note: currently, shellcheck target calls check-scripts-syntax
### so when both are invoked at once, in the end the check is only
### executed once. Later it is anticipated that shellcheck would
### be implemented by requiring, configuring and calling the tool
### named "shellcheck" for even more code inspection and details.
### Still, there remains value in also checking the script syntax
### by the very version of the shell interpreter that would run
### these scripts in production usage of the resulting packages.
( $CI_TIME make VERBOSE=1 shellcheck check-scripts-syntax )
exit $?
;;
"default-all-errors")
RES=0
if pkg-config --exists nss && pkg-config --exists openssl && [ "${BUILD_SSL_ONCE-}" != "true" ] ; then
# Try builds for both cases as they are ifdef-ed
echo "=== Building with SSL=openssl..."
( CONFIG_OPTS+=("--with-openssl")
configure_nut
build_to_only_catch_errors ) || RES=$?
echo "=== Clean the sandbox..."
make distclean -k || true
echo "=== Building with SSL=nss..."
( CONFIG_OPTS+=("--with-nss")
configure_nut
build_to_only_catch_errors ) || RES=$?
else
# Build what we can configure
configure_nut
build_to_only_catch_errors || RES=$?
fi
exit $RES
;;
esac
( echo "`date`: Starting the parallel build attempt..."; \
$CI_TIME make VERBOSE=1 -k -j8 all; ) || \
( echo "`date`: Starting the sequential build attempt..."; \
$CI_TIME make VERBOSE=1 all )
echo "=== Are GitIgnores good after 'make all'? (should have no output below)"
git status -s || true
echo "==="
if [ -n "`git status -s`" ]; then
echo "FATAL: There are changes in some files listed above - tracked sources should be updated in the PR, and build products should be added to a .gitignore file!" >&2
git diff || true
echo "==="
exit 1
fi
[ -z "$CI_TIME" ] || echo "`date`: Trying to install the currently tested project into the custom DESTDIR..."
$CI_TIME make VERBOSE=1 DESTDIR="$INST_PREFIX" install
[ -n "$CI_TIME" ] && echo "`date`: listing files installed into the custom DESTDIR..." && \
find "$INST_PREFIX" -ls || true
if [ "$DO_DISTCHECK" == "no" ] ; then
echo "Skipping distcheck (doc generation is disabled, it would fail)"
else
[ -z "$CI_TIME" ] || echo "`date`: Starting distcheck of currently tested project..."
(
export DISTCHECK_CONFIGURE_FLAGS="${CONFIG_OPTS[@]}"
$CI_TIME make VERBOSE=1 DISTCHECK_CONFIGURE_FLAGS="$DISTCHECK_CONFIGURE_FLAGS" distcheck
echo "=== Are GitIgnores good after 'make distcheck'? (should have no output below)"
git status -s || true
echo "==="
)
fi
if [ "$HAVE_CCACHE" = yes ]; then
echo "CCache stats after build:"
ccache -s
fi
;;
bindings)
pushd "./bindings/${BINDING}" && ./ci_build.sh
;;
"")
echo "ERROR: No BUILD_TYPE was specified, doing a minimal default ritual"
./autogen.sh
./configure
make all && make check
;;
*)
pushd "./builds/${BUILD_TYPE}" && REPO_DIR="$(dirs -l +1)" ./ci_build.sh
;;
esac