jenkins: keep failed distchecks around for investigation
[gnupg-doc.git] / misc / jenkins / bin / build.bash
1 #!/bin/bash
2 # Script used jenkins to run builds for GnuPG and related packages.
3
4 # Stop on error and be nice to other processes.
5 set -xe
6 renice -n 10 -p $$
7
8 # Configuration.
9 MAKE=make
10
11 # Platform-specific configuration.
12 case "$(uname)" in
13     OpenBSD)
14         MAKE=gmake
15         ;;
16 esac
17
18 if [ "$XTARGET" = w32 ]; then
19     CC=i686-w64-mingw32-gcc
20     CXX=i686-w64-mingw32-g++
21 fi
22
23 # Setup ccache if installed.
24 if ccache --version >/dev/null; then
25     export CCACHE_DIR="$HOME/cache/$JOB_NAME"
26     mkdir -p "$CCACHE_DIR"
27     export CC="ccache ${CC:-gcc}"
28     export CXX="ccache ${CXX:-g++}"
29 fi
30
31 # Setup important envars
32 PREFIX=$HOME/prefix/$XTARGET
33 ORIGINAL_PREFIX=$HOME/prefix/$XTARGET
34 export PATH=$PREFIX/bin:$PATH
35
36 # Tweak the prefix we're installing this project into.  For gnupg-1.4
37 # and friends.
38 case "$JOB_NAME" in
39     *-1.4*)
40         PREFIX=$PREFIX-1.4
41         ;;
42     *-2.0*)
43         PREFIX=$PREFIX-2.0
44         ;;
45     *-2.2*)
46         PREFIX=$PREFIX-2.2
47         ;;
48 esac
49 mkdir -p $PREFIX
50
51
52 fix_permissions()
53 {
54   find $1 -type d -exec chmod +w {} + || true
55 }
56
57 fix_permissions .
58
59 # Clean everything
60 git clean -fdx
61
62 # Run out autogen - note that --force is not required due to the git clean.
63 ./autogen.sh
64
65 # Parallel jobs.
66 MAKEFLAGS="-j6"
67
68 # Parallel tests with our test suite.
69 export TESTFLAGS="--parallel"
70
71 SCANBUILD=
72 if [ "$(uname)" = Linux ] \
73        && [ "$ROOT_BUILD_CAUSE_TIMERTRIGGER" = true ]; then
74     # We only do scan-builds (which are really slow) on nightly
75     # builds.
76     SCANBUILD="scan-build -o ${WORKSPACE}/clangScanBuildReports -v"
77 fi
78 CONFIGUREFLAGS=
79 SANFLAGS=""
80 if [ "$(uname)" = Linux ]; then
81     # XXX: We should check if the sanitizers are available.
82     SANFLAGS="-fsanitize=undefined -fsanitize=address"
83 fi
84
85 if [ "$(uname)" = Darwin ]; then
86     # XXX until we properly set this somewhere else
87     cversion="_DARWIN_C_SOURCE=900000L"
88     CFLAGS="$CFLAGS -D$cversion"
89     CXXFLAGS="$CXXFLAGS -D$cversion"
90 fi
91
92 # Tweak the build depending on the package.
93 case "$JOB_NAME" in
94     *tgpg*)
95         MAKEFLAGS="$MAKEFLAGS GPG=/usr/bin/gpg2"
96         ;;
97     *gpgme*)
98         # using libasan for python broke again, so disable the python
99         # bindings for the sanitizer build
100         if [ "$XTARGET" = sanitizer ]; then
101             CONFIGUREFLAGS_0="--enable-languages=cpp qt"
102         fi
103
104         # Disable Python bindings on macOS.  Something is not working
105         # there.
106         if [ "$NODE_NAME" = zygalski ]; then
107             CONFIGUREFLAGS_0="--enable-languages=cpp qt"
108         fi
109         ;;
110     *gnupg*)
111         # Common configure options.
112         CONFIGUREFLAGS="--enable-wks-tools --enable-gpg2-is-gpg"
113
114         # For Windows builds...
115         if [ "$XTARGET" = w32 ]; then
116             # ... we need to tweak it a little and we leave out some
117             # stuff...
118             CONFIGUREFLAGS="$CONFIGUREFLAGS --with-zlib=$ORIGINAL_PREFIX --with-bzip2=$ORIGINAL_PREFIX"
119         else
120             # ... that we enable for all other builds.
121             CONFIGUREFLAGS="$CONFIGUREFLAGS --enable-g13 --enable-symcryptrun"
122         fi
123
124         if [ "$NODE_NAME" = zygalski ]; then
125             CONFIGUREFLAGS="$CONFIGUREFLAGS --with-libiconv-prefix=$HOME/pkg"
126         fi
127         if [ "$NODE_NAME" = openbsd60 ]; then
128             CONFIGUREFLAGS="$CONFIGUREFLAGS --with-libiconv-prefix=$HOME/compat --with-bzip2=$HOME/compat"
129         fi
130
131         # Disable NTBTLS for now until it is actually mature and used.
132         CONFIGUREFLAGS="$CONFIGUREFLAGS --disable-ntbtls"
133         ;;
134 esac
135
136 # See if we have a GPGME checkout for the tesets.
137 xtest_gpgme_srcdir="$HOME/src/gpgme-for-gnupgs-tests"
138 if [ -d "$xtest_gpgme_srcdir/obj-$XTARGET" ]; then
139     # Some targets, like the sanitizer target, require a custom
140     # version of GPGME.
141     export XTEST_GPGME_SRCDIR="$xtest_gpgme_srcdir"
142     export XTEST_GPGME_BUILDDIR="$xtest_gpgme_srcdir/obj-$XTARGET"
143 elif [ -d "$xtest_gpgme_srcdir/obj" ]; then
144     export XTEST_GPGME_SRCDIR="$xtest_gpgme_srcdir"
145     export XTEST_GPGME_BUILDDIR="$xtest_gpgme_srcdir/obj"
146 fi
147
148 # The libraries use RUNPATH when linking the tests, so they locate
149 # their dependencies that way.  GnuPG, however, does not.  Therefore,
150 # we set LD_LIBRARY_PATH.
151 test_environment="LD_LIBRARY_PATH=$ORIGINAL_PREFIX/lib"
152
153 # HACKHACKHACK:
154 #
155 # Because newer Debian toolchains prefer RUNPATH over RPATH, and
156 # RUNPATH has lower precedence than LD_LIBRARY_PATH, we need to
157 # explicitly add libtool's .libs directory:
158 case "$JOB_NAME" in
159   *gnupg*)
160     if [ "${XTEST_GPGME_BUILDDIR}" ]; then
161         test_environment="LD_LIBRARY_PATH=${XTEST_GPGME_BUILDDIR}/src/.libs:${XTEST_GPGME_BUILDDIR}/lang/cpp/src/.libs:${XTEST_GPGME_BUILDDIR}/lang/qt/src/.libs:$ORIGINAL_PREFIX/lib"
162     fi
163     ;;
164   *gpgme*)
165     test_environment="LD_LIBRARY_PATH=$(pwd)/obj/src/.libs:$(pwd)/obj/lang/cpp/src/.libs:$(pwd)/obj/lang/qt/src/.libs:$ORIGINAL_PREFIX/lib"
166     ;;
167   *)
168     test_environment="LD_LIBRARY_PATH=$(pwd)/obj/src/.libs:$ORIGINAL_PREFIX/lib"
169     ;;
170 esac
171 #
172 # If we don't do this, the version tests fail because the runtime
173 # linker will pick up the library from LD_LIBRARY_PATH.  Also, testing
174 # the installed version is not what we want ofc.
175 #
176 # KCAHKCAHKCAH
177
178 # We build on the "obj" subdir.
179 abs_configure="$(pwd)/configure"
180 mkdir -p obj
181 cd obj
182
183
184 # Print the environment.
185 env
186 ulimit -a
187 set +x
188 for f in /etc/gcrypt/hwf.deny /etc/gcrypt/fips_enabled ; do
189   if [ -f "$f" ]; then
190     echo "=== $f ==="
191     cat -n "$f"
192   fi
193 done
194 set -x
195
196
197 # Switch on the different targets.
198 case "$XTARGET" in
199     native)
200         ../configure --prefix=$PREFIX --enable-maintainer-mode \
201                    $CONFIGUREFLAGS \
202                    "$CONFIGUREFLAGS_0" \
203                    CFLAGS="$CFLAGS" \
204                    CXXFLAGS="$CXXFLAGS -std=c++11"
205         $MAKE $MAKEFLAGS
206
207         env $test_environment $MAKE -k check verbose=2 \
208             || echo "FAIL: make check failed with status $?"
209         # Jenkins looks for "FAIL:" to mark a build unstable,
210         # hence || ... here
211
212         $MAKE install
213         ;;
214     in-tree)
215         cd ..
216         ./configure --prefix=$PREFIX --enable-maintainer-mode \
217                    $CONFIGUREFLAGS \
218                    "$CONFIGUREFLAGS_0" \
219                    CFLAGS="$CFLAGS" \
220                    CXXFLAGS="$CXXFLAGS -std=c++11"
221         $MAKE $MAKEFLAGS
222
223         # HACKHACKHACK: Fix the test_environment hack.
224         test_environment="$(echo $test_environment | sed -e 's#obj/##g')"
225         # KCAHKCAHKCAH
226
227         env $test_environment $MAKE -k check verbose=2 \
228             || echo "FAIL: make check failed with status $?"
229         # Jenkins looks for "FAIL:" to mark a build unstable,
230         # hence || ... here
231
232         $MAKE install
233         ;;
234     sanitizer)
235         # asan breaks the configure tests, so we disable it here.
236         ASAN_OPTIONS=detect_leaks=0 \
237         $SCANBUILD \
238             ../configure --prefix=$PREFIX --enable-maintainer-mode \
239                    $CONFIGUREFLAGS \
240                    "$CONFIGUREFLAGS_0" \
241                    CFLAGS="$CFLAGS $SANFLAGS -fPIC" \
242                    CXXFLAGS="$CXXFLAGS $SANFLAGS -fPIC -std=c++11"
243         $SCANBUILD $MAKE $MAKEFLAGS
244
245         env $test_environment $MAKE -k check verbose=2 \
246             || echo "FAIL: make check failed with status $?"
247         # Jenkins looks for "FAIL:" to mark a build unstable,
248         # hence || ... here
249
250         $MAKE install
251         ;;
252     w32)
253         export w32root=$PREFIX
254
255         # autogen.rc adds --with-gpg-error-prefix=@SYSROOT@, so we cannot
256         # install to a prefix that doesn't also contain all the dependencies,
257         # patch that out, so that the gpg-error-config and friends are located
258         # using PATH
259         if [ -f "/home/jenkins/bin/$(dirname $JOB_NAME)-w32.patch" ]; then
260           ( cd .. && patch -p1 <"/home/jenkins/bin/$(dirname $JOB_NAME)-w32.patch" )
261         fi
262         # We need to point it to npth then...
263         case "$JOB_NAME" in
264             gnupg/XTARGET=w32|gnupg-2.2/XTARGET=w32)
265                 CONFIGUREFLAGS="${CONFIGUREFLAGS} --with-npth-prefix=$ORIGINAL_PREFIX"
266                 ;;
267             gnupg-2.0/XTARGET=w32)
268                 CONFIGUREFLAGS="${CONFIGUREFLAGS} --with-pth-prefix=$ORIGINAL_PREFIX --with-adns=$ORIGINAL_PREFIX"
269                 ;;
270         esac
271
272         # gpg1's autogen.sh does not add --enable-maintainer-mode, so
273         # version.texi is not generated.  we add it here to be sure.
274         # likewise for --prefix
275         ../autogen.sh --build-w32 --enable-maintainer-mode --prefix=$PREFIX \
276           $CONFIGUREFLAGS
277         $MAKE $MAKEFLAGS
278         $MAKE install
279
280         case "$JOB_NAME" in
281                 gnupg/*|gnupg-2.2/*)
282                         bash /home/jenkins/bin/make-windows-cd.sh
283                         # We need to pass the absolute path of the iso.
284                         bash $HOME/bin/run-tests-w32.bash "$(readlink -f gnupg-test.iso)" || echo "Warning: error running tests on Windows."
285                         ;;
286         esac
287         ;;
288     distcheck)
289         CONFIGUREFLAGS=
290         WORKDIR="$(mktemp -d)"
291         cleanup()
292         {
293           cd /tmp
294           fix_permissions "$WORKDIR"
295           rm -rf -- "$WORKDIR" || true
296         }
297         trap cleanup EXIT
298
299           # We use a different WORKDIR to avoid problems with too long
300           # file names
301           cd "$WORKDIR"
302           $abs_configure --prefix=$PREFIX --enable-maintainer-mode \
303                    $CONFIGUREFLAGS
304
305           # Extract the directory / tarname from the package
306           tarname=$(awk <config.h '
307                      /^#define PACKAGE_TARNAME/ {gsub(/"/,"",$3);name=$3};
308                      /^#define PACKAGE_VERSION/ {gsub(/"/,"",$3);vers=$3};
309                      END {print name "-" vers}')
310
311           # HACKHACKHACK: Because newer Debian toolchains prefer
312           # RUNPATH over RPATH, and RUNPATH has lower precedence than
313           # LD_LIBRARY_PATH, we need to explicitly add libtool's .libs
314           # directory:
315           case "$JOB_NAME" in
316             *gnupg*)
317               if [ "${XTEST_GPGME_BUILDDIR}" ]; then
318                   test_environment="LD_LIBRARY_PATH=${XTEST_GPGME_BUILDDIR}/src/.libs:${XTEST_GPGME_BUILDDIR}/lang/cpp/src/.libs:${XTEST_GPGME_BUILDDIR}/lang/qt/src/.libs:$ORIGINAL_PREFIX/lib"
319               fi
320               ;;
321             *gpgme*)
322               test_environment="LD_LIBRARY_PATH=$(pwd)/${tarname}/_build/sub/src/.libs:$(pwd)/${tarname}/_build/sub/lang/cpp/src/.libs:$(pwd)/${tarname}/_build/sub/lang/qt/src/.libs:$ORIGINAL_PREFIX/lib"
323               ;;
324             *)
325               test_environment="LD_LIBRARY_PATH=$(pwd)/${tarname}/_build/sub/src/.libs:$ORIGINAL_PREFIX/lib"
326               ;;
327           esac
328           # KCAHKCAHKCAH
329
330           if ! env $test_environment $MAKE $MAKEFLAGS distcheck ; then
331               # Jenkins looks for "FAIL:" to mark a build unstable,
332               # hence we ignore errors here.
333               echo "FAIL: make distcheck failed with status $?"
334               # Disable the cleanup so that we can investigate.
335               trap - EXIT
336               exit 0
337           fi
338
339           if [ -f "${tarname}.tar.bz2" ]; then
340              bzcat "${tarname}.tar.bz2" | tar xf -
341           elif [ -f "${tarname}.tar.gz" ]; then
342              zcat "${tarname}.tar.gz" | tar xf -
343           else
344              echo "No tarball named $tarname found - skipping installation" >&2
345              exit 0
346           fi
347           # And do a final build using the generated tarball
348           cd ${tarname}
349           ./configure --prefix=$PREFIX $CONFIGUREFLAGS
350           $MAKE $MAKEFLAGS
351           $MAKE $MAKEFLAGS install
352
353         ;;
354     *)
355         echo "Bad XTARGET: '$XTARGET'"
356         exit 2
357 esac