1#! /bin/sh
2# Simple configure script for c-lightning.
3
4set -e
5
6CONFIGURATOR=ccan/tools/configurator/configurator
7CONFIG_VAR_FILE=config.vars
8CONFIG_HEADER=ccan/config.h
9BASE_WARNFLAGS="-Wall -Wundef -Wmissing-prototypes -Wmissing-declarations -Wstrict-prototypes -Wold-style-definition -Werror"
10
11: ${PKG_CONFIG=pkg-config}
12
13# You can set PG_CONFIG in the environment to direct configure to call
14# a specific 'pg_config' binary. If you set it to an empty string, then
15# PostgreSQL support will be explicitly disabled, even if a 'pg_config'
16# binary exists in your PATH. If you leave it unset, then the following
17# line enables the automagic detection that most users want.
18: ${PG_CONFIG=pg_config}
19
20usage_with_default()
21{
22    if [ $# = 4 ]; then
23	if [ "$2" = 1 ]; then
24	    DEF=$3
25	else
26	    DEF=$4
27	fi
28    else
29	DEF=$2
30    fi
31    echo "  $1 (default $DEF)"
32}
33
34# Given DEVELOPER, what COPTFLAGS do we default to.
35default_coptflags()
36{
37    if [ "$1" = 0 ]; then
38	echo "-Og"
39    fi
40}
41
42# Given COPTFLAGS, HAVE_GCC and HAVE_MODERN_GCC, what CWARNFLAGS to default to?
43default_cwarnflags()
44{
45    F=$BASE_WARNFLAGS
46    # Clang doesn't like -Wno-maybe-uninitialized, but doesn't seem
47    # to give spurious warnings, either.
48    if [ "$2" = 1 ]; then
49	# With old gccs, or optimization != -O3, we need to suppress some warnings.
50	if [ -n "${1##*-O3*}" ] || [ "$3" != "1" ]; then
51	    F="$F -Wno-maybe-uninitialized"
52	fi
53    fi
54    echo "$F"
55}
56
57default_pytest()
58{
59    # Since we just checked that we have python3 we give that one the
60    # most priority and then fall back to some common aliases.
61    PYTEST_BINS="python3 -m pytest,pytest,py.test,pytest3,pytest-3"
62    IFS=','
63    for p in $PYTEST_BINS; do
64	# If it is a combined command such as `python3 -m pytest` we
65	# want to only call which on the executable
66	exe=$(echo "$p" | awk '{print $1}')
67	# shellcheck disable=SC2086
68	if [ "$(which $exe)" != "" ] ; then
69	    "$p" --version 2>&1 | grep -q "pytest" || continue
70	    echo "$p"
71	    return
72	fi
73    done
74
75    PYTHON_BINS="python python3"
76    for p in $PYTHON_BINS; do
77        if [ "$(which $p)" != "" ] ; then
78            $p --version 2>&1 | grep -q "Python 3." || continue
79            if $p -c "import pytest" 2>/dev/null ; then
80                echo "$p -m pytest"
81                return
82            fi
83        fi
84    done
85}
86
87check_command()
88{
89    name="$1"
90    shift 1
91
92    echo -n "checking for $name... "
93    if "$@" >/dev/null 2>&1; then
94	echo 'found'
95	return 0
96    fi
97    echo 'not found'
98    return 1
99}
100
101default_valgrind_setting()
102{
103    # Valgrind must accept all these options (might exit with error 7 though
104    # if /bin/true leaks mem on your system!)
105    if valgrind -q --error-exitcode=7 --track-origins=yes --leak-check=full --show-reachable=yes --errors-for-leak-kinds=all /bin/true >/dev/null 2>&1 || [ $? = 7 ]; then
106	echo 1
107    else
108	echo 0
109    fi
110}
111
112set_defaults()
113{
114    # Default values, loaded from environment or canned.
115    # Note that ":-" means substitute if empty or unset, "-" means only if unset
116    # which matters since you might explicitly set of these blank.
117    PREFIX=${PREFIX:-/usr/local}
118    CC=${CC:-cc}
119    CDEBUGFLAGS=${CDEBUGFLAGS--std=gnu11 -g -fstack-protector-strong}
120    DEVELOPER=${DEVELOPER:-0}
121    EXPERIMENTAL_FEATURES=${EXPERIMENTAL_FEATURES:-0}
122    COMPAT=${COMPAT:-1}
123    STATIC=${STATIC:-0}
124    ASAN=${ASAN:-0}
125    UBSAN=${UBSAN:-0}
126    PYTEST=${PYTEST-$(default_pytest)}
127    COPTFLAGS=${COPTFLAGS-$(default_coptflags "$DEVELOPER")}
128    CONFIGURATOR_CC=${CONFIGURATOR_CC-$CC}
129    VALGRIND=${VALGRIND:-$(default_valgrind_setting)}
130    TEST_NETWORK=${TEST_NETWORK:-regtest}
131    FUZZING=${FUZZING:-0}
132}
133
134usage()
135{
136    echo "Usage: ./configure [--reconfigure] [setting=value] [options]"
137    echo "If --reconfigure is specified, $CONFIG_VAR_FILE will set defaults."
138    echo "Default settings:"
139    set_defaults
140    DEFAULT_COPTFLAGS="$(default_coptflags $DEVELOPER)"
141    # We assume we have a modern gcc.
142    DEFAULT_CWARNFLAGS="$(default_cwarnflags ""$DEFAULT_COPTFLAGS"" 1 1)"
143    usage_with_default "CC" "$CC"
144    usage_with_default "CWARNFLAGS" "$DEFAULT_CWARNFLAGS"
145    usage_with_default "COPTFLAGS" "$DEFAULT_COPTFLAGS"
146    usage_with_default "CDEBUGFLAGS" "$CDEBUGFLAGS"
147    usage_with_default "CONFIGURATOR_CC" "${CONFIGURATOR_CC:-$CC}"
148    echo "    To override compile line for configurator itself"
149    usage_with_default "PYTEST" "$PYTEST"
150    usage_with_default "VALGRIND" "$VALGRIND"
151
152    echo "Options include:"
153    usage_with_default "--prefix=" "$PREFIX"
154    echo "    Prefix for make install"
155    usage_with_default "--enable/disable-developer" "$DEVELOPER" "enable" "disable"
156    echo "    Developer mode, good for testing"
157    usage_with_default "--enable/disable-experimental-features" "$EXPERIMENTAL_FEATURES" "enable" "disable"
158    echo "    Enable experimental features"
159    usage_with_default "--enable/disable-compat" "$COMPAT" "enable" "disable"
160    echo "    Compatibility mode, good to disable to see if your software breaks"
161    usage_with_default "--enable/disable-valgrind" "(autodetect)"
162    echo "    Run tests with Valgrind"
163    usage_with_default "--enable/disable-static" "$STATIC" "enable" "disable"
164    echo "    Static link sqlite3, gmp and zlib libraries"
165    usage_with_default "--enable/disable-address-sanitizer" "$ASAN" "enable" "disable"
166    echo "    Compile with address-sanitizer"
167    usage_with_default "--enable/disable-ub-sanitizer" "$UBSAN" "enable" "disable"
168    echo "    Compile with undefined behaviour sanitizer"
169    usage_with_default "--enable/disable-fuzzing" "$FUZZING" "enable" "disable"
170    exit 1
171}
172
173add_var()
174{
175    if [ -n "$2" ]; then
176        echo "Setting $1... $2"
177    else
178        echo "$1 not found"
179    fi
180    echo "$1=$2" >> $CONFIG_VAR_FILE.$$
181    [ -z "$3" ] || echo "#define $1 $2" >> "$3"
182}
183
184for opt in "$@"; do
185    case "$opt" in
186	--reconfigure)
187	    # Figure out what defaulT COPTFLAGS was for this config.vars
188	    DEFAULT_COPTFLAGS=
189	    # Set from values if not already set.
190	    while IFS='=' read VAR VAL; do
191		if eval [ -z \${$VAR+x} ]; then eval $VAR=\"$VAL\"; fi
192		if [ "$VAR" = DEVELOPER ]; then
193		   DEFAULT_COPTFLAGS=$(default_coptflags "$VAL")
194		fi
195	    done < $CONFIG_VAR_FILE
196	    # If we were those defaults, unset so we get new defaults in
197	    # case DEVELOPER has changed.
198	    if [ x"$COPTFLAGS" = x"$DEFAULT_COPTFLAGS" ]; then
199		unset COPTFLAGS
200	    fi
201	    ;;
202	CC=*) CC="${opt#CC=}";;
203	CONFIGURATOR_CC=*) CONFIGURATOR_CC="${opt#CONFIGURATOR_CC=}";;
204	CWARNFLAGS=*) CWARNFLAGS="${opt#CWARNFLAGS=}";;
205	CDEBUGFLAGS=*) CDEBUGFLAGS="${opt#CDEBUGFLAGS=}";;
206	COPTFLAGS=*) COPTFLAGS="${opt#COPTFLAGS=}";;
207	PYTEST=*) PYTEST="${opt#PYTEST=}";;
208	--prefix=*) PREFIX="${opt#--prefix=}";;
209	--enable-developer) DEVELOPER=1;;
210	--disable-developer) DEVELOPER=0;;
211	--enable-experimental-features) EXPERIMENTAL_FEATURES=1;;
212	--disable-experimental-features) EXPERIMENTAL_FEATURES=0;;
213	--enable-compat) COMPAT=1;;
214	--disable-compat) COMPAT=0;;
215	--enable-valgrind) VALGRIND=1;;
216	--disable-valgrind) VALGRIND=0;;
217	--enable-static) STATIC=1;;
218	--disable-static) STATIC=0;;
219	--enable-address-sanitizer) ASAN=1;;
220	--disable-address-sanitizer) ASAN=0;;
221	--enable-ub-sanitizer) UBSAN=1;;
222	--disable-ub-sanitize) UBSAN=0;;
223	--enable-fuzzing) FUZZING=1;;
224	--disable-fuzzing) FUZZING=0;;
225	--help|-h) usage;;
226	*)
227	    echo "Unknown option '$opt'" >&2
228	    usage
229	    ;;
230    esac
231done
232
233# Now fill in any unset vars.
234set_defaults
235
236# We assume warning flags don't affect congfigurator that much!
237echo -n "Compiling $CONFIGURATOR..."
238$CC ${CWARNFLAGS-$BASE_WARNFLAGS} $CDEBUGFLAGS $COPTFLAGS -o $CONFIGURATOR $CONFIGURATOR.c
239echo "done"
240
241if [ "$ASAN" = "1" ]; then
242    if [ "$VALGRIND" = "1" ]; then
243	echo "Address sanitizer (ASAN) and valgrind cannot be enabled at the same time"
244	exit 1
245    fi
246fi
247
248if [ "$FUZZING" = "1" ]; then
249	case "$CC" in
250		(*"clang"*)
251			;;
252		(*)
253			echo "Fuzzing is currently only supported with clang."
254			exit 1
255			;;
256	esac
257fi
258
259
260SQLITE3_CFLAGS=""
261SQLITE3_LDLIBS="-lsqlite3"
262if command -v "${PKG_CONFIG}" >/dev/null; then
263    SQLITE3_CFLAGS="$("${PKG_CONFIG}" --silence-errors --cflags sqlite3 || :)"
264    SQLITE3_LDLIBS="$("${PKG_CONFIG}" --silence-errors --libs sqlite3 || :)"
265fi
266
267POSTGRES_INCLUDE=""
268POSTGRES_LDLIBS=""
269if command -v "${PG_CONFIG}" >/dev/null; then
270    POSTGRES_INCLUDE="-I$("${PG_CONFIG}" --includedir)"
271    POSTGRES_LDLIBS="-L$("${PG_CONFIG}" --libdir) -lpq"
272fi
273
274# Clean up on exit.
275trap "rm -f $CONFIG_VAR_FILE.$$" 0
276
277$CONFIGURATOR --extra-tests --autotools-style --var-file=$CONFIG_VAR_FILE.$$ --header-file=$CONFIG_HEADER.$$ --configurator-cc="$CONFIGURATOR_CC" --wrapper="$CONFIGURATOR_WRAPPER" "$CC" ${CWARNFLAGS-$BASE_WARNFLAGS} $CDEBUGFLAGS $COPTFLAGS -I/usr/local/include -L/usr/local/lib $SQLITE3_CFLAGS $POSTGRES_INCLUDE <<EOF
278
279var=HAVE_GOOD_LIBSODIUM
280desc=libsodium with IETF chacha20 variants
281style=DEFINES_EVERYTHING|EXECUTE|MAY_NOT_COMPILE
282link=-lsodium
283code=
284#include <sodium.h>
285#include <stdio.h>
286#include <string.h>
287
288int main(void)
289{
290	crypto_secretstream_xchacha20poly1305_state crypto_state;
291	unsigned char header[crypto_secretstream_xchacha20poly1305_HEADERBYTES];
292	unsigned char data[] = { 1, 2, 3 };
293
294	crypto_secretstream_xchacha20poly1305_init_push(&crypto_state, header,
295	                                                data);
296	printf("%p\n", crypto_aead_chacha20poly1305_ietf_encrypt);
297	printf("%d\n", crypto_aead_chacha20poly1305_ietf_NPUBBYTES);
298	return 0;
299}
300/*END*/
301var=HAVE_SQLITE3_EXPANDED_SQL
302desc=sqlite3_expanded_sql
303style=DEFINES_EVERYTHING|EXECUTE|MAY_NOT_COMPILE
304link=$SQLITE3_LDLIBS
305code=
306#include <sqlite3.h>
307#include <stdio.h>
308
309int main(void)
310{
311	printf("%p\n", sqlite3_expanded_sql);
312	return 0;
313}
314/*END*/
315var=HAVE_SQLITE3
316desc=sqlite3
317style=DEFINES_EVERYTHING|EXECUTE|MAY_NOT_COMPILE
318link=$SQLITE3_LDLIBS
319code=
320#include <sqlite3.h>
321#include <stdio.h>
322
323int main(void)
324{
325	printf("%p\n", sqlite3_prepare_v2);
326	return 0;
327}
328/*END*/
329var=HAVE_POSTGRES
330desc=postgres
331style=DEFINES_EVERYTHING|EXECUTE|MAY_NOT_COMPILE
332link=$POSTGRES_LDLIBS
333code=
334#include <libpq-fe.h>
335#include <stdio.h>
336
337int main(void)
338{
339	printf("libpq version %d\n", PQlibVersion());
340	return 0;
341}
342/*END*/
343var=HAVE_GCC
344desc=compiler is GCC
345style=OUTSIDE_MAIN
346code=
347#ifndef __GNUC__
348#error "Not GCC"
349#endif
350#ifdef __clang__
351#error "clang"
352#endif
353/*END*/
354var=HAVE_MODERN_GCC
355desc=GCC version is 7 or above
356style=OUTSIDE_MAIN
357code=
358#if __GNUC__ < 7
359#error "Not modern GCC"
360#endif
361/*END*/
362var=HAVE_PWRITEV
363desc=pwritev() defined
364style=DEFINES_EVERYTHING|EXECUTE|MAY_NOT_COMPILE
365code=
366#include <sys/uio.h>
367#include <sys/types.h>
368#include <sys/stat.h>
369#include <fcntl.h>
370
371int main(void)
372{
373	struct iovec iov[2];
374	int fd = open("/dev/null", O_WRONLY);
375
376	iov[0].iov_base = "hello";
377	iov[0].iov_len = 5;
378	iov[1].iov_base = " world";
379	iov[1].iov_len = 6;
380	if (pwritev(fd, iov, 2, 0) == 11)
381		return 0;
382	return 1;
383}
384/*END*/
385EOF
386
387if check_command 'python3-mako' python3 -c 'import mako'; then
388    HAVE_PYTHON3_MAKO=1
389else
390    HAVE_PYTHON3_MAKO=0
391fi
392
393if echo | check_command sha256sum sha256sum; then
394    SHA256SUM=sha256sum
395elif echo | check_command "shasum -a 256" shasum -a 256; then
396    SHA256SUM="shasum -a 256"
397elif echo | check_command sha256 sha256; then
398    SHA256SUM=sha256
399else
400    echo "*** We need sha256sum, shasum -a 256, or sha256!" >&2
401    exit 1
402fi
403
404# Now we can finally set our warning flags
405if [ -z ${CWARNFLAGS+x} ]; then
406    CWARNFLAGS=$(default_cwarnflags "$COPTFLAGS" \
407		    $(sed -n 's/^HAVE_GCC=//p' < $CONFIG_VAR_FILE.$$) \
408		    $(sed -n 's/^HAVE_MODERN_GCC=//p' < $CONFIG_VAR_FILE.$$) )
409fi
410
411add_var PREFIX "$PREFIX"
412add_var CC "$CC"
413add_var CONFIGURATOR_CC "$CONFIGURATOR_CC"
414add_var CWARNFLAGS "$CWARNFLAGS"
415add_var CDEBUGFLAGS "$CDEBUGFLAGS"
416add_var COPTFLAGS "$COPTFLAGS"
417add_var SQLITE3_CFLAGS "$SQLITE3_CFLAGS"
418add_var SQLITE3_LDLIBS "$SQLITE3_LDLIBS"
419add_var POSTGRES_INCLUDE "$POSTGRES_INCLUDE"
420add_var POSTGRES_LDLIBS "$POSTGRES_LDLIBS"
421add_var VALGRIND "$VALGRIND"
422add_var DEVELOPER "$DEVELOPER" $CONFIG_HEADER.$$
423add_var EXPERIMENTAL_FEATURES "$EXPERIMENTAL_FEATURES" $CONFIG_HEADER.$$
424add_var COMPAT "$COMPAT" $CONFIG_HEADER.$$
425add_var PYTEST "$PYTEST"
426add_var STATIC "$STATIC"
427add_var ASAN "$ASAN"
428add_var UBSAN "$UBSAN"
429add_var TEST_NETWORK "$TEST_NETWORK"
430add_var HAVE_PYTHON3_MAKO "$HAVE_PYTHON3_MAKO"
431add_var SHA256SUM "$SHA256SUM"
432add_var FUZZING "$FUZZING"
433
434# Hack to avoid sha256 name clash with libwally: will be fixed when that
435# becomes a standalone shared lib.
436echo '#include "ccan_compat.h"' >> $CONFIG_HEADER.$$
437
438# Now we set them all and check.
439while IFS='=' read VAR VAL; do
440    eval $VAR=\"$VAL\"
441done < $CONFIG_VAR_FILE.$$
442
443if [ "$HAVE_SQLITE3" = 0 -a "$HAVE_POSTGRES" = 0 ]; then
444    # I have no database yet I must schema!)
445    echo "*** We need a database, but neither sqlite3 nor postgres found" >&2
446    exit 1
447fi
448
449mv $CONFIG_VAR_FILE.$$ $CONFIG_VAR_FILE
450mv $CONFIG_HEADER.$$ $CONFIG_HEADER
451