1# Generate configure script for libpqxx.  This needs the autoconf archive
2# package installed.  (The configure script itself does not require it though.)
3
4AC_PREREQ(2.69)
5AC_INIT(
6	libpqxx,
7	[m4_esyscmd_s([./tools/extract_version])],
8	[Jeroen T. Vermeulen])
9AC_LANG(C++)
10# Require C++17 at minimum.
11AX_CXX_COMPILE_STDCXX_17([noext])
12AC_CONFIG_SRCDIR([src/connection.cxx])
13AC_CONFIG_AUX_DIR(config)
14AC_CONFIG_MACRO_DIR([config/m4])
15AM_INIT_AUTOMAKE([subdir-objects])
16
17PQXX_ABI=m4_esyscmd_s([./tools/extract_version --abi])
18AC_SUBST(PQXXVERSION, $PACKAGE_VERSION)
19AC_SUBST(PQXX_ABI)
20
21AC_CONFIG_HEADER([include/pqxx/config.h])
22
23# Default prefix for installs.
24AC_PREFIX_DEFAULT(/usr/local)
25
26
27# Read test programme from config-test.
28AC_DEFUN([read_test], [AC_LANG_SOURCE(
29	esyscmd(tools/m4esc.py --input=config-tests/$1))])
30
31
32# Checks for programs.
33AC_PROG_CXX
34AC_PROG_INSTALL
35AC_DISABLE_SHARED
36AC_PROG_LIBTOOL
37AC_PROG_MAKE_SET
38AC_PATH_PROG([MKDIR], [mkdir])
39
40# Documentation.
41AC_ARG_ENABLE(
42	documentation,
43	[AS_HELP_STRING([--enable-documentation], [Generate documentation])],
44	[],
45	[enable_documentation=auto])
46AC_ARG_VAR([DOXYGEN],
47	[Path to doxygen needed to build reference documentation])
48AC_PATH_TOOL([DOXYGEN], [doxygen], [nodoxygen])
49AC_ARG_VAR([HAVE_DOT],
50	[Variable used by doxygen to declare availibility of dot])
51AC_CHECK_TOOL([HAVE_DOT], [dot], [YES], [NO])
52AC_ARG_VAR([XMLTO], [Path to xmlto needed to build tutorial documentation])
53AC_PATH_TOOL([XMLTO], [xmlto], [noxmlto])
54AS_IF([test "$enable_documentation" = "yes" && test "$DOXYGEN" = "nodoxygen" -o "$XMLTO" = "noxmlto"],
55	[AC_MSG_ERROR([could not files tools necessary to build documentation])])
56AM_CONDITIONAL([BUILD_REFERENCE],
57	[test "$enable_documentation" != "no" -a "$DOXYGEN" != "nodoxygen"])
58AM_CONDITIONAL([BUILD_TUTORIAL],
59	[test "$enable_documentation" != "no" -a "$XMLTO" != "xmlto"])
60
61AM_MAINTAINER_MODE
62
63# See if we want verbose compiler warnings.
64AC_MSG_CHECKING([maintainer mode])
65AC_ARG_ENABLE(maintainer-mode)
66AC_MSG_RESULT(${enable_maintainer_mode})
67
68# See if we want "audit," with loads of runtime checking.
69AC_MSG_CHECKING([audit])
70AC_ARG_ENABLE(audit)
71AC_MSG_RESULT(${enable_audit})
72
73# See if we want "suggestions," such as "this class could be final."
74# (The suggestions are often useful, but can also easily be wrong.)
75AC_MSG_CHECKING([suggest])
76AC_ARG_ENABLE(suggest)
77AC_MSG_RESULT(${enable_suggest})
78
79
80AC_ARG_ENABLE(shared)
81AS_IF(
82    [test "${shared}" = "yes" ],
83    [CPPFLAGS="$CPPFLAGS -DPQXX_SHARED"])
84
85
86# Add options to compiler command line, if compiler accepts them.
87add_compiler_opts_if_ok() {
88	for option in $*
89	do
90		ACO_SAVE_CXXFLAGS="$CXXFLAGS"
91		CXXFLAGS="$CXXFLAGS $option"
92		AC_MSG_CHECKING([whether $CXX accepts $option])
93		AC_COMPILE_IFELSE(
94			[AC_LANG_PROGRAM([], [])],
95			has_option=yes,
96			has_option=no)
97		AC_MSG_RESULT($has_option)
98		AS_IF(
99		    [test "$has_option" = "no" ],
100		    [CXXFLAGS="$ACO_SAVE_CXXFLAGS"])
101	done
102}
103
104
105# Add options to compiler command line, unconditionally.
106add_compiler_opts() {
107	CXXFLAGS="$CXXFLAGS $*"
108}
109
110
111# Let's try to get the compiler to be helpful.
112#
113# (Omit options -Weffc++ and -Wabi because they currently yield too many
114# warnings in gcc's standard headers; omit -Wunreachable-code because it isn't
115# always right)
116if test "$GCC" = "yes"
117then
118	# In maintainer mode, enable all the warning options we can.
119	if test "$enable_maintainer_mode" = "yes"
120	then
121		# "Eternal" (FLW) g++ options.  These have been around for
122		# ages, and both g++ and clang++ support them.  Don't bother
123		# checking for support; just add them to the compiler options.
124		add_compiler_opts \
125			-fstrict-enums \
126			-Werror \
127			-Wall \
128			-pedantic \
129			-Wcast-align  \
130			-Wcast-qual  \
131			-Wconversion \
132			-Wctor-dtor-privacy \
133			-Wendif-labels \
134			-Wextra \
135			-Wfloat-equal \
136			-Wformat=2 \
137			-Wformat-security \
138			-Wmissing-include-dirs \
139			-Wno-div-by-zero \
140			-Wnon-virtual-dtor \
141			-Wold-style-cast \
142			-Woverlength-strings \
143			-Woverloaded-virtual \
144			-Wpointer-arith  \
145			-Wredundant-decls \
146			-Wshadow \
147			-Wsign-promo \
148			-Wundef \
149			-Wunused \
150			-Wwrite-strings
151
152		# "Iffy" g++ options.  Some reasonably current g++-like
153		# compilers may not support these.
154		add_compiler_opts_if_ok \
155			-fnothrow-opt \
156			-Wattribute-alias=2 \
157			-Wextra-semi \
158			-Wlogical-op \
159			-Wnoexcept \
160			-Wrestrict \
161			-Wstringop-overflow \
162			-Wzero-as-null-pointer-constant \
163			-Warray-bounds=2 \
164			-Wduplicated-branches \
165			-Wduplicated-cond \
166			-Wsuggest-attribute=noreturn \
167			-Wsuggest-override \
168			-Wtrampolines
169	fi
170
171	# In "audit," enable all runtime checks we can.
172	if test "$enable_audit" = "yes"
173	then
174		add_compiler_opts_if_ok \
175			-fsanitize=address \
176			-fsanitize=leak \
177			-fsanitize=undefined \
178			-fsanitize-address-use-after-scope \
179			-fstack-protector-all
180	fi
181
182	# In "suggest" mode, enable a bunch of code suggestions.
183	if test "$enable_suggest" = "yes"
184	then
185		add_compiler_opts_if_ok \
186			-Wsuggest-attribute=cold \
187			-Wsuggest-attribute=const \
188			-Wsuggest-attribute=malloc \
189			-Wsuggest-attribute=pure \
190			-Wsuggest-final-types \
191			-Wsuggest-final-methods
192	fi
193
194AC_MSG_CHECKING([g++ visibility attribute])
195gcc_visibility=yes
196SAVE_CXXFLAGS="$CXXFLAGS"
197CXXFLAGS="$CXXFLAGS -Werror"
198AC_COMPILE_IFELSE(
199	[read_test(gcc_visibility.cxx)],
200	AC_DEFINE(
201		[PQXX_HAVE_GCC_VISIBILITY],
202		1,
203		[Define if g++ supports visibility attribute.]),
204	gcc_visibility=no)
205AC_MSG_RESULT($gcc_visibility)
206CXXFLAGS="$SAVE_CXXFLAGS"
207if test "$gcc_visibility" = "yes"
208then
209    # Make internal definitions accessible only to the library itself.
210    # Only definitions marked PQXX_LIBEXPORT will be accessible.
211    add_compiler_opts -fvisibility=hidden
212    add_compiler_opts -fvisibility-inlines-hidden
213fi
214
215AC_MSG_CHECKING([g++ pure attribute])
216gcc_pure=yes
217AC_COMPILE_IFELSE(
218	[read_test(gcc_pure.cxx)],
219	AC_DEFINE(
220		[PQXX_HAVE_GCC_PURE],
221		1,
222		[Define if g++ supports pure attribute]),
223	gcc_pure=no)
224AC_MSG_RESULT($gcc_pure)
225
226fi # End of gcc-specific part.
227
228
229# Check for __cxa_demangle.
230AC_MSG_CHECKING([__cxa_demangle])
231cxa_demangle=yes
232AC_COMPILE_IFELSE(
233	[read_test(cxa_demangle.cxx)],
234	AC_DEFINE(
235		[PQXX_HAVE_CXA_DEMANGLE],
236		1,
237		[Define if compiler supports __cxa_demangle]),
238	cxa_demangle=no)
239AC_MSG_RESULT($cxa_demangle)
240
241
242# Check for sufficient Concepts support, introduced with C++20.
243AC_MSG_CHECKING([concepts])
244concepts=yes
245AC_COMPILE_IFELSE(
246	[read_test(concepts.cxx)],
247	AC_DEFINE(
248		[PQXX_HAVE_CONCEPTS],
249		1,
250		[Define if compiler supports Concepts and <ranges> header.]),
251	concepts=no)
252AC_MSG_RESULT($concepts)
253
254
255# Check for strnlen_s.
256AC_MSG_CHECKING([strnlen_s])
257strnlen_s=yes
258AC_COMPILE_IFELSE(
259	[read_test(strnlen_s.cxx)],
260	AC_DEFINE(
261		[PQXX_HAVE_STRNLEN_S],
262		1,
263		[Define if compiler provides strnlen_s]),
264	strnlen_s=no)
265AC_MSG_RESULT($strnlen_s)
266
267
268# Check for strnlen.
269AC_MSG_CHECKING([strnlen])
270strnlen=yes
271AC_COMPILE_IFELSE(
272	[read_test(strnlen.cxx)],
273	AC_DEFINE(
274		[PQXX_HAVE_STRNLEN],
275		1,
276		[Define if compiler provides strnlen]),
277	strnlen=no)
278AC_MSG_RESULT($strnlen)
279
280
281# It's mid-2019, and gcc's charconv supports integers but not yet floats.
282# So for now, we test for int and float conversion... separately.
283#
284# It's worse for older clang versions, which compile the integer conversions
285# but then fail at link time because of a missing symbol "__muloti4" with the
286# "long long" version.  I couldn't resolve that symbol by adding -lm either.
287# So don't just compile these tests; link them as well.
288AC_MSG_CHECKING([for C++17 charconv integer conversion])
289have_charconv_int=yes
290AC_LINK_IFELSE(
291	[read_test(charconv_int.cxx)],
292	AC_DEFINE(
293		[PQXX_HAVE_CHARCONV_INT],
294		1,
295		[Define if <charconv> supports integer conversion.]),
296	have_charconv_int=no)
297AC_MSG_RESULT($have_charconv_int)
298
299AC_MSG_CHECKING([for C++17 charconv floating-point conversion])
300have_charconv_float=yes
301AC_LINK_IFELSE(
302	[read_test(charconv_float.cxx)],
303	AC_DEFINE(
304		[PQXX_HAVE_CHARCONV_FLOAT],
305		1,
306		[Define if <charconv> supports floating-point conversion.]),
307	have_charconv_float=no)
308AC_MSG_RESULT($have_charconv_float)
309
310# As per #262, clang with libcxxrt does not support thread_local on non-POD
311# objects.  Luckily we can live without those, it's just less efficient.
312AC_MSG_CHECKING([for full thread_local support])
313have_thread_local=yes
314AC_LINK_IFELSE(
315	[read_test(thread_local.cxx)],
316	AC_DEFINE(
317		[PQXX_HAVE_THREAD_LOCAL],
318		1,
319		[Define if thread_local is fully supported.]),
320	have_thread_local=no)
321AC_MSG_RESULT($have_thread_local)
322
323# Still getting errors on std::visit() from clang 6, and on one of my systems,
324# on gcc 7 as well.
325AC_MSG_CHECKING([for full std::variant support])
326have_variant=yes
327AC_LINK_IFELSE(
328	[read_test(variant.cxx)],
329	AC_DEFINE(
330		[PQXX_HAVE_VARIANT],
331		1,
332		[Define if std::variant is fully supported.]),
333	have_variant=no)
334AC_MSG_RESULT($have_variant)
335
336# Doing my own test for poll() for now.  The test built into autoconf-archive
337# triggers stupid warnings.
338# TODO: Try newer version of autoconf-archive.
339#AX_HAVE_POLL(
340#        [AX_CONFIG_FEATURE_ENABLE(poll)],
341#        [AX_CONFIG_FEATURE_DISABLE(poll)])
342#AX_CONFIG_FEATURE(
343#	[poll],
344#	[System supports poll().],
345#	[PQXX_HAVE_POLL],
346#	[System supports poll().])
347AC_MSG_CHECKING([for poll()])
348ax_cv_have_poll=yes
349AC_LINK_IFELSE(
350	[read_test(poll.cxx)],
351	AC_DEFINE(
352		[PQXX_HAVE_POLL],
353		1,
354		[Define if poll() is available.]),
355	ax_cv_have_poll=no)
356AC_MSG_RESULT($ax_cv_have_poll)
357
358if test "$ax_cv_have_poll" != "yes"
359then
360# No poll(); we'll fall back to select().
361
362# Some systems keep select() in a separate library which is not linked by
363# default.  See if we need one of those.
364socklibok=no
365AC_SEARCH_LIBS(select, socket nsl ws2_32 wsock32 winsock, [socklibok=yes])
366
367# Microsoft proprietary libraries do not work with code that is generated with
368# autoconf's SEARCH_LIBS macro, so we need to check manually and just use the
369# first socket library available.
370# We only do this if select() is not available by other means, to avoid picking
371# up an unnecessary Windows compatibility library on a non-Windows system.
372for l in ws2_32 wsock32 winsock
373do
374	if test "${socklibok}" != "yes"
375	then
376		AC_CHECK_LIB($l,main,LIBS="$LIBS -l$l";[socklibok=yes])
377	fi
378done
379
380if test "${socklibok}" != "yes"
381then
382	AC_MSG_ERROR([
383Could not figure out how to link a simple sockets-based program.  Please read
384the config.log file for more clues as to why this failed.
385])
386fi
387
388fi # No poll()
389
390
391# Find PostgreSQL includes and libraries
392AC_PATH_PROG([PKG_CONFIG], [pkg-config])
393AC_PATH_PROGS(PG_CONFIG, pg_config)
394
395AC_ARG_WITH(
396    [postgres-include],
397    [AS_HELP_STRING(
398        [--with-postgres-include=DIR],
399        [Use PostgreSQL includes from DIR.  Defaults to querying pg_config or pkg-config, whichever is available.])],
400    AS_IF(
401        [test "x$with_postgres_include" = "xyes"],
402        [with_postgres_include=""]))
403
404if test -n "$with_postgres_include"
405then
406    POSTGRES_INCLUDE="-I$with_postgres_include"
407else
408    if test -x "$PKG_CONFIG" || test -x "$PG_CONFIG"
409    then
410        # We should prefer pkg-config over pg_config, but there seems to be a
411        # problem in pkg-config 1.6.3.  Until that's been resolved (#291), go
412        # with pg_config if we can.
413        if test -x "$PG_CONFIG"
414        then
415            # From pg_config we can either get the C compiler options used to
416            # compile postgres, which isn't quite what we want; or we can get
417            # the headers directory, without the full option.  That's something
418            # we can work with.  The compiler must support the "-I" option for
419            # that, but both scripts assume that anyway.
420            POSTGRES_INCLUDE="-I$($PG_CONFIG --includedir)"
421        else
422            # From pkg-config we can get the compiler options to extend the
423            # include path.  We use that.
424            POSTGRES_INCLUDE=$($PKG_CONFIG libpq --cflags-only-I)
425        fi
426        AC_MSG_NOTICE([finding PostgreSQL headers using $POSTGRES_INCLUDE])
427    else
428        POSTGRES_INCLUDE=""
429
430        # We have nothing to tell us where the libpq headers are.  That's fine
431        # if the compiler can find it, but if not, fail here.
432        AC_CHECK_HEADER(
433	        [libpq-fe.h],
434	        [],
435	[AC_MSG_ERROR([
436Can't find the main PostgreSQL client header, libpq-fe.h.  Make sure that it
437is installed, and either use the --with-postgres-include option or install
438pkg-config.
439])])
440    fi
441fi
442AC_SUBST(POSTGRES_INCLUDE)
443
444# Add the compiler option so we can compile configure tests which rely on the
445# libpq headers.
446CPPFLAGS="$CPPFLAGS $POSTGRES_INCLUDE"
447
448
449AC_ARG_WITH(
450    [postgres-lib],
451    [AS_HELP_STRING(
452        [--with-postgres-lib=DIR],
453        [Use PostgreSQL libraries from DIR.  Defaults to querying pg_config.])],
454    AS_IF(
455        [test "x$with_postgres_lib" = "xyes"],
456        [with_postgres_lib=""]))
457
458# If no --with-postgres-lib was given, and we have pkg-config, use that.
459AS_IF(
460    [test -z "$with_postgres_lib" -a -x "$PKG_CONFIG"],
461    [with_postgres_lib=$($PKG_CONFIG libpq --libs-only-L | sed 's/^-L//')])
462
463# pg_config is deprecated, but for some users it may still provide the only
464# right answer.  For instance, `pkg-config` may not know where `libpq` is
465# installed.
466AS_IF(
467    [test -z "$with_postgres_lib" -a -x "$PG_CONFIG"],
468    [with_postgres_lib=$($PG_CONFIG --libdir)])
469
470AS_IF(
471    [test -n "$with_postgres_lib"],
472    [AC_MSG_NOTICE([using PostgreSQL libraries at $with_postgres_lib])],
473    [AC_MSG_NOTICE([using PostgreSQL libraries in default location])])
474
475AC_SUBST(with_postgres_lib)
476
477
478AC_CHECK_HEADER(
479	[libpq-fe.h],
480	[],
481	[AC_MSG_ERROR([
482Can't find the main PostgreSQL client header, libpq-fe.h.  Are you sure the
483libpq headers are installed correctly, and that we've got the right path?
484])])
485
486
487AC_MSG_CHECKING([for ability to compile source files using libpq])
488AC_COMPILE_IFELSE(
489	[AC_LANG_PROGRAM(
490		[[#include<libpq-fe.h>]],
491		[[PQexec(nullptr,"")]]
492	)],
493	[],
494	[AC_MSG_ERROR([
495Could not compile a call to a basic libpq function.  There must be something
496seriously wrong with the headers that "pg_config --includedir" or "pkg-config
497libpq --cflags" pointed to; the contents of config.log may give you a clue
498about the nature of the failure.
499Source including the libpq header libpq-fe.h can be compiled, but a call to the
500most basic libpq function PQexec() failed to compile successfully.  This is the
501litmus test for a working libpq.
502])])
503AC_MSG_RESULT(yes)
504
505
506if test "x${with_postgres_lib}" = "x"; then
507    with_postgres_libpath=""
508else
509    with_postgres_libpath="-L${with_postgres_lib}"
510fi
511LDFLAGS="$LDFLAGS ${with_postgres_libpath}"
512
513AC_CHECK_LIB(
514	[pq],
515	[PQexec],
516	[],
517	[AC_MSG_ERROR([
518Did not find the PQexec() function in libpq.  This is the litmus test for a
519working libpq installation.
520
521A source file using the PQexec() function did compile without problems, and the
522libpq library is available for linking, but for some reason a call to PQexec()
523failed to link properly to the libpq library.  This may be because the libpq
524library file is damaged, or in some incorrect format, or if your libpq is much
525more recent than libpqxx version $PQXX_ABI, perhaps libpq has undergone a
526radical ABI change.
527
528The last parts of config.log may give you a clue as to what really went wrong,
529but be warned that this is no easy reading.  Look for the last error message
530occurring in the file.
531])],
532	${with_postgres_libpath})
533
534
535# PQencryptPasswordConn was added in postgres 10.
536AC_MSG_CHECKING([for PQencryptPasswordConn])
537have_pqencryptpasswordconn=yes
538AC_COMPILE_IFELSE(
539	[AC_LANG_PROGRAM(
540		[#include<libpq-fe.h>],
541		[
542			extern PGconn *conn;
543			PQencryptPasswordConn(
544				conn, "pwd", "user", "scram-sha-256")
545		]
546	)],
547	AC_DEFINE(
548		[PQXX_HAVE_PQENCRYPTPASSWORDCONN],
549		1,
550		[Define if libpq has PQencryptPasswordConn (since pg 10).]),
551	[have_pqencryptpasswordconn=no])
552AC_MSG_RESULT($have_pqencryptpasswordconn)
553
554
555# Remove redundant occurrances of -lpq
556LIBS=[$(echo "$LIBS" | sed -e 's/-lpq * -lpq\>/-lpq/g')]
557
558
559AC_MSG_CHECKING([that type of libpq's Oid is as expected])
560AC_COMPILE_IFELSE(
561	[AC_LANG_PROGRAM(
562		[
563			#include<libpq-fe.h>
564			#include"${srcdir}/include/pqxx/internal/libpq-forward.hxx"
565			extern void f(pqxx::oid&);
566		],
567		[Oid o;f(o)],
568	)],
569	[],
570	[AC_MSG_ERROR([
571The Oid typedef in libpq has changed.  Please notify the libpqxx authors of the
572change!
573])])
574AC_MSG_RESULT(yes)
575
576
577AC_PROG_MAKE_SET
578
579AC_CONFIG_FILES([
580	Makefile config/Makefile doc/Makefile doc/Doxyfile src/Makefile
581	test/Makefile tools/Makefile include/Makefile include/pqxx/Makefile
582	libpqxx.pc])
583
584
585AC_CONFIG_COMMANDS([configitems], ["${srcdir}/tools/splitconfig" "${srcdir}"])
586
587AC_OUTPUT
588