1AC_PREREQ([2.63])
2AC_INIT([gdnsd],[2.4.3],[https://github.com/gdnsd/gdnsd/issues])
3AC_CONFIG_SRCDIR([src/main.c])
4AC_CONFIG_AUX_DIR([acaux])
5AM_INIT_AUTOMAKE([1.11.1 dist-xz no-dist-gzip foreign tar-ustar subdir-objects -Wall])
6AC_CONFIG_MACRO_DIR([m4])
7AM_SILENT_RULES([yes])
8
9## Autoconf-2.63-Compat
10# Future reference: both of the below could be addressed by bumping our
11# AC_PREREQ() to 2.64.  It's just a question of at what point in the future
12# the 2.63-using distros are old enough that it's reasonable to do so.
13#---
14# We're compatible to autoconf 2.63, which doesn't have PACKAGE_URL
15#   as a final arg to AC_INIT.  We can't define it ourselves here
16#   with the same name as this causes compiler warnings that matter
17#   during other parts of ./configure.  So, pick a new name for now.
18AC_DEFINE([PKG_URL],["http://gdnsd.org"],[Package URL])
19#---
20# This hack makes PKG_CHECK_VARS from m4/pkg.m4 work on autoconf 2.63
21# ( courtesy of sunnybear in https://github.com/gdnsd/gdnsd/issues/85 )
22m4_ifndef([AS_VAR_COPY],
23[m4_define([AS_VAR_COPY],
24[AS_LITERAL_IF([$1[]$2], [$1=$$2], [eval $1=\$$2])])])
25## End Autoconf-2.63-Compat
26
27# TODO: when/if a new autoconf release has a C11 macro,
28#    prefer that and fall back to requiring C99.
29AC_PROG_CC_C99
30if test "x$ac_cv_prog_cc_c99" = xno; then
31    AC_MSG_ERROR([Your compiler lacks sufficient C99 support])
32fi
33# AC_PROG_CC_C99 has to come before this or we don't get a C99 CPP
34AC_USE_SYSTEM_EXTENSIONS
35
36# This is explcitly checked by CC_C99 above for now, but
37#   the C11 standard reversed course and made this an optional
38#   feature, so we may as well double-check here for future-proofing
39AC_C_VARARRAYS
40if test "x$ac_cv_c_vararrays" = xno; then
41    AC_MSG_ERROR([Your compiler lacks support for variable arrays])
42fi
43
44AM_PROG_CC_C_O
45
46# POSIX threads stuff
47AX_PTHREAD(,AC_MSG_ERROR([POSIX threads support is required]))
48LIBS="$PTHREAD_LIBS $LIBS"
49CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
50CC="$PTHREAD_CC"
51
52AC_MSG_CHECKING([if compiling with clang])
53AC_COMPILE_IFELSE(
54[AC_LANG_PROGRAM([], [[
55#ifndef __clang__
56       not clang
57#endif
58]])],
59[CLANG=yes], [CLANG=no])
60AC_MSG_RESULT([$CLANG])
61
62# need to know endian-ness
63AC_C_BIGENDIAN
64
65# pointer width...
66AC_CHECK_SIZEOF(uintptr_t)
67
68# Apparently libtool+automake need this now, in newer versions
69#   which have it at all
70m4_ifdef([AM_PROG_AR], [AM_PROG_AR])
71
72# The libtool macros in 2.2.6b - 2.4.2 have a bug that causes
73#  them to accidentally add LIBADD_DLOPEN to LIBS permanently,
74#  so we workaround that by saving and restoring LIBS
75XLIBS=$LIBS
76AC_DISABLE_STATIC
77LT_INIT([dlopen])
78LT_PREREQ([2.2.6])
79LT_LIB_DLLOAD
80AC_SUBST([LIBTOOL_DEPS])
81AC_SUBST([LIBADD_DLOPEN])
82LIBS=$XLIBS
83
84# Check for --enable-developer
85developer=no
86AC_ARG_ENABLE([developer],
87    [  --enable-developer      Turn on gcc developer warnings, debugging, etc (default=no)],
88    [if test "x$enable_developer" = xyes; then developer=yes; fi])
89
90# normal builds set -DNDEBUG because we make very very heavy
91#   use of assertions that really slow stuff down.
92# --enable-developer sets liburcu debug stuff and doesn't set -DNDEBUG,
93if test "x$developer" != xno; then
94    AC_DEFINE([DEBUG_RCU], 1, [liburcu verification checks])
95    AC_DEFINE([RCU_DEBUG], 1, [liburcu verification checks])
96    TRY_DEBUG_CFLAGS=-g
97else
98    CPPFLAGS="-DNDEBUG ${CPPFLAGS}"
99    TRY_DEBUG_CFLAGS=
100fi
101
102# These are only for urcu header stuff currently
103AC_DEFINE([_LGPL_SOURCE], 1, [LGPL-compatible source])
104AC_DEFINE([GDNSD_SOURCE_TREE], 1, [Identifies local source vs 3rd party])
105
106harden=1
107AC_ARG_WITH([hardening],[AS_HELP_STRING([--without-hardening],
108    [Disable compiler/linker flags for security hardening])],[
109    if test "x$withval" = xno; then
110        harden=0
111    fi
112])
113HARDEN_COMPILER=
114HARDEN_LINKER=
115CFLAGS_PIE=
116LDFLAGS_PIE=
117if test $harden = 1; then
118    AS_CASE([$CFLAGS], [*-O[[1-6]]*], [CPPFLAGS="-D_FORTIFY_SOURCE=2 ${CPPFLAGS}"])
119    HARDEN_COMPILER="-fstack-protector-all -ftrapv"
120    HARDEN_LINKER="-Wl,-z,relro -Wl,-z,now -Wl,-z,noexecstack"
121    AX_APPEND_COMPILE_FLAGS([-fPIE],[CFLAGS_PIE],[])
122    AX_APPEND_LINK_FLAGS([-pie],[LDFLAGS_PIE],[])
123fi
124AC_SUBST([CFLAGS_PIE])
125AC_SUBST([LDFLAGS_PIE])
126
127# clang does not fail on some unsupported options without this,
128#  but it screws up some of our warnflag tests on gcc as well.
129CLANG_WERROR=
130if test $CLANG = yes; then
131   CLANG_WERROR="-Werror"
132fi
133
134AX_APPEND_LINK_FLAGS([\
135    $HARDEN_LINKER \
136    -Wl,--as-needed \
137    -Wl,--gc-sections \
138],[LDFLAGS],[$CLANG_WERROR])
139
140AX_APPEND_COMPILE_FLAGS([\
141    $TRY_DEBUG_CFLAGS \
142    $HARDEN_COMPILER \
143    -fvisibility=hidden \
144    -ffunction-sections \
145    -fdata-sections \
146    -fno-common \
147    -pipe \
148    -Wall \
149    -Wextra \
150    -Warray-bounds=2 \
151    -Wbad-function-cast \
152    -Wcast-align \
153    -Wcast-qual \
154    -Wduplicated-cond \
155    -Wendif-labels \
156    -Wfloat-equal \
157    -Wfloat-conversion \
158    -Wformat=2 \
159    -Wformat-signedness \
160    -Winit-self \
161    -Wjump-misses-init \
162    -Wlogical-op \
163    -Wloop-analysis \
164    -Wmissing-declarations \
165    -Wmissing-include-dirs \
166    -Wmissing-prototypes \
167    -Wnull-dereference \
168    -Wold-style-definition \
169    -Wpointer-arith \
170    -Wredundant-decls \
171    -Wshadow \
172    -Wsign-conversion \
173    -Wshift-overflow=2 \
174    -Wstrict-overflow=5 \
175    -Wstrict-prototypes \
176    -Wswitch-default \
177    -Wswitch-enum \
178    -Wtrampolines \
179    -Wundef \
180    -Wunused \
181    -Wwrite-strings \
182    -Wthis-does-not-exist \
183],[CFLAGS],[$CLANG_WERROR])
184
185# include libdmn configure stuff
186m4_include([libgdnsd/libdmn.m4])
187
188# include libgdmaps configure stuff
189m4_include([libgdmaps/libgdmaps.m4])
190
191# explicit check on math lib.  libev also does this, but
192#  might not in the future, and we need it directly
193XLIBS=$LIBS
194LIBS=""
195AC_CHECK_LIB(m,atan2)
196MATH_LIB=$LIBS
197LIBS=$XLIBS
198AC_SUBST([MATH_LIB])
199
200# posix_madvise to readahead on zonefiles
201AC_CHECK_FUNCS([posix_madvise])
202
203# high-precision mtime from struct stat
204AC_CHECK_MEMBERS([struct stat.st_mtim.tv_nsec])
205AC_CHECK_MEMBERS([struct stat.st_mtimespec.tv_nsec])
206AC_CHECK_MEMBERS([struct stat.st_mtimensec])
207
208# *mmsg for Linux
209HAS_SENDMMSG=1
210AC_CHECK_DECLS([sendmmsg, recvmmsg],,[HAS_SENDMMSG=0],[[#include <sys/socket.h>]])
211AC_CHECK_FUNCS([sendmmsg recvmmsg],,[HAS_SENDMMSG=0])
212if test $HAS_SENDMMSG -eq 1; then
213    AC_DEFINE([USE_SENDMMSG],1,[Linux sendmmsg is usable])
214fi
215
216# Network Stuff
217AC_DEFINE([__APPLE_USE_RFC_3542],1,[Force MacOS Lion and higher to use RFC3542 IPv6 stuff])
218
219# liburcu-qsbr
220KILL_QSBR=0
221AC_ARG_WITH([urcu],[AS_HELP_STRING([--without-urcu],
222    [Explicitly disable userspace-rcu detection])],[
223    if test "x$withval" = xno; then
224        KILL_QSBR=1
225    fi
226])
227
228GDNSD_B_QSBR=0
229QSBRLIBS=
230if test $KILL_QSBR -eq 0; then
231    AC_CHECK_HEADER(urcu-qsbr.h,[
232        XLIBS=$LIBS
233        LIBS=""
234        AC_CHECK_LIB([urcu-qsbr],[perror],[
235            GDNSD_B_QSBR=1
236            QSBRLIBS="-lurcu-qsbr"
237        ])
238        LIBS=$XLIBS
239    ])
240fi
241AC_DEFINE_UNQUOTED([GDNSD_B_QSBR], [$GDNSD_B_QSBR], [Use liburcu-qsbr])
242AC_SUBST([GDNSD_B_QSBR])
243AC_SUBST([QSBRLIBS])
244
245# systemd unit dir for "make install" of gdnsd.service
246PKG_CHECK_VAR([SYSD_UNITDIR], [systemd], [systemdsystemunitdir])
247AC_MSG_CHECKING([for systemd system unit installdir])
248AC_ARG_WITH([systemdsystemunitdir],
249        AS_HELP_STRING([--with-systemdsystemunitdir=DIR], [Directory for systemd service files]),
250        if test x"$with_systemdsystemunitdir" = xno; then
251            with_systemdsystemunitdir=""
252        fi,
253        [with_systemdsystemunitdir="$SYSD_UNITDIR"]
254)
255if test -n "$with_systemdsystemunitdir"; then
256    AC_MSG_RESULT([$with_systemdsystemunitdir])
257else
258    AC_MSG_RESULT([none])
259fi
260AC_SUBST([systemdsystemunitdir], [$with_systemdsystemunitdir])
261AM_CONDITIONAL(DO_SYSD_UNITFILE, [test -n "$with_systemdsystemunitdir"])
262
263# libev (which shouldn't use pkg-config anyways, but has
264#   to on Fedora because they munge the header path the author intended...)
265PKG_CHECK_MODULES([LIBEV],[libev >= 4.0],
266    CPPFLAGS="${CPPFLAGS} ${LIBEV_CFLAGS}"
267,
268    # try manually...
269    XLIBS=$LIBS
270    LIBS=""
271    AC_CHECK_LIB([ev],[ev_break],,AC_MSG_ERROR([libev 4.x library not found!]))
272    AC_CHECK_DECLS([EVBREAK_ALL],,AC_MSG_ERROR([libev 4.x headers not found!]),[
273        #include <ev.h>
274    ])
275    LIBEV_LIBS=$LIBS
276    LIBS=$XLIBS
277)
278AC_SUBST([LIBEV_LIBS])
279
280#---------------------------------------------
281# pthread setname (4 non-portable variants...)
282#---------------------------------------------
283AC_CHECK_HEADERS([pthread_np.h])
284define(pthread_np_preamble,[
285  #include <pthread.h>
286  #if HAVE_PTHREAD_NP_H
287  #  include <pthread_np.h>
288  #endif
289])
290# 2-arg setname (e.g. Linux/glibc, QNX, IBM)
291AC_MSG_CHECKING([for 2-arg pthread_setname_np])
292AC_LINK_IFELSE([AC_LANG_PROGRAM(pthread_np_preamble, [
293    pthread_setname_np(pthread_self(), "foo")
294])], [
295  AC_DEFINE(HAVE_PTHREAD_SETNAME_NP_2, 1, [2-arg pthread_setname_np])
296  AC_MSG_RESULT([yes])
297], [
298  AC_MSG_RESULT([no])
299
300  # 2-arg set_name (e.g. FreeBSD, OpenBSD)
301  AC_MSG_CHECKING([for 2-arg pthread_set_name_np])
302  AC_LINK_IFELSE([AC_LANG_PROGRAM(pthread_np_preamble, [
303      return pthread_set_name_np(pthread_self(), "foo");
304  ])], [
305    AC_DEFINE(HAVE_PTHREAD_SET_NAME_NP_2, 1, [2-arg pthread_set_name_np])
306    AC_MSG_RESULT([yes])
307  ], [
308    AC_MSG_RESULT([no])
309
310    # 1-arg setname (e.g. Darwin)
311    AC_MSG_CHECKING([for 1-arg pthread_setname_np])
312    AC_LINK_IFELSE([AC_LANG_PROGRAM(pthread_np_preamble, [
313        return pthread_setname_np("foo");
314    ])], [
315      AC_DEFINE(HAVE_PTHREAD_SETNAME_NP_1, 1, [1-arg pthread_setname_np])
316      AC_MSG_RESULT([yes])
317    ], [
318      AC_MSG_RESULT([no])
319
320      # 3-arg setname (e.g. NetBSD)
321      AC_MSG_CHECKING([for 3-arg pthread_setname_np])
322      AC_LINK_IFELSE([AC_LANG_PROGRAM(pthread_np_preamble, [
323          return pthread_setname_np(pthread_self(), "foo", NULL);
324      ])], [
325        AC_DEFINE(HAVE_PTHREAD_SETNAME_NP_3, 1, [3-arg pthread_setname_np])
326        AC_MSG_RESULT([yes])
327      ], [
328        AC_MSG_RESULT([no])
329      ])
330    ])
331  ])
332])
333#---------------------------------------------
334# end pthread_setname stuff
335#---------------------------------------------
336
337# == inotify stuff ==
338# inotify_init1() is Linux 2.6.27+ and glibc 2.9
339# We also use Linux 2.6.36+ / glibc 2.13 IN_EXCL_UNLINK, but we
340#   fix that with a manual ifndef for the define and a runtime
341#   kernel version check for the support
342USE_INOTIFY=1
343AC_CHECK_FUNCS([inotify_init1],,[USE_INOTIFY=0])
344if test $USE_INOTIFY -eq 1; then
345    AC_DEFINE([USE_INOTIFY], 1, [Linux 2.6.36+ inotify support])
346fi
347
348# Basic perl 5.10.1+
349AC_ARG_VAR([PERL],[path to Perl 5.10.1 or higher])
350if test "x$ac_cv_env_PERL_set" != "xset"; then
351    AC_PATH_PROG([PERL],[perl],[missing])
352fi
353if test x"$PERL" = xmissing; then
354    AC_MSG_ERROR([Cannot find required perl binary])
355fi
356AX_PROG_PERL_VERSION([5.10.1],,[AC_MSG_ERROR([Perl 5.10.1 or higher required])])
357
358# pod2man
359AC_ARG_VAR([POD2MAN],[path to the Perl "pod2man" command])
360if test "x$ac_cv_env_POD2MAN_set" != "xset"; then
361    AC_PATH_PROG([POD2MAN],[pod2man],[missing])
362fi
363if test x"$POD2MAN" = xmissing; then
364    AC_MSG_ERROR([Cannot find required pod2man binary (perl podlater)])
365fi
366
367# prove for test harness (optional)
368AC_ARG_VAR([PROVE], [path to the Perl Test::Harness "prove" command])
369if test "x$ac_cv_env_PROVE_set" != "xset"; then
370    AC_PATH_PROG([PROVE],[prove],[missing])
371fi
372if test x"$PROVE" = xmissing; then
373    AC_MSG_WARN([Cannot "make check" without the Perl Test::Harness "prove" command])
374fi
375
376# various perl modules for the testsuites (optional)
377HAVE_TESTSUITE_MODULES=0
378AX_PROG_PERL_MODULES(
379    [Test::More JSON::PP Socket6 IO::Socket::INET6 HTTP::Daemon LWP],
380    [HAVE_TESTSUITE_MODULES=1],
381    AC_MSG_WARN([[Cannot "make check" without Perl modules Test::More, JSON::PP, Socket6, IO::Socket::INET6, HTTP::Daemon, and LWP (aka libwww-perl)]])
382)
383AC_SUBST([HAVE_TESTSUITE_MODULES])
384
385# Find ragel
386AC_ARG_VAR([RAGEL],[path to ragel version 6.x])
387if test "x$ac_cv_env_RAGEL_set" != "xset"; then
388    AC_PATH_PROG([RAGEL],[ragel],[missing])
389fi
390if test "x$RAGEL" = xmissing; then
391    AC_MSG_ERROR([Ragel not found])
392else
393    $RAGEL --version|$EGREP 'Ragel State Machine Compiler version 6\.' >/dev/null \
394        || AC_MSG_ERROR([Ragel is not version 6.x])
395fi
396
397# Discover CPUs for testsuite parallelism, allowing user to override via env var.
398# I'd much rather either:
399#  (a) steal the user-supplied -jN argument from make inside of Makefile.am,
400#      but there doesn't seem to be a really good way to do that reliably, especially with
401#      recursive make.  or...
402#  (b) Set -jN based on TEST_CPUS (and rename it BUILD_CPUS), but there doesn't seem
403#      to be any clean way to do that either without disabling direct user override
404#      of that in MAKEFLAGS at make invocation time...
405# As things stand with this commit, user-supplied -jN controls build parallelism
406#  and is not auto-detected, while TEST_CPUS controls testsuite parallelism, and
407#  is auto-detected but can be overridden at configure time.
408AC_ARG_VAR([TEST_CPUS],[number of CPUs to assume when parallelizing the testsuite])
409AC_MSG_CHECKING([number of CPUs available for testing])
410if test "x$ac_cv_env_TEST_CPUS_set" = "xset"; then
411    AC_MSG_RESULT([$TEST_CPUS (user-specified)])
412else
413    # These two methods should work for the *BSDs, MacOS, and Linux
414    TEST_CPUS=$(sysctl -n hw.ncpu 2>/dev/null || getconf _NPROCESSORS_ONLN 2>/dev/null || echo 1)
415    AC_MSG_RESULT([$TEST_CPUS])
416fi
417
418# Decompressor for compressed test data from git submodule
419AC_ARG_VAR([XZ],[path to xz compression utility])
420if test "x$ac_cv_env_XZ_set" != "xset"; then
421    AC_PATH_PROG([XZ], [xz], [missing])
422fi
423AM_CONDITIONAL(HAS_XZ, [test x$XZ != xmissing])
424
425# Allow user to override the port range we use for testing
426AC_ARG_WITH([testport],[AS_HELP_STRING([--with-testport=N],
427    [The testsuite needs ~300 IP port numbers to use, starting at "N", that it can bind to on "127.0.0.1" and "::1".  If the default value of "12345" does not work for you, change it here.])],
428    [],
429    [with_testport=12345]
430)
431
432TESTPORT_START=$with_testport
433AC_SUBST([TESTPORT_START])
434
435AC_CHECK_HEADERS([valgrind/memcheck.h])
436
437# Allow specifying an alternate rundir (default $localstatedir/run) for distros
438#   that prefer e.g. /run to /var/run
439rundir_fail="The --with-rundir= option must specify an absolute pathname if used";
440AC_ARG_WITH([rundir],[AS_HELP_STRING([--with-rundir=LOCALSTATEDIR/run],
441    [Specify alternate ditro-specific rundir, e.g. /run])],[
442  echo "$with_rundir" | $GREP '^/' >/dev/null || AC_MSG_ERROR($rundir_fail)
443  GDNSD_DEFPATH_RUN="${with_rundir}/${PACKAGE_NAME}"
444],[
445  GDNSD_DEFPATH_RUN="${localstatedir}/run/${PACKAGE_NAME}"
446])
447GDNSD_DEFPATH_CONFIG="${sysconfdir}/${PACKAGE_NAME}"
448GDNSD_DEFPATH_STATE="${localstatedir}/lib/${PACKAGE_NAME}"
449GDNSD_DEFPATH_LIB="${libdir}/${PACKAGE_NAME}"
450GDNSD_DEFPATH_LIBEXEC="${libexecdir}/${PACKAGE_NAME}"
451AC_SUBST([GDNSD_DEFPATH_RUN])
452AC_SUBST([GDNSD_DEFPATH_CONFIG])
453AC_SUBST([GDNSD_DEFPATH_STATE])
454AC_SUBST([GDNSD_DEFPATH_LIB])
455AC_SUBST([GDNSD_DEFPATH_LIBEXEC])
456
457# clump up all of the libgdnsd libdeps for re-use in LDADD for
458#   binaries that link libgdnsd on platforms where libtool's
459#   automatic dep resolution is disabled
460LIBGDNSD_LIBS="$MATH_LIB $QSBRLIBS $LIBEV_LIBS $LIBADD_DLOPEN $LIBUNWIND_LIBS"
461AC_SUBST([LIBGDNSD_LIBS])
462
463# BUILD_FEATURES for cmdline output
464B_FEAT="prod"
465if test "x$developer" != xno;    then B_FEAT="dev";             fi
466if test "x$HAS_SENDMMSG" = x1;   then B_FEAT="$B_FEAT mmsg";    fi
467if test "x$USE_INOTIFY" = x1;    then B_FEAT="$B_FEAT inotify"; fi
468if test "x$HAVE_LIBUNWIND" = x1; then B_FEAT="$B_FEAT unwind";  fi
469if test "x$HAVE_GEOIP2" = x1;    then B_FEAT="$B_FEAT geoip2";  fi
470if test "x$GDNSD_B_QSBR" = x1;   then B_FEAT="$B_FEAT urcu";    fi
471AC_DEFINE_UNQUOTED([BUILD_FEATURES], ["$B_FEAT"], [Build Features])
472
473# BUILD_INFO for cmdline output
474B_INFO=non-git
475if test -d ${srcdir}/${GIT_DIR:-.git} -o -f ${srcdir}/.git; then
476    [B_INFO=`cd ${srcdir}; git describe --match 'v[0-9]*' --always --dirty`]
477fi
478AC_DEFINE_UNQUOTED([BUILD_INFO],["$B_INFO"],[Build Info])
479
480# Output generation
481AC_CONFIG_HEADERS([config.h])
482AC_CONFIG_FILES([
483  Makefile
484  t/Makefile
485  t/libtap/Makefile
486  t/libgdmaps/Makefile
487])
488AC_CONFIG_COMMANDS([mkdirs],[$MKDIR_P sysd; $MKDIR_P docs])
489AC_OUTPUT
490
491echo "========================================================================"
492echo "| Build Info: $B_INFO"
493echo "| Build Features: $B_FEAT"
494echo "| CC: $CC"
495echo "| CPPFLAGS: $CPPFLAGS"
496echo "| CFLAGS: $CFLAGS $CFLAGS_PIE"
497echo "| LDFLAGS: $LDFLAGS $LDFLAGS_PIE"
498echo "========================================================================"
499