1# Configure script for htslib, a C library for high-throughput sequencing data.
2#
3#    Copyright (C) 2015-2021 Genome Research Ltd.
4#
5#    Author: John Marshall <jm18@sanger.ac.uk>
6#
7# Permission is hereby granted, free of charge, to any person obtaining a copy
8# of this software and associated documentation files (the "Software"), to deal
9# in the Software without restriction, including without limitation the rights
10# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11# copies of the Software, and to permit persons to whom the Software is
12# furnished to do so, subject to the following conditions:
13#
14# The above copyright notice and this permission notice shall be included in
15# all copies or substantial portions of the Software.
16#
17# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
23# DEALINGS IN THE SOFTWARE.
24
25dnl Process this file with autoconf to produce a configure script
26AC_INIT([HTSlib], m4_esyscmd_s([./version.sh 2>/dev/null]),
27        [samtools-help@lists.sourceforge.net], [], [http://www.htslib.org/])
28AC_PREREQ(2.63)  dnl This version introduced 4-argument AC_CHECK_HEADER
29AC_CONFIG_SRCDIR(hts.c)
30AC_CONFIG_HEADERS(config.h)
31
32m4_include([m4/hts_prog_cc_warnings.m4])
33m4_include([m4/hts_hide_dynamic_syms.m4])
34m4_include([m4/pkg.m4])
35
36dnl Copyright notice to be copied into the generated configure script
37AC_COPYRIGHT([Portions copyright (C) 2020-2021 Genome Research Ltd.
38
39This configure script is free software: you are free to change and
40redistribute it.  There is NO WARRANTY, to the extent permitted by law.])
41
42dnl Notes to be copied (by autoheader) into the generated config.h.in
43AH_TOP([/* If you use configure, this file provides @%:@defines reflecting your
44   configuration choices.  If you have not run configure, suitable
45   conservative defaults will be used.
46
47   Autoheader adds a number of items to this template file that are not
48   used by HTSlib: STDC_HEADERS and most HAVE_*_H header file defines
49   are immaterial, as we assume standard ISO C headers and facilities;
50   the PACKAGE_* defines are unused and are overridden by the more
51   accurate PACKAGE_VERSION as computed by the Makefile.  */])
52
53dnl Variant of AC_MSG_ERROR that ensures subsequent make(1) invocations fail
54dnl until the configuration error is resolved and configure is run again.
55AC_DEFUN([MSG_ERROR],
56  [cat > config.mk <<'EOF'
57ifneq ($(MAKECMDGOALS),distclean)
58$(error Resolve configure error first)
59endif
60EOF
61   AC_MSG_ERROR([$1], [$2])])
62
63AC_PROG_CC
64AC_PROG_RANLIB
65
66dnl Turn on compiler warnings, if possible
67HTS_PROG_CC_WARNINGS
68dnl Flags to treat warnings as errors.  These need to be applied to CFLAGS
69dnl later as they can interfere with some of the tests (notably AC_SEARCH_LIBS)
70HTS_PROG_CC_WERROR(hts_late_cflags)
71
72dnl Avoid chicken-and-egg problem where pkg-config supplies the
73dnl PKG_PROG_PKG_CONFIG macro, but we want to use it to check
74dnl for pkg-config...
75m4_ifdef([PKG_PROG_PKG_CONFIG], [PKG_PROG_PKG_CONFIG], [PKG_CONFIG=""])
76
77need_crypto=no
78pc_requires=
79static_LDFLAGS=$LDFLAGS
80static_LIBS='-lpthread -lz -lm'
81private_LIBS=$LDFLAGS
82
83AC_ARG_ENABLE([bz2],
84  [AS_HELP_STRING([--disable-bz2],
85                  [omit support for BZ2-compressed CRAM files])],
86  [], [enable_bz2=yes])
87
88AC_ARG_ENABLE([gcs],
89  [AS_HELP_STRING([--enable-gcs],
90                  [support Google Cloud Storage URLs])],
91  [], [enable_gcs=check])
92
93AC_SYS_LARGEFILE
94
95AC_ARG_ENABLE([libcurl],
96  [AS_HELP_STRING([--enable-libcurl],
97                  [enable libcurl-based support for http/https/etc URLs])],
98  [], [enable_libcurl=check])
99
100AC_ARG_ENABLE([lzma],
101  [AS_HELP_STRING([--disable-lzma],
102                  [omit support for LZMA-compressed CRAM files])],
103  [], [enable_lzma=yes])
104
105AC_ARG_ENABLE([plugins],
106  [AS_HELP_STRING([--enable-plugins],
107                  [enable separately-compiled plugins for file access])],
108  [], [enable_plugins=no])
109AC_SUBST(enable_plugins)
110
111AC_ARG_WITH([external-htscodecs],
112  [AS_HELP_STRING([--with-external-htscodecs],
113                  [get htscodecs functions from a shared library])],
114  [], [with_external_htscodecs=no])
115AC_SUBST(with_external_htscodecs)
116
117AC_ARG_WITH([libdeflate],
118  [AS_HELP_STRING([--with-libdeflate],
119                  [use libdeflate for faster crc and deflate algorithms])],
120  [], [with_libdeflate=check])
121
122AC_ARG_WITH([plugin-dir],
123  [AS_HELP_STRING([--with-plugin-dir=DIR],
124                  [plugin installation location [LIBEXECDIR/htslib]])],
125  [case $withval in
126     yes|no) MSG_ERROR([no directory specified for --with-plugin-dir]) ;;
127   esac],
128   [with_plugin_dir='$(libexecdir)/htslib'])
129AC_SUBST([plugindir], $with_plugin_dir)
130
131AC_ARG_WITH([plugin-path],
132  [AS_HELP_STRING([--with-plugin-path=PATH],
133                  [default HTS_PATH plugin search path [PLUGINDIR]])],
134  [case $withval in
135     yes) MSG_ERROR([no path specified for --with-plugin-path]) ;;
136     no)  with_plugin_path= ;;
137   esac],
138  [with_plugin_path=$with_plugin_dir])
139AC_SUBST([pluginpath], $with_plugin_path)
140
141AC_ARG_ENABLE([s3],
142  [AS_HELP_STRING([--enable-s3],
143                  [support Amazon AWS S3 URLs])],
144  [], [enable_s3=check])
145
146basic_host=${host_alias:-unknown-`uname -s`}
147AC_MSG_CHECKING([shared library type for $basic_host])
148case $basic_host in
149  *-cygwin* | *-CYGWIN*)
150    host_result="Cygwin DLL"
151    PLATFORM=CYGWIN
152    PLUGIN_EXT=.cygdll
153    ;;
154  *-darwin* | *-Darwin*)
155    host_result="Darwin dylib"
156    PLATFORM=Darwin
157    PLUGIN_EXT=.bundle
158    ;;
159  *-msys* | *-MSYS* | *-mingw* | *-MINGW*)
160    host_result="MSYS dll"
161    PLATFORM=MSYS
162    PLUGIN_EXT=.dll
163    # This also sets __USE_MINGW_ANSI_STDIO which in turn makes PRId64,
164    # %lld and %z printf formats work.  It also enforces the snprintf to
165    # be C99 compliant so it returns the correct values (in kstring.c).
166    CPPFLAGS="$CPPFLAGS -D_XOPEN_SOURCE=600"
167    ;;
168  *)
169    host_result="plain .so"
170    PLATFORM=default
171    PLUGIN_EXT=.so
172    ;;
173esac
174AC_MSG_RESULT([$host_result])
175AC_SUBST([PLATFORM])
176
177dnl Try to get more control over which symbols are exported in the shared
178dnl library.
179HTS_HIDE_DYNAMIC_SYMBOLS
180
181dnl FIXME This pulls in dozens of standard header checks
182AC_FUNC_MMAP
183AC_CHECK_FUNCS([gmtime_r fsync drand48 srand48_deterministic])
184
185# Darwin has a dubious fdatasync() symbol, but no declaration in <unistd.h>
186AC_CHECK_DECL([fdatasync(int)], [AC_CHECK_FUNCS(fdatasync)])
187
188if test $enable_plugins != no; then
189  AC_SEARCH_LIBS([dlsym], [dl], [],
190    [MSG_ERROR([dlsym() not found
191
192Plugin support requires dynamic linking facilities from the operating system.
193Either configure with --disable-plugins or resolve this error to build HTSlib.])])
194  # Check if the compiler understands -rdynamic
195  # TODO Test whether this is required and/or needs tweaking per-platform
196  HTS_TEST_CC_C_LD_FLAG([-rdynamic],[rdynamic_flag])
197  AS_IF([test x"$rdynamic_flag" != "xno"],
198    [LDFLAGS="$LDFLAGS $rdynamic_flag"
199     static_LDFLAGS="$static_LDFLAGS $rdynamic_flag"])
200  case "$ac_cv_search_dlsym" in
201    -l*) static_LIBS="$static_LIBS $ac_cv_search_dlsym" ;;
202  esac
203  AC_DEFINE([ENABLE_PLUGINS], 1, [Define if HTSlib should enable plugins.])
204  AC_SUBST([PLUGIN_EXT])
205  AC_DEFINE_UNQUOTED([PLUGIN_EXT], ["$PLUGIN_EXT"],
206                     [Platform-dependent plugin filename extension.])
207fi
208
209AC_SEARCH_LIBS([log], [m], [],
210  [MSG_ERROR([log() not found
211
212HTSLIB requires a working floating-point math library.
213FAILED.  This error must be resolved in order to build HTSlib successfully.])])
214
215zlib_devel=ok
216dnl Set a trivial non-empty INCLUDES to avoid excess default includes tests
217AC_CHECK_HEADER([zlib.h], [], [zlib_devel=missing], [;])
218AC_CHECK_LIB(z, inflate,  [], [zlib_devel=missing])
219
220if test $zlib_devel != ok; then
221  MSG_ERROR([zlib development files not found
222
223HTSlib uses compression routines from the zlib library <http://zlib.net>.
224Building HTSlib requires zlib development files to be installed on the build
225machine; you may need to ensure a package such as zlib1g-dev (on Debian or
226Ubuntu Linux) or zlib-devel (on RPM-based Linux distributions or Cygwin)
227is installed.
228
229FAILED.  This error must be resolved in order to build HTSlib successfully.])
230fi
231
232dnl connect() etc. fns are in libc on linux, but libsocket on illumos/Solaris
233AC_SEARCH_LIBS([recv], [socket ws2_32], [
234if test "$ac_cv_search_recv" != "none required"
235then
236  static_LIBS="$static_LIBS $ac_cv_search_recv"
237fi],
238  dnl on MinGW-i686, checking recv() linking requires an annotated declaration
239  [AC_MSG_CHECKING([for library containing recv using declaration])
240   LIBS="-lws2_32 $LIBS"
241   AC_LINK_IFELSE(
242     [AC_LANG_PROGRAM([[#include <winsock2.h>]], [[recv(0, 0, 0, 0);]])],
243     [AC_MSG_RESULT([-lws2_32])
244      static_LIBS="$static_LIBS -lws2_32"],
245     [AC_MSG_RESULT([no])
246      MSG_ERROR([unable to find the recv() function])])])
247
248if test "$enable_bz2" != no; then
249  bz2_devel=ok
250  AC_CHECK_HEADER([bzlib.h], [], [bz2_devel=missing], [;])
251  AC_CHECK_LIB([bz2], [BZ2_bzBuffToBuffCompress], [], [bz2_devel=missing])
252  if test $bz2_devel != ok; then
253    MSG_ERROR([libbzip2 development files not found
254
255The CRAM format may use bzip2 compression, which is implemented in HTSlib
256by using compression routines from libbzip2 <http://www.bzip.org/>.
257
258Building HTSlib requires libbzip2 development files to be installed on the
259build machine; you may need to ensure a package such as libbz2-dev (on Debian
260or Ubuntu Linux) or bzip2-devel (on RPM-based Linux distributions or Cygwin)
261is installed.
262
263Either configure with --disable-bz2 (which will make some CRAM files
264produced elsewhere unreadable) or resolve this error to build HTSlib.])
265  fi
266dnl Unfortunately the 'bzip2' package-cfg module is not standard.
267dnl Redhat/Fedora has it; Debian/Ubuntu does not.
268  if test -n "$PKG_CONFIG" && "$PKG_CONFIG" --exists bzip2; then
269     pc_requires="$pc_requires bzip2"
270  else
271     private_LIBS="$private_LIBS -lbz2"
272  fi
273  static_LIBS="$static_LIBS -lbz2"
274fi
275
276if test "$enable_lzma" != no; then
277  lzma_devel=ok
278  AC_CHECK_HEADERS([lzma.h], [], [lzma_devel=header-missing], [;])
279  AC_CHECK_LIB([lzma], [lzma_easy_buffer_encode], [], [lzma_devel=missing])
280  if test $lzma_devel = missing; then
281    MSG_ERROR([liblzma development files not found
282
283The CRAM format may use LZMA2 compression, which is implemented in HTSlib
284by using compression routines from liblzma <http://tukaani.org/xz/>.
285
286Building HTSlib requires liblzma development files to be installed on the
287build machine; you may need to ensure a package such as liblzma-dev (on Debian
288or Ubuntu Linux), xz-devel (on RPM-based Linux distributions or Cygwin), or
289xz (via Homebrew on macOS) is installed; or build XZ Utils from source.
290
291Either configure with --disable-lzma (which will make some CRAM files
292produced elsewhere unreadable) or resolve this error to build HTSlib.])
293  fi
294  pc_requires="$pc_requires liblzma"
295  static_LIBS="$static_LIBS -llzma"
296fi
297
298AS_IF([test "x$with_external_htscodecs" != "xno"],
299  [libhtscodecs=ok
300   AC_CHECK_HEADER([htscodecs/rANS_static4x16.h],[],
301                   [libhtscodecs='missing header'],[;])
302   AC_CHECK_LIB([htscodecs],[rans_compress_bound_4x16],
303                [:],[libhtscodecs='missing library'])
304   AS_IF([test "$libhtscodecs" = "ok"],
305     [AC_DEFINE([HAVE_EXTERNAL_LIBHTSCODECS], 1, [Define if using an external libhtscodecs])
306      LIBS="-lhtscodecs $LIBS"
307      private_LIBS="-lhtscodecs $private_LIBS"
308      static_LIBS="-lhtscodecs $static_LIBS"
309      selected_htscodecs_mk="htscodecs_external.mk"],
310      [MSG_ERROR([libhtscodecs development files not found: $libhtscodecs
311
312You asked to use an external htscodecs library, but do not have the
313required header / library files.  You either need to supply these and
314if necessary set CPPFLAGS and LDFLAGS so the compiler can find them;
315or configure using --without-external-htscodecs to build the required
316functions from the htscodecs submodule.
317])])],
318  [AC_MSG_CHECKING([whether htscodecs files are present])
319   AS_IF([test -e "$srcdir/htscodecs/htscodecs/rANS_static4x16.h"],
320     [AC_MSG_RESULT([yes])
321      selected_htscodecs_mk="htscodecs_bundled.mk"],
322     [AC_MSG_RESULT([no])
323      AS_IF([test -e "$srcdir/.git"],
324        [MSG_ERROR([htscodecs submodule files not present.
325
326HTSlib uses some functions from the htscodecs project, which is normally
327included as a submodule.  Try running:
328
329  git submodule update --init --recursive
330
331in  the top-level htslib directory to update it, and then re-run configure.
332])],
333        [MSG_ERROR([htscodecs submodule files not present.
334
335You have an incomplete distribution.  Please try downloading one of the
336official releases from https://www.htslib.org
337])])])])
338
339AS_IF([test "x$with_libdeflate" != "xno"],
340  [libdeflate=ok
341   AC_CHECK_HEADER([libdeflate.h],[],[libdeflate='missing header'],[;])
342   AC_CHECK_LIB([deflate], [libdeflate_deflate_compress],[:],[libdeflate='missing library'])
343   AS_IF([test "$libdeflate" = "ok"],
344    [AC_DEFINE([HAVE_LIBDEFLATE], 1, [Define if libdeflate is available.])
345     LIBS="-ldeflate $LIBS"
346     private_LIBS="$private_LIBS -ldeflate"
347     static_LIBS="$static_LIBS -ldeflate"],
348    [AS_IF([test "x$with_libdeflate" != "xcheck"],
349       [MSG_ERROR([libdeflate development files not found: $libdeflate
350
351You requested libdeflate, but do not have the required header / library
352files.  The source for libdeflate is available from
353<https://github.com/ebiggers/libdeflate>.  You may have to adjust
354search paths in CPPFLAGS and/or LDFLAGS if the header and library
355are not currently on them.
356
357Either configure with --without-libdeflate or resolve this error to build
358HTSlib.])])])])
359
360libcurl=disabled
361if test "$enable_libcurl" != no; then
362  libcurl_devel=ok
363  AC_CHECK_HEADER([curl/curl.h], [], [libcurl_devel="headers not found"], [;])
364  AC_CHECK_LIB([curl], [curl_easy_pause], [:],
365    [AC_CHECK_LIB([curl], [curl_easy_init],
366       [libcurl_devel="library is too old (7.18+ required)"],
367       [libcurl_devel="library not found"])])
368
369  if test "$libcurl_devel" = ok; then
370    AC_DEFINE([HAVE_LIBCURL], 1, [Define if libcurl file access is enabled.])
371    libcurl=enabled
372  elif test "$enable_libcurl" = check; then
373    AC_MSG_WARN([libcurl not enabled: $libcurl_devel])
374  else
375    MSG_ERROR([libcurl $libcurl_devel
376
377Support for HTTPS and other SSL-based URLs requires routines from the libcurl
378library <http://curl.se/libcurl/>.  Building HTSlib with libcurl enabled
379requires libcurl development files to be installed on the build machine; you
380may need to ensure a package such as libcurl4-{gnutls,nss,openssl}-dev (on
381Debian or Ubuntu Linux) or libcurl-devel (on RPM-based Linux distributions
382or Cygwin) is installed.
383
384Either configure with --disable-libcurl or resolve this error to build HTSlib.])
385  fi
386
387dnl -lcurl is only needed for static linking if hfile_libcurl is not a plugin
388  if test "$libcurl" = enabled ; then
389    if test "$enable_plugins" != yes ; then
390      static_LIBS="$static_LIBS -lcurl"
391    fi
392  fi
393fi
394AC_SUBST([libcurl])
395
396gcs=disabled
397if test "$enable_gcs" != no; then
398  if test $libcurl = enabled; then
399    AC_DEFINE([ENABLE_GCS], 1, [Define if HTSlib should enable GCS support.])
400    gcs=enabled
401  else
402    case "$enable_gcs" in
403      check) AC_MSG_WARN([GCS support not enabled: requires libcurl support]) ;;
404      *) MSG_ERROR([GCS support not enabled
405
406Support for Google Cloud Storage URLs requires libcurl support to be enabled
407in HTSlib.  Configure with --enable-libcurl in order to use GCS URLs.])
408      ;;
409    esac
410  fi
411fi
412AC_SUBST([gcs])
413
414s3=disabled
415if test "$enable_s3" != no; then
416  if test $libcurl = enabled; then
417    s3=enabled
418    need_crypto="$enable_s3"
419  else
420    case "$enable_s3" in
421      check) AC_MSG_WARN([S3 support not enabled: requires libcurl support]) ;;
422      *) MSG_ERROR([S3 support not enabled
423
424Support for Amazon AWS S3 URLs requires libcurl support to be enabled
425in HTSlib.  Configure with --enable-libcurl in order to use S3 URLs.])
426      ;;
427    esac
428  fi
429fi
430
431CRYPTO_LIBS=
432if test $need_crypto != no; then
433  AC_CHECK_FUNC([CCHmac],
434    [AC_DEFINE([HAVE_COMMONCRYPTO], 1,
435               [Define if you have the Common Crypto library.])],
436    [save_LIBS=$LIBS
437     AC_SEARCH_LIBS([HMAC], [crypto],
438       [AC_DEFINE([HAVE_HMAC], 1, [Define if you have libcrypto-style HMAC().])
439        case "$ac_cv_search_HMAC" in
440          -l*) CRYPTO_LIBS=$ac_cv_search_HMAC ;;
441        esac],
442     [case "$need_crypto" in
443     check) AC_MSG_WARN([S3 support not enabled: requires SSL development files])
444         s3=disabled ;;
445     *) MSG_ERROR([SSL development files not found
446
447Support for AWS S3 URLs requires routines from an SSL library.  Building
448HTSlib with libcurl enabled requires SSL development files to be installed
449on the build machine; you may need to ensure a package such as libgnutls-dev,
450libnss3-dev, or libssl-dev (on Debian or Ubuntu Linux, corresponding to the
451libcurl4-*-dev package installed), or openssl-devel (on RPM-based Linux
452distributions or Cygwin) is installed.
453
454Either configure with --disable-s3 or resolve this error to build HTSlib.]) ;;
455       esac])
456     LIBS=$save_LIBS])
457dnl Only need to add to static_LIBS if not building as a plugin
458  if test "$enable_plugins" != yes ; then
459     static_LIBS="$static_LIBS $CRYPTO_LIBS"
460  fi
461fi
462
463dnl Look for regcomp in various libraries (needed on windows/mingw).
464AC_SEARCH_LIBS(regcomp, regex, [libregex=needed], [])
465
466dnl Look for PTHREAD_MUTEX_RECURSIVE.
467dnl This is normally in pthread.h except on some broken glibc implementations.
468AC_CHECK_DECL(PTHREAD_MUTEX_RECURSIVE, [], [AC_DEFINE([_XOPEN_SOURCE],[600], [Needed for PTHREAD_MUTEX_RECURSIVE])], [[#include <pthread.h>]])
469
470if test "$s3" = enabled ; then
471   AC_DEFINE([ENABLE_S3], 1, [Define if HTSlib should enable S3 support.])
472fi
473
474dnl Apply value from HTS_PROG_CC_WERROR (if set)
475AS_IF([test "x$hts_late_cflags" != x],[CFLAGS="$CFLAGS $hts_late_cflags"])
476
477AC_SUBST([s3])
478AC_SUBST([CRYPTO_LIBS])
479
480AC_SUBST([pc_requires])
481AC_SUBST([private_LIBS])
482AC_SUBST([static_LDFLAGS])
483AC_SUBST([static_LIBS])
484
485AC_CONFIG_FILES([config.mk htslib.pc.tmp:htslib.pc.in])
486AC_CONFIG_LINKS([htscodecs.mk:$selected_htscodecs_mk])
487
488if test "$srcdir" != .; then
489  # Set up for a separate build directory. As HTSlib uses a non-recursive
490  # makefile, we need to create additional build subdirectories explicitly.
491  AC_CONFIG_LINKS([Makefile:Makefile htslib.mk:htslib.mk])
492  AC_CONFIG_FILES([htslib_vars.mk:builddir_vars.mk.in])
493  AC_CONFIG_COMMANDS([mkdir],
494    [AS_MKDIR_P([cram])
495     AS_MKDIR_P([htscodecs/htscodecs])
496     AS_MKDIR_P([htscodecs/tests])
497     AS_MKDIR_P([test/fuzz])
498     AS_MKDIR_P([test/longrefs])
499     AS_MKDIR_P([test/tabix])])
500fi
501
502# @HTSDIRslash_if_relsrcdir@ will be empty when $srcdir is absolute
503case "$srcdir" in
504  /*) HTSDIRslash_if_relsrcdir= ;;
505  *)  HTSDIRslash_if_relsrcdir='$(HTSDIR)/' ;;
506esac
507AC_SUBST([HTSDIRslash_if_relsrcdir])
508
509AC_OUTPUT
510