1# configure.ac
2
3AC_INIT(tmate, 2.4.0)
4
5AM_SILENT_RULES([yes])
6AC_CONFIG_AUX_DIR(etc)
7AM_INIT_AUTOMAKE([foreign subdir-objects])
8
9AC_CANONICAL_HOST
10
11# When CFLAGS isn't set at this stage and gcc is detected by the macro below,
12# autoconf will automatically use CFLAGS="-O2 -g". Prevent that by using an
13# empty default.
14: ${CFLAGS=""}
15
16# Set up the compiler in two different ways and say yes we may want to install.
17AC_PROG_CC
18AM_PROG_CC_C_O
19AC_PROG_CPP
20AC_PROG_EGREP
21AC_PROG_INSTALL
22PKG_PROG_PKG_CONFIG
23
24# Default tmux.conf goes in /etc not ${prefix}/etc.
25test "$sysconfdir" = '${prefix}/etc' && sysconfdir=/etc
26
27# Is this --enable-debug?
28found_debug=yes
29AC_ARG_ENABLE(
30	debug,
31	AC_HELP_STRING(--enable-debug, enable debug build flags),
32	found_debug=$enable_debug
33)
34AM_CONDITIONAL(IS_DEBUG, test "x$found_debug" = xyes)
35
36# Is this --enable-coverage?
37AC_ARG_ENABLE(
38	coverage,
39	AC_HELP_STRING(--enable-coverage, enable coverage build flags),
40	found_coverage=$enable_coverage
41)
42AM_CONDITIONAL(IS_COVERAGE, test "x$found_coverage" = xyes)
43
44# Is this a static build?
45AC_ARG_ENABLE(
46	static,
47	AC_HELP_STRING(--enable-static, create a static build),
48	found_static=$enable_static
49)
50if test "x$found_static" = xyes; then
51        # XXX Static build are only doable with the musl library
52	PKG_CONFIG="pkg-config --static"
53
54	CFLAGS="$CFLAGS -flto"
55	LDFLAGS="$LDFLAGS -flto -static -no-pie"
56
57	PKG_CHECK_MODULES([ZLIB], [zlib], [
58		CPPFLAGS="$ZLIB_CFLAGS $CPPFLAGS"
59		LIBS="$ZLIB_LIBS $LIBS"
60	 ])
61
62	PKG_CHECK_MODULES([LIBCRYPTO], [libcrypto], [
63		CPPFLAGS="$LIBCRYPTO_CFLAGS $CPPFLAGS"
64		LIBS="$LIBCRYPTO_LIBS $LIBS"
65	])
66fi
67
68# Is this gcc?
69AM_CONDITIONAL(IS_GCC, test "x$GCC" = xyes)
70
71# Is this Sun CC?
72AC_EGREP_CPP(
73	yes,
74	[
75		#ifdef __SUNPRO_C
76		yes
77		#endif
78	],
79	found_suncc=yes,
80	found_suncc=no
81)
82AM_CONDITIONAL(IS_SUNCC, test "x$found_suncc" = xyes)
83
84# Is this glibc?
85AC_MSG_CHECKING(for glibc)
86AC_EGREP_CPP(
87	yes,
88	[
89		#include <features.h>
90		#ifdef __GLIBC__
91		yes
92		#endif
93	],
94	found_glibc=yes,
95	found_glibc=no
96)
97AM_CONDITIONAL(IS_GLIBC, test "x$found_glibc" = xyes)
98AC_MSG_RESULT($found_glibc)
99
100# Check for various headers. Alternatives included from compat.h.
101AC_CHECK_HEADERS(
102	[ \
103		bitstring.h \
104		curses.h \
105		dirent.h \
106		execinfo.h \
107		fcntl.h \
108		inttypes.h \
109		libutil.h \
110		ncurses.h \
111		ndir.h \
112		paths.h \
113		pty.h \
114		stdint.h \
115		sys/dir.h \
116		sys/ndir.h \
117		sys/tree.h \
118		term.h \
119		util.h \
120	]
121)
122
123# Look for library needed for flock.
124AC_SEARCH_LIBS(flock, bsd)
125
126# Look for library needed for backtrace
127AC_SEARCH_LIBS(backtrace, execinfo)
128
129# Check for some functions that are replaced or omitted.
130AC_CHECK_FUNCS(
131	[ \
132		backtrace \
133		dirfd \
134		flock \
135		setproctitle \
136		sysconf \
137		cfmakeraw \
138	]
139)
140
141# Look for clock_gettime. Must come before event_init.
142AC_SEARCH_LIBS(clock_gettime, rt)
143
144# Look for libevent.
145PKG_CHECK_MODULES(
146	LIBEVENT,
147	libevent,
148	[
149		CPPFLAGS="$LIBEVENT_CFLAGS $CPPFLAGS"
150		LIBS="$LIBEVENT_LIBS $LIBS"
151		found_libevent=yes
152	],
153	[
154		AC_SEARCH_LIBS(
155			event_init,
156			[event event-1.4 event2],
157			found_libevent=yes,
158			found_libevent=no
159		)
160	]
161)
162if test "x$found_libevent" = xno; then
163	AC_MSG_ERROR("libevent not found")
164fi
165
166# Look for ncurses
167PKG_CHECK_MODULES(
168	LIBNCURSES,
169	ncurses,
170	[
171		CPPFLAGS="$LIBNCURSES_CFLAGS $CPPFLAGS"
172		LIBS="$LIBNCURSES_LIBS $LIBS"
173		found_curses=yes
174	],
175	[
176		AC_SEARCH_LIBS(
177			setupterm,
178			[ncurses curses terminfo],
179			found_curses=yes,
180			found_curses=no
181		)
182	]
183)
184if test "x$found_curses" = xno; then
185	AC_MSG_ERROR("curses not found")
186fi
187
188# Look for utempter.
189AC_CHECK_HEADER(utempter.h, found_utempter=yes, found_utempter=no)
190if test "x$found_utempter" = xyes; then
191	AC_SEARCH_LIBS(
192		utempter_add_record,
193		utempter,
194		found_utempter=yes,
195		found_utempter=no
196	)
197	if test "x$found_utempter" = xyes; then
198		AC_DEFINE(HAVE_UTEMPTER)
199	fi
200fi
201
202PKG_CHECK_MODULES(
203  MSGPACK,
204  msgpack >= 1.1.0,
205  [
206    CPPFLAGS="$MSGPACK_CFLAGS $CPPFLAGS"
207    LIBS="$MSGPACK_LIBS $LIBS"
208    found_msgpack=yes
209  ],
210  found_msgpack=no
211)
212if test "x$found_msgpack" = xno; then
213  AC_MSG_ERROR("msgpack >= 1.1.0 not found")
214fi
215
216PKG_CHECK_MODULES(
217  LIBSSH,
218  libssh >= 0.8.4,
219  [
220    CPPFLAGS="$LIBSSH_CFLAGS $CPPFLAGS"
221    LIBS="$LIBSSH_LIBS $LIBS"
222    found_libssh=yes
223  ],
224  found_libssh=no
225)
226if test "x$found_libssh" = xno; then
227  AC_MSG_ERROR("libssh >= 0.8.4 not found")
228fi
229
230# Check for b64_ntop.
231AC_MSG_CHECKING(for b64_ntop)
232AC_TRY_LINK(
233	[
234		#include <sys/types.h>
235		#include <netinet/in.h>
236		#include <resolv.h>
237	],
238	[b64_ntop(NULL, 0, NULL, 0);],
239	found_b64_ntop=yes,
240	found_b64_ntop=no
241)
242if test "x$found_b64_ntop" = xno; then
243	AC_MSG_RESULT(no)
244
245	AC_MSG_CHECKING(for b64_ntop with -lresolv)
246	LIBS="$LIBS -lresolv"
247	AC_TRY_LINK(
248		[
249			#include <sys/types.h>
250			#include <netinet/in.h>
251			#include <resolv.h>
252		],
253		[b64_ntop(NULL, 0, NULL, 0);],
254		found_b64_ntop=yes,
255		found_b64_ntop=no
256	)
257	if test "x$found_b64_ntop" = xno; then
258		AC_MSG_RESULT(no)
259	fi
260fi
261if test "x$found_b64_ntop" = xyes; then
262	AC_DEFINE(HAVE_B64_NTOP)
263	AC_MSG_RESULT(yes)
264fi
265AM_CONDITIONAL(NO_B64_NTOP, [test "x$found_b64_ntop" = xno])
266
267# Look for networking libraries.
268AC_SEARCH_LIBS(inet_ntoa, nsl)
269AC_SEARCH_LIBS(socket, socket)
270AC_CHECK_LIB(xnet, socket)
271
272# Check for CMSG_DATA. Some platforms require _XOPEN_SOURCE_EXTENDED (for
273# example see xopen_networking(7) on HP-UX).
274XOPEN_DEFINES=
275AC_MSG_CHECKING(for CMSG_DATA)
276AC_EGREP_CPP(
277	yes,
278	[
279		#include <sys/socket.h>
280		#ifdef CMSG_DATA
281		yes
282		#endif
283	],
284	found_cmsg_data=yes,
285	found_cmsg_data=no
286)
287AC_MSG_RESULT($found_cmsg_data)
288if test "x$found_cmsg_data" = xno; then
289	AC_MSG_CHECKING(if CMSG_DATA needs _XOPEN_SOURCE_EXTENDED)
290	AC_EGREP_CPP(
291		yes,
292		[
293			#define _XOPEN_SOURCE 1
294			#define _XOPEN_SOURCE_EXTENDED 1
295			#include <sys/socket.h>
296			#ifdef CMSG_DATA
297			yes
298			#endif
299		],
300		found_cmsg_data=yes,
301		found_cmsg_data=no
302	)
303	AC_MSG_RESULT($found_cmsg_data)
304	if test "x$found_cmsg_data" = xyes; then
305		XOPEN_DEFINES="-D_XOPEN_SOURCE -D_XOPEN_SOURCE_EXTENDED"
306	else
307		AC_MSG_ERROR("CMSG_DATA not found")
308	fi
309fi
310AC_SUBST(XOPEN_DEFINES)
311
312# Look for imsg in libutil. compat/imsg.c is linked by Makefile.am if missing.
313AC_SEARCH_LIBS(imsg_init, util, found_imsg_init=yes, found_imsg_init=no)
314if test "x$found_imsg_init" = xyes; then
315	AC_DEFINE(HAVE_IMSG)
316fi
317AM_CONDITIONAL(NO_IMSG, [test "x$found_imsg_init" = xno])
318
319# Look for forkpty in libutil. compat/forkpty-*.c is linked if not found.
320AC_SEARCH_LIBS(forkpty, util, found_forkpty=yes, found_forkpty=no)
321if test "x$found_forkpty" = xyes; then
322	AC_DEFINE(HAVE_FORKPTY)
323fi
324AM_CONDITIONAL(NO_FORKPTY, [test "x$found_forkpty" = xno])
325
326# Look for closefrom, compat/closefrom.c used if missing.
327AC_CHECK_FUNC(closefrom, found_closefrom=yes, found_closefrom=no)
328if test "x$found_closefrom" = xyes; then
329	AC_DEFINE(HAVE_CLOSEFROM)
330fi
331AM_CONDITIONAL(NO_CLOSEFROM, [test "x$found_closefrom" = xno])
332
333# Look for daemon, compat/daemon.c used if missing.
334AC_CHECK_FUNC(daemon, found_daemon=yes, found_daemon=no)
335if test "x$found_daemon" = xyes; then
336	AC_DEFINE(HAVE_DAEMON)
337fi
338AM_CONDITIONAL(NO_DAEMON, [test "x$found_daemon" = xno])
339
340# Look for setenv, compat/setenv.c used if missing.
341AC_CHECK_FUNC(setenv, found_setenv=yes, found_setenv=no)
342if test "x$found_setenv" = xyes; then
343	AC_DEFINE(HAVE_SETENV)
344fi
345AM_CONDITIONAL(NO_SETENV, [test "x$found_setenv" = xno])
346
347# Look for strlcpy, compat/strlcpy.c used if missing.
348AC_CHECK_FUNC(strlcpy, found_strlcpy=yes, found_strlcpy=no)
349if test "x$found_strlcpy" = xyes; then
350	AC_DEFINE(HAVE_STRLCPY)
351fi
352AM_CONDITIONAL(NO_STRLCPY, [test "x$found_strlcpy" = xno])
353
354# Look for strlcat, compat/strlcat.c used if missing.
355AC_CHECK_FUNC(strlcat, found_strlcat=yes, found_strlcat=no)
356if test "x$found_strlcat" = xyes; then
357	AC_DEFINE(HAVE_STRLCAT)
358fi
359AM_CONDITIONAL(NO_STRLCAT, [test "x$found_strlcat" = xno])
360
361# Look for asprintf, compat/asprintf.c used if missing.
362AC_CHECK_FUNC(asprintf, found_asprintf=yes, found_asprintf=no)
363if test "x$found_asprintf" = xyes; then
364	AC_DEFINE(HAVE_ASPRINTF)
365fi
366AM_CONDITIONAL(NO_ASPRINTF, [test "x$found_asprintf" = xno])
367
368# Look for fgetln, compat/fgetln.c used if missing.
369AC_CHECK_FUNC(fgetln, found_fgetln=yes, found_fgetln=no)
370if test "x$found_fgetln" = xyes; then
371	AC_DEFINE(HAVE_FGETLN)
372fi
373AM_CONDITIONAL(NO_FGETLN, [test "x$found_fgetln" = xno])
374
375# Look for fparseln, compat/fparseln.c used if missing.
376AC_CHECK_FUNC(fparseln, found_fparseln=yes, found_fparseln=no)
377if test "x$found_fparseln" = xyes; then
378	AC_DEFINE(HAVE_FPARSELN)
379fi
380AM_CONDITIONAL(NO_FPARSELN, [test "x$found_fparseln" = xno])
381
382# Look for strcasestr, compat/strcasestr.c used if missing.
383AC_CHECK_FUNC(strcasestr, found_strcasestr=yes, found_strcasestr=no)
384if test "x$found_strcasestr" = xyes; then
385	AC_DEFINE(HAVE_STRCASESTR)
386fi
387AM_CONDITIONAL(NO_STRCASESTR, [test "x$found_strcasestr" = xno])
388
389# Look for strsep, compat/strsep.c used if missing.
390AC_CHECK_FUNC(strsep, found_strsep=yes, found_strsep=no)
391if test "x$found_strsep" = xyes; then
392	AC_DEFINE(HAVE_STRSEP)
393fi
394AM_CONDITIONAL(NO_STRSEP, [test "x$found_strsep" = xno])
395
396# Look for strtonum, compat/strtonum.c used if missing.
397AC_CHECK_FUNC(strtonum, found_strtonum=yes, found_strtonum=no)
398if test "x$found_strtonum" = xyes; then
399	AC_DEFINE(HAVE_STRTONUM)
400fi
401AM_CONDITIONAL(NO_STRTONUM, [test "x$found_strtonum" = xno])
402
403# Look for stravis, compat/{vis,unvis}.c used if missing.
404AC_CHECK_FUNC(stravis, found_stravis=yes, found_stravis=no)
405if test "x$found_stravis" = xyes; then
406	AC_MSG_CHECKING(if strnvis is broken)
407	AC_EGREP_HEADER([strnvis\(char \*, const char \*, size_t, int\)],
408			vis.h,
409			AC_MSG_RESULT(no),
410			[found_stravis=no])
411	if test "x$found_stravis" = xno; then
412		AC_MSG_RESULT(yes)
413	fi
414fi
415if test "x$found_stravis" = xyes; then
416	AC_DEFINE(HAVE_VIS)
417fi
418AM_CONDITIONAL(NO_VIS, [test "x$found_stravis" = xno])
419
420# Look for cfmakeraw, compat/cfmakeraw.c used if missing.
421AC_CHECK_FUNC(cfmakeraw, found_cfmakeraw=yes, found_cfmakeraw=no)
422if test "x$found_cfmakeraw" = xyes; then
423	AC_DEFINE(HAVE_CFMAKERAW)
424fi
425AM_CONDITIONAL(NO_CFMAKERAW, [test "x$found_cfmakeraw" = xno])
426
427# Look for openat, compat/openat.c used if missing.
428AC_CHECK_FUNC(openat, found_openat=yes, found_openat=no)
429if test "x$found_openat" = xyes; then
430	AC_DEFINE(HAVE_OPENAT)
431fi
432AM_CONDITIONAL(NO_OPENAT, [test "x$found_openat" = xno])
433
434# Look for reallocarray, compat/reallocarray.c used if missing.
435AC_CHECK_FUNC(reallocarray, found_reallocarray=yes, found_reallocarray=no)
436if test "x$found_reallocarray" = xyes; then
437	AC_DEFINE(HAVE_REALLOCARRAY)
438fi
439AM_CONDITIONAL(NO_REALLOCARRAY, [test "x$found_reallocarray" = xno])
440
441# Look for getopt. glibc's getopt does not enforce argument order and the ways
442# of making it do so are stupid, so just use our own instead.
443AC_CHECK_FUNC(getopt, found_getopt=yes, found_getopt=no)
444if test "x$found_getopt" != xno; then
445	AC_CHECK_DECLS(
446		[optarg, optind, optreset],
447		,
448		found_getopt=no,
449		[
450			#include <unistd.h>
451		]
452	)
453	if test "x$found_getopt" != xno; then
454		AC_MSG_CHECKING(if system getopt should be avoided)
455		if test "x$found_glibc" = xyes; then
456			found_getopt=no
457			AC_MSG_RESULT(yes)
458		else
459			AC_MSG_RESULT(no)
460			AC_DEFINE(HAVE_GETOPT)
461		fi
462	fi
463fi
464AM_CONDITIONAL(NO_GETOPT, [test "x$found_getopt" = xno])
465
466# Check for BSD-style integer types.
467AC_MSG_CHECKING(for BSD-style unsigned types)
468AC_COMPILE_IFELSE([AC_LANG_SOURCE(
469	[
470		#include <sys/types.h>
471		#ifdef HAVE_STDINT_H
472		#include <stdint.h>
473		#else
474		#include <inttypes.h>
475		#endif
476		int main(void)
477		{ u_int8_t u8; u_int16_t u16; u_int32_t u32; u_int64_t u64; }
478	])],
479	[AC_DEFINE(HAVE_BSD_TYPES) AC_MSG_RESULT(yes)],
480	AC_MSG_RESULT(no)
481)
482
483# Look for a suitable queue.h.
484AC_CHECK_DECL(
485	TAILQ_PREV,
486	found_queue_h=yes,
487	found_queue_h=no,
488	[#include <sys/queue.h>]
489)
490AC_CHECK_DECL(
491	TAILQ_REPLACE,
492	,
493	found_queue_h=no,
494	[#include <sys/queue.h>]
495)
496if test "x$found_queue_h" = xyes; then
497	AC_DEFINE(HAVE_QUEUE_H)
498fi
499
500# Look for __progname.
501AC_MSG_CHECKING(for __progname)
502AC_LINK_IFELSE([AC_LANG_SOURCE(
503	[
504		#include <stdio.h>
505		#include <stdlib.h>
506		extern char *__progname;
507		int main(void) {
508			const char *cp = __progname;
509			printf("%s\n", cp);
510			exit(0);
511		}
512	])],
513	[AC_DEFINE(HAVE___PROGNAME) AC_MSG_RESULT(yes)],
514	AC_MSG_RESULT(no)
515)
516
517# Look for fcntl(F_CLOSEM).
518AC_CHECK_DECL(
519	F_CLOSEM,
520	AC_DEFINE(HAVE_FCNTL_CLOSEM),
521	,
522	[#include <fcntl.h>]
523)
524
525# Look for /proc/$$.
526AC_MSG_CHECKING(for /proc/\$\$)
527if test -d /proc/$$; then
528	AC_DEFINE(HAVE_PROC_PID)
529	AC_MSG_RESULT(yes)
530else
531	AC_MSG_RESULT(no)
532fi
533
534# Man page defaults to mdoc.
535MANFORMAT=mdoc
536AC_SUBST(MANFORMAT)
537
538# Figure out the platform for osdep-*.c and forkpty-*.c.
539AC_MSG_CHECKING(platform)
540case "$host_os" in
541	*aix*)
542		AC_MSG_RESULT(aix)
543		PLATFORM=aix
544		;;
545	*darwin*)
546		AC_MSG_RESULT(darwin)
547		AC_DEFINE(BROKEN_CMSG_FIRSTHDR)
548		PLATFORM=darwin
549		;;
550	*dragonfly*)
551		AC_MSG_RESULT(dragonfly)
552		PLATFORM=dragonfly
553		;;
554	*linux*)
555		AC_MSG_RESULT(linux)
556		PLATFORM=linux
557    AC_DEFINE(IS_LINUX)
558		;;
559	*freebsd*)
560		AC_MSG_RESULT(freebsd)
561		PLATFORM=freebsd
562		;;
563	*netbsd*)
564		AC_MSG_RESULT(netbsd)
565		PLATFORM=netbsd
566		;;
567	*openbsd*)
568		AC_MSG_RESULT(openbsd)
569		PLATFORM=openbsd
570		;;
571	*sunos*)
572		AC_MSG_RESULT(sunos)
573		PLATFORM=sunos
574		;;
575	*solaris*)
576		AC_MSG_RESULT(sunos)
577		PLATFORM=sunos
578		MANFORMAT=man
579		;;
580	*hpux*)
581		AC_MSG_RESULT(hpux)
582		PLATFORM=hpux
583		;;
584	*cygwin*)
585		AC_MSG_RESULT(cygwin)
586		PLATFORM=cygwin
587		;;
588	*)
589		AC_MSG_RESULT(unknown)
590		PLATFORM=unknown
591		;;
592esac
593AC_SUBST(PLATFORM)
594AM_CONDITIONAL(IS_AIX, test "x$PLATFORM" = xaix)
595AM_CONDITIONAL(IS_DARWIN, test "x$PLATFORM" = xdarwin)
596AM_CONDITIONAL(IS_DRAGONFLY, test "x$PLATFORM" = xdragonfly)
597AM_CONDITIONAL(IS_LINUX, test "x$PLATFORM" = xlinux)
598AM_CONDITIONAL(IS_FREEBSD, test "x$PLATFORM" = xfreebsd)
599AM_CONDITIONAL(IS_NETBSD, test "x$PLATFORM" = xnetbsd)
600AM_CONDITIONAL(IS_OPENBSD, test "x$PLATFORM" = xopenbsd)
601AM_CONDITIONAL(IS_SUNOS, test "x$PLATFORM" = xsunos)
602AM_CONDITIONAL(IS_HPUX, test "x$PLATFORM" = xhpux)
603AM_CONDITIONAL(IS_UNKNOWN, test "x$PLATFORM" = xunknown)
604
605# autoconf should create a Makefile.
606AC_OUTPUT(Makefile)
607