1#!/bin/sh
2set -o xtrace   # Write all commands first to stderr
3set -o errexit  # Exit the script with error if any of the commands fail
4
5# Supported/used environment variables:
6#       CFLAGS                  Additional compiler flags
7#       MARCH                   Machine Architecture. Defaults to lowercase uname -m
8#       RELEASE                 Use the fully qualified release archive
9#       DEBUG                   Use debug configure flags
10#       VALGRIND                Run the test suite through valgrind
11#       CC                      Which compiler to use
12#       ANALYZE                 Run the build through clangs scan-build
13#       COVERAGE                Produce code coverage reports
14#       LIBBSON                 Build against bundled or external libbson
15#       EXTRA_CONFIGURE_FLAGS   Extra configure flags to use
16
17RELEASE=${RELEASE:-no}
18DEBUG=${DEBUG:-no}
19VALGRIND=${VALGRIND:-no}
20ANALYZE=${ANALYZE:-no}
21COVERAGE=${COVERAGE:-no}
22SASL=${SASL:-no}
23SSL=${SSL:-no}
24SNAPPY=${SNAPPY:-bundled}
25ZLIB=${ZLIB:-bundled}
26INSTALL_DIR=$(pwd)/install-dir
27
28echo "CFLAGS: $CFLAGS"
29echo "MARCH: $MARCH"
30echo "RELEASE: $RELEASE"
31echo "DEBUG: $DEBUG"
32echo "VALGRIND: $VALGRIND"
33echo "CC: $CC"
34echo "ANALYZE: $ANALYZE"
35echo "COVERAGE: $COVERAGE"
36
37# Get the kernel name, lowercased
38OS=$(uname -s | tr '[:upper:]' '[:lower:]')
39echo "OS: $OS"
40
41# Automatically retrieve the machine architecture, lowercase, unless provided
42# as an environment variable (e.g. to force 32bit)
43[ -z "$MARCH" ] && MARCH=$(uname -m | tr '[:upper:]' '[:lower:]')
44
45# Default configure flags for debug builds and release builds
46DEBUG_FLAGS="\
47   --enable-html-docs=no \
48   --enable-man-pages=no \
49   --enable-optimizations=no \
50   --enable-extra-align=no \
51   --enable-maintainer-flags \
52   --enable-debug \
53   --disable-silent-rules \
54   --disable-automatic-init-and-cleanup \
55   --prefix=$INSTALL_DIR \
56"
57
58RELEASE_FLAGS="\
59   --enable-man-pages=no \
60   --enable-html-docs=no \
61   --enable-extra-align=no \
62   --enable-optimizations \
63   --disable-automatic-init-and-cleanup \
64   --prefix=$INSTALL_DIR \
65"
66if [ "$LIBBSON" = "external" ]; then
67   RELEASE_FLAGS="$RELEASE_FLAGS --with-libbson=system"
68   DEBUG_FLAGS="$DEBUG_FLAGS --with-libbson=system"
69else
70   RELEASE_FLAGS="$RELEASE_FLAGS --with-libbson=bundled"
71   DEBUG_FLAGS="$DEBUG_FLAGS --with-libbson=bundled"
72fi
73if [ ! -z "$ZLIB" ]; then
74   RELEASE_FLAGS="$RELEASE_FLAGS --with-zlib=${ZLIB}"
75   DEBUG_FLAGS="$DEBUG_FLAGS --with-zlib=${ZLIB}"
76fi
77if [ ! -z "$SNAPPY" ]; then
78   RELEASE_FLAGS="$RELEASE_FLAGS --with-snappy=${SNAPPY}"
79   DEBUG_FLAGS="$DEBUG_FLAGS --with-snappy=${SNAPPY}"
80fi
81
82# By default we build from git clone, which requires autotools
83# This gets overwritten if we detect we should use the release archive
84CONFIGURE_SCRIPT="./autogen.sh"
85
86
87# --strip-components is an GNU tar extension. Check if the platform
88# has GNU tar installed as `gtar`, otherwise we assume to be on
89# platform that supports it
90# command -v returns success error code if found and prints the path to it
91if command -v gtar 2>/dev/null; then
92   TAR=gtar
93else
94   TAR=tar
95fi
96
97# Available on our Ubuntu 16.04 images
98[ "$ANALYZE" = "yes" ] && SCAN_BUILD="scan-build -o scan --status-bugs"
99
100[ "$DEBUG" = "yes" ] && CONFIGURE_FLAGS=$DEBUG_FLAGS || CONFIGURE_FLAGS=$RELEASE_FLAGS
101
102CONFIGURE_FLAGS="$CONFIGURE_FLAGS --enable-sasl=${SASL}"
103CONFIGURE_FLAGS="$CONFIGURE_FLAGS --enable-ssl=${SSL}"
104[ "$COVERAGE" = "yes" ] && CONFIGURE_FLAGS="$CONFIGURE_FLAGS --enable-coverage --disable-examples"
105
106[ "$VALGRIND" = "yes" ] && TARGET="valgrind" || TARGET="test"
107
108if [ "$RELEASE" = "yes" ]; then
109   # Build from the release tarball.
110   mkdir build-dir
111   $TAR xf ../mongoc.tar.gz -C build-dir --strip-components=1
112   cd build-dir
113   CONFIGURE_SCRIPT="./configure"
114fi
115
116#if ldconfig -N -v 2>/dev/null | grep -q libSegFault.so; then
117   #export SEGFAULT_SIGNALS="all"
118   #export LD_PRELOAD="libSegFault.so"
119#fi
120
121# UndefinedBehaviorSanitizer configuration
122UBSAN_OPTIONS="print_stacktrace=1 abort_on_error=1"
123# AddressSanitizer configuration
124ASAN_OPTIONS="detect_leaks=1 abort_on_error=1"
125# LeakSanitizer configuration
126LSAN_OPTIONS="log_pointers=true"
127
128case "$MARCH" in
129   i386)
130      CFLAGS="$CFLAGS -m32 -march=i386"
131      CXXFLAGS="$CXXFLAGS -m32 -march=i386"
132      CONFIGURE_FLAGS="$CONFIGURE_FLAGS --with-snappy=bundled --with-zlib=bundled"
133   ;;
134   s390x)
135      CFLAGS="$CFLAGS -march=z196 -mtune=zEC12"
136      CXXFLAGS="$CXXFLAGS -march=z196 -mtune=zEC12"
137   ;;
138   x86_64)
139      CFLAGS="$CFLAGS -m64 -march=x86-64"
140      CXXFLAGS="$CXXFLAGS -m64 -march=x86-64"
141   ;;
142   ppc64le)
143      CFLAGS="$CFLAGS -mcpu=power8 -mtune=power8 -mcmodel=medium"
144      CXXFLAGS="$CXXFLAGS -mcpu=power8 -mtune=power8 -mcmodel=medium"
145   ;;
146esac
147CFLAGS="$CFLAGS -Werror"
148
149
150case "$OS" in
151   darwin)
152      CFLAGS="$CFLAGS -Wno-unknown-pragmas"
153      export DYLD_LIBRARY_PATH=".libs:src/libbson/.libs:$LD_LIBRARY_PATH"
154      # llvm-cov is installed from brew
155      export PATH=$PATH:/usr/local/opt/llvm/bin
156   ;;
157
158   linux)
159      # Make linux builds a tad faster by parallelise the build
160      cpus=$(grep -c '^processor' /proc/cpuinfo)
161      MAKEFLAGS="-j${cpus}"
162      export LD_LIBRARY_PATH=".libs:src/libbson/.libs:$LD_LIBRARY_PATH"
163   ;;
164esac
165
166case "$CC" in
167   clang)
168      CXX=clang++
169   ;;
170   gcc)
171      CXX=g++
172   ;;
173esac
174
175CONFIGURE_FLAGS="$CONFIGURE_FLAGS $EXTRA_CONFIGURE_FLAGS"
176export MONGOC_TEST_FUTURE_TIMEOUT_MS=30000
177export MONGOC_TEST_SKIP_LIVE=on
178export MONGOC_TEST_SKIP_SLOW=on
179
180export CFLAGS="$CFLAGS"
181export CXXFLAGS="$CXXFLAGS"
182export CC="$CC"
183export CXX="$CXX"
184
185if [ "$LIBBSON" = "external" ]; then
186   # This usually happens in mongoc ./autogen.sh, but since we are compiling against
187   # external libbson we need to install libbson before running mongoc ./autogen.sh
188   git submodule update --init
189   cd src/libbson
190   ./autogen.sh $CONFIGURE_FLAGS
191   make all
192   make install
193   cd ../../
194fi
195export PKG_CONFIG_PATH=$INSTALL_DIR/lib/pkgconfig:$PKG_CONFIG_PATH
196
197export PATH=$INSTALL_DIR/bin:$PATH
198echo "OpenSSL Version:"
199pkg-config --modversion libssl || true
200
201$SCAN_BUILD $CONFIGURE_SCRIPT $CONFIGURE_FLAGS
202# This needs to be exported _after_ running autogen as the $CONFIGURE_SCRIPT might
203# use git to fetch the submodules, which uses libcurl which is linked against
204# the system openssl which isn't abi compatible with our custom openssl/libressl
205export LD_LIBRARY_PATH=$EXTRA_LIB_PATH:$LD_LIBRARY_PATH
206export DYLD_LIBRARY_PATH=$EXTRA_LIB_PATH:$DYLD_LIBRARY_PATH
207openssl version
208if [ -n "$SSL_VERSION" ]; then
209   openssl version | grep -q $SSL_VERSION
210fi
211# This should fail when using fips capable OpenSSL when fips mode is enabled
212openssl md5 README.rst || true
213$SCAN_BUILD make all
214
215# Write stderr to error.log and to console.
216mkfifo pipe
217tee error.log < pipe &
218$SCAN_BUILD make $TARGET TEST_ARGS="-d -F test-results.json" 2>pipe
219rm pipe
220
221# Check if the error.log exists, and is more than 0 byte
222if [ -s error.log ]; then
223   cat error.log
224
225   if [ "$CHECK_LOG" = "yes" ]; then
226      # Ignore ar(1) warnings, and check the log again
227      grep -v "^ar: " error.log > log.log
228      if [ -s log.log ]; then
229         cat error.log
230         # Mark build as failed if there is unknown things in the log
231         exit 2
232      fi
233   fi
234fi
235
236
237if [ "$COVERAGE" = "yes" ]; then
238   case "$CC" in
239      clang)
240         lcov --gcov-tool `pwd`/.evergreen/llvm-gcov.sh --capture --derive-func-data --directory . --output-file .coverage.lcov --no-external
241         ;;
242      *)
243         lcov --gcov-tool gcov --capture --derive-func-data --directory . --output-file .coverage.lcov --no-external
244         ;;
245   esac
246   genhtml .coverage.lcov --legend --title "mongoc code coverage" --output-directory coverage
247fi
248