# vim: set ft=tcl syntax=tcl ts=2 sw=2 expandtab: # Make sure we use /usr as a default prefix on Linux; we can't use $host_ # variables because this needs to go before the inclusion of the system module. if {![catch {exec uname} out] && $out eq {Linux}} { options-defaults { prefix /usr } } autosetup-require-version 0.6.9 # Standard autosetup modules and our own modules use system cc cc-lib mutt-gettext mutt-iconv pkg-config ############################################################################### # Names and versions define PACKAGE "neomutt" define PACKAGE_VERSION "20211029" define BUGS_ADDRESS "neomutt-devel@neomutt.org" # Subdirectories that contain additional Makefile.autosetup files set subdirs {po docs contrib} ############################################################################### ############################################################################### # Add any user options here options { # Curses with-ncurses:path => "Location of ncurses" # Features w/o 3rd party dependencies doc=1 => "Disable building the documentation" full-doc=0 => "Build the full documentation set" docdir:path => "Documentation root" with-lock:=fcntl => "Select fcntl() or flock() to lock files" fmemopen=0 => "Use fmemopen() for temporary in-memory files" inotify=1 => "Disable file monitoring support (Linux only)" locales-fix=0 => "Enable locales fix" pgp=1 => "Disable PGP support" smime=1 => "Disable SMIME support" mixmaster=0 => "Enable Mixmaster support" with-mixmaster:=mixmaster => "Location of the mixmaster executable" homespool=0 => "Enable new mail spooling in the user's HOME" with-homespool:mailbox => "File in the user's HOME where new mail is spooled" with-mailpath:/var/mail => "Directory where spool mailboxes are located" with-domain:domain => "Specify your DNS domain name" # Crypto # OpenSSL or GnuTLS ssl=0 => "Enable TLS support using OpenSSL" with-ssl:path => "Location of OpenSSL" gnutls=0 => "Enable TLS support using GnuTLS" with-gnutls:path => "Location of GnuTLS" # GPGME gpgme=0 => "Enable GPGME support" with-gpgme:path => "Location of GPGME" # GSS (IMAP auth) gss=0 => "Use GSSAPI authentication for IMAP" with-gss:path => "Location of GSSAPI library" # SASL (IMAP and POP auth) sasl=0 => "Use the SASL network security library" with-sasl:path => "Location of the SASL network security library" # AutoCrypt autocrypt=0 => "Enable AutoCrypt support (requires GPGME and SQLite)" # Lua lua=0 => "Enable Lua scripting support" with-lua:path => "Location of Lua" # Notmuch notmuch=0 => "Enable Notmuch support" with-notmuch:path => "Location of Notmuch" # NLS nls=1 => "Disable Native Language Support" with-nls:path => "Location of libintl" # IDN idn=1 => "Disable GNU libidn for internationalized domain names" with-idn:path => "Location of GNU libidn" idn2=0 => "Enable GNU libidn2 for internationalized domain names" with-idn2:path => "Location of GNU libidn2" # PCRE2 pcre2=0 => "Enable PCRE2 regular expressions" with-pcre2:path => "Location of PCRE2" # Header cache bdb=0 => "Use BerkeleyDB for the header cache" with-bdb:path => "Location of BerkeleyDB" with-bdb-version:version => "Version of BerkeleyDB" gdbm=0 => "Use GNU dbm for the header cache" with-gdbm:path => "Location of GNU dbm" kyotocabinet=0 => "Use KyotoCabinet for the header cache" with-kyotocabinet:path => "Location of KyotoCabinet" lmdb=0 => "Use LMDB for the header cache" with-lmdb:path => "Location of LMDB" qdbm=0 => "Use QDBM for the header cache" with-qdbm:path => "Location of QDBM" rocksdb=0 => "Use RocksDB for the header cache" with-rocksdb:path => "Location of RocksDB" tdb=0 => "Use TDB for the header cache" with-tdb:path => "Location of TDB" tokyocabinet=0 => "Use TokyoCabinet for the header cache" with-tokyocabinet:path => "Location of TokyoCabinet" # sqlite sqlite=0 => "Enable SQLite support" with-sqlite:path => "Location of SQLite" # compression lz4=0 => "Enable LZ4 header cache compression support" with-lz4:path => "Location of LZ4" zlib=0 => "Enable zlib support" with-zlib:path => "Location of zlib" zstd=0 => "Enable Zstandard header cache compression support" with-zstd:path => "Location of Zstandard" # System with-sysroot:path => "Target system root" with-tmpdir:=/tmp => "location of the tmp directory" # Misc include-path-in-cflags=1 => "Remove include paths from CFLAGS in the output of neomutt -v" # Testing asan=0 => "Enable the Address Sanitizer" coverage=0 => "Enable Coverage Testing" testing=0 => "Enable Unit Testing" # Configure with pkg-config pkgconf=0 => "Use pkg-config during configure" # Enable all options everything=0 => "Enable all options" # Debug options debug-backtrace=0 => "DEBUG: Enable backtrace support with libunwind" with-backtrace:path => "Location of libunwind" debug-email=0 => "DEBUG: Enable Email dump" debug-graphviz=0 => "DEBUG: Enable Graphviz dump" debug-notify=0 => "DEBUG: Enable Notifications dump" debug-parse-test=0 => "DEBUG: Enable 'neomutt -T' for config testing" debug-window=0 => "DEBUG: Enable windows dump" # Deprecated stuff with-ui:=deprecated => "Deprecated" with-slang:deprecated => "Deprecated" } ############################################################################### ############################################################################### # Deprecated config options foreach dep {with-ui with-slang} { if {[opt-bool -nodefault $dep] != -1} { user-notice "\nThe configure option \"--$dep\" is not used anymore\n" } } ############################################################################### ############################################################################### # All boolean options are converted to want-* definitions here. Further down, # their values is checked with [get-define opt]. This facilitates the handling # of dependencies among options (see "everything"). if {1} { # Keep sorted, please. foreach opt { asan autocrypt bdb coverage debug-backtrace debug-email debug-graphviz debug-notify debug-parse-test debug-window doc everything fmemopen full-doc gdbm gnutls gpgme gss homespool idn idn2 include-path-in-cflags inotify kyotocabinet lmdb locales-fix lua lz4 mixmaster nls notmuch pcre2 pgp pkgconf qdbm rocksdb sasl smime sqlite ssl testing tdb tokyocabinet zlib zstd } { define want-$opt [opt-bool $opt] } # These options support a --with-opt parameter. If that is set, force the # relative --enable-opt to true. This allows "--with-opt=/usr" to be used as # a shortcut for "--opt --with-opt=/usr". foreach opt { bdb gdbm gnutls gpgme gss homespool idn idn2 kyotocabinet lmdb lua lz4 mixmaster nls notmuch pcre2 qdbm rocksdb sasl sqlite ssl tdb tokyocabinet zlib zstd } { if {[opt-val with-$opt] ne {}} { define want-$opt 1 } } # No more usage of [opt-bool] below this point. proc opt-bool {args} { user-error "opt-bool should not be called here" } } ############################################################################### ############################################################################### # Paths define BINDIR [get-define bindir] define MUTTLOCALEDIR [get-define datadir]/locale define PKGDATADIR [get-define datadir]/neomutt define PKGDOCDIR [opt-val docdir [get-define datadir]/doc/neomutt] define SYSCONFDIR [get-define sysconfdir] define TMPDIR [opt-val with-tmpdir /tmp] set libdir_tail [file tail [get-define libdir]] ;# used only locally ############################################################################### ############################################################################### # Helper functions if {1} { # Check for a header file and a function in a library proc check-inc-and-lib {name prefix header fun lib} { cc-with [list -cflags -I$prefix/include -libs -L$prefix/$::libdir_tail] { if {[cc-check-includes $header] && [cc-check-function-in-lib $fun $lib]} { define-append CFLAGS -I$prefix/include define-append LDFLAGS -L$prefix/$::libdir_tail define-feature $name } } have-feature $name } proc check-define {incfile macro} { set code {} if {$incfile ne {}} { append code "#include \"$incfile\"\n" } append code "#ifndef $macro\n#error \"$macro not defined\"\n#endif\n$macro" if {[catch {exec {*}[get-define CC] {*}[get-define CFLAGS] -xc - -E | tail -1 << $code} out]} { error } set out } # Check whether a macro is defined after preprocessing a header file proc has-define {incfile macro} { expr {[catch {check-define $incfile $macro}] == 0} } # Get the value of a macro by preprocessing a header file that defines it proc get-define-value {incfile macro} { if {![catch {check-define $incfile $macro} out]} { return $out } } # Convert a string into a representation suitable for a C char[] proc text2c {s} { set result "\n " set i 0 foreach c [split $s {}] { append result "0x[format %02x [scan $c %c]], " if {[expr {[incr i] % 12 == 0}]} { append result "\n " set i 0 } } append result "0x00\n"; } # Guess what.. proc yesno val { expr {$val ? "yes" : "no"} } # Wrapper around pkg-config, to optionally fail is a pkg is not found, and to # add the compile/link definitions for the module. proc pkgconf {required module args} { if {[pkg-config $module {*}$args]} { # Add only non-duplicate CFLAGS and LDFLAGS foreach which {CFLAGS LDFLAGS} { foreach flag [pkg-config-get $module $which] { if {$flag ni [get-define $which]} { define-append $which $flag } } } # Order of libraries matter, so we cannot skip duplicates define-append LIBS [pkg-config-get $module LIBS] return 1 } elseif {[string is bool $required] && $required} { user-error "$module $args" } else { return 0 } } } ############################################################################### ############################################################################### # C compiler definitions and related tools if {1} { # First off, require c99 if {[cc-check-standards c99] eq {}} { user-error "C99 is required" } define-append CFLAGS_FOR_BUILD -std=c99 define LDFLAGS_FOR_BUILD {} # Check for tools and programs cc-check-tools ar ranlib strip cc-check-progs install if {![cc-path-progs sendmail]} { define SENDMAIL /usr/sbin/sendmail } # GCC-specifc CFLAGS if {![catch {exec {*}[get-define CC] --version} res]} { if {[regexp -nocase gcc $res]} { define-append CFLAGS "-fno-delete-null-pointer-checks" } } # Enable extensions (reverse-engineered from AC_SYSTEM_EXTENSIONS) if {1} { if {[cc-check-includes minix/config.h]} { lappend extensions -D_POSIX_SOURCE=1 lappend extensions -D_POSIX_1_SOURCE=2 lappend extensions -D_MINIX=1 } lappend extensions -D_ALL_SOURCE=1 lappend extensions -D_GNU_SOURCE=1 lappend extensions -D__EXTENSIONS__ define-append CFLAGS_FOR_BUILD {*}$extensions define-append CFLAGS {*}$extensions } cc-with [list -cflags [get-define CFLAGS]] # Endianness cc-check-endian if {[have-feature BIG_ENDIAN]} { define WORDS_BIGENDIAN } # Large file support if {[cc-check-lfs]} { define OFF_T_FMT {"%" PRId64} } else { define OFF_T_FMT {"%" PRId32} } define LOFF_T off_t } ############################################################################### ############################################################################### # signal-related checks # Let's always use volatile for sig_atomic_t cc-check-includes signal.h define SIG_ATOMIC_VOLATILE_T "volatile sig_atomic_t" cc-with {-includes "signal.h unistd.h"} { cc-check-decls sys_siglist } ############################################################################### ############################################################################### # Check for includes and functions that in the code are surrounded by # '#ifdef HAVE_FOO_H' and '#ifdef HAVE_FUNCTION' and for functions that might # be in different libraries if {1} { cc-check-includes \ ioctl.h \ termios.h \ sys/ioctl.h \ syscall.h \ sys/random.h \ sys/syscall.h \ sysexits.h cc-check-functions \ clock_gettime \ fgetc_unlocked \ futimens \ getaddrinfo \ getrandom \ getsid \ iswblank \ mkdtemp \ qsort_s \ strsep \ tcgetwinsize \ utimesnsat \ vasprintf \ wcscasecmp # The following systems have known-bad qsort_r with reversed arguments if {![has-define sys/param.h __FreeBSD_version] && ![has-define {} __APPLE__]} { cc-check-functions qsort_r } cc-check-function-in-lib gethostent nsl cc-check-function-in-lib setsockopt socket cc-check-function-in-lib getaddrinfo_a anl cc-with {-includes time.h} { cc-check-types "struct timespec" } cc-with {-includes sys/stat.h} { cc-check-members "struct stat.st_atim.tv_nsec" } } ############################################################################### ############################################################################### # Various unconditional defines define USE_COMP_MBOX define USE_IMAP define USE_NNTP define USE_POP define USE_SIDEBAR define USE_SMTP define SUN_ATTACHMENT define TEST_CASE_MAXSIZE 1024 ############################################################################### set prefix [opt-val with-sysroot][get-define prefix] ############################################################################### # Everything if {[get-define want-everything]} { foreach opt {bdb gdbm gpgme kyotocabinet lmdb lua lz4 notmuch pgp rocksdb qdbm sasl smime ssl tokyocabinet tdb zlib zstd} { define want-$opt append conf_options "--$opt " } } else { set conf_options "$::argv" } ############################################################################### # Locking switch [opt-val with-lock fcntl] { fcntl { define USE_FCNTL } flock { define USE_FLOCK } default { user-error "Invalid value for --with-lock=[opt-val with-lock], select fcntl\ or flock" } } ############################################################################### # Locales fix if {[get-define want-locales-fix]} {define LOCALES_HACK} ############################################################################### # Documentation if {[get-define want-doc]} { if {![cc-check-progs xsltproc]} { user-error "Unable to find xsltproc" } msg-checking "Checking for DocBook DTDs..." set res [exec xmlcatalog --shell << {public "-//OASIS//DTD DocBook XML V4.2//EN"}] if {[string match {> No entry*} $res]} { msg-result "no" user-error "Install DocBook DTDs or './configure --disable-doc'" } msg-result "yes" define BUILD_DOC } if {[get-define want-full-doc]} {define MAKEDOC_FULL} ############################################################################### # AutoCrypt if {[get-define want-autocrypt]} { define USE_AUTOCRYPT define want-sqlite 1 define want-gpgme 1 } ############################################################################### # GPGME if {[get-define want-gpgme]} { if {[is-defined _FILE_OFFSET_BITS]} { define-append CFLAGS -D_FILE_OFFSET_BITS=[get-define _FILE_OFFSET_BITS] } msg-checking "Checking for GPGME..." if {1} { # Locate gpgme-config set gpgme_prefix [opt-val with-gpgme $prefix] set gpgme_config_guess [file join $gpgme_prefix bin gpgme-config] if {[file-isexec $gpgme_config_guess]} { define GPGME-CONFIG $gpgme_config_guess } else { if {![cc-check-progs gpgme-config]} { user-error "Unable to find gpgme-config" } } set gpgme_config [get-define GPGME-CONFIG] # Version if {[catch {exec-with-stderr $gpgme_config --version} gpgme_version err]} { user-error "Could not derive --version from $gpgme_config" } if {[scan $gpgme_version "%d.%d.%d" gpgme_maj gpgme_min gpgme_patch] != 3} { user-error "Could not parse GPGME version $gpgme_version" } msg-result $gpgme_version if {[get-define want-autocrypt]} { if {$gpgme_maj < 1 || $gpgme_min < 8} { user-error "Found GPGME version $gpgme_version, need 1.8.0 for AutoCrypt" } } else { if {$gpgme_maj < 1 || $gpgme_min < 4} { user-error "Found GPGME version $gpgme_version, need 1.4.0" } } define GPGME_VERSION_NUMBER [format "0x%02x%02x%02x" $gpgme_maj $gpgme_min $gpgme_patch] # RHEL6 doesn't have this function yet cc-check-function-in-lib gpgme_op_export_keys gpgme # CFLAGS if {[catch {exec-with-stderr $gpgme_config --cflags} res err]} { user-error "Could not derive --cflags from $gpgme_config" } define-append CFLAGS $res # LIBS if {[catch {exec-with-stderr $gpgme_config --libs} res err]} { user-error "Could not derive --libs from $gpgme_config" } define-append LIBS $res } define-feature gpgme msg-checking "Checking for gpg-error..." if {1} { # Locate gpg-error-config set gpg_error_config_guess [file join $gpgme_prefix bin gpg-error-config] if {[file-isexec $gpg_error_config_guess]} { define GPG-ERROR-CONFIG $gpg_error_config_guess } else { if {![cc-check-progs gpg-error-config]} { user-error "Unable to find gpg-error-config" } } set gpg_error_config [get-define GPG-ERROR-CONFIG] # Version if {[catch {exec-with-stderr $gpg_error_config --version} gpg_error_version err]} { user-error "Could not derive --version from $gpg_error_config" } # CFLAGS if {[catch {exec-with-stderr $gpg_error_config --cflags} res err]} { user-error "Could not derive --cflags from $gpg_error_config" } define-append CFLAGS $res # LIBS if {[catch {exec-with-stderr $gpg_error_config --libs} res err]} { user-error "Could not derive --libs from $gpg_error_config" } define-append LIBS $res } msg-result $gpg_error_version define CRYPT_BACKEND_GPGME } ############################################################################### # INOTIFY if {[get-define want-inotify]} { if {[cc-check-functions inotify_add_watch inotify_init inotify_rm_watch]} { define USE_INOTIFY cc-check-functions inotify_init1 cc-check-includes sys/inotify.h } } ############################################################################### # PGP if {[get-define want-pgp]} { define-feature PGP define CRYPT_BACKEND_CLASSIC_PGP } ############################################################################### # SMIME if {[get-define want-smime]} { define-feature SMIME define CRYPT_BACKEND_CLASSIC_SMIME } ############################################################################### # SASL if {[get-define want-sasl]} { if {[get-define want-pkgconf]} { pkgconf true libsasl2 # RHEL6 doesn't have this function yet cc-check-functions sasl_client_done define USE_SASL define-feature SASL } else { foreach sasl_lib {sasl2 sasl} { if {[check-inc-and-lib sasl [opt-val with-sasl $prefix] \ sasl/sasl.h sasl_encode64 $sasl_lib]} { # RHEL6 doesn't have this function yet cc-check-functions sasl_client_done define USE_SASL break } } if {![get-define USE_SASL]} { user-error "Unable to find SASL" } } } ############################################################################### # Unit Testing if {[get-define want-testing]} { define ENABLE_UNIT_TESTS lappend subdirs test } ############################################################################### # Lua if {[get-define want-lua]} { if {[get-define want-pkgconf]} { if {![pkgconf false lua] && ![pkgconf false lua-5.4] && ![pkgconf false lua-5.3] && ![pkgconf false lua-5.2]} { user-error "Unable to find LUA" } define USE_LUA } else { set lua_versions { 5.4 5.3 5.2 } ;# Will be checked in order apply {{lua_prefix lua_versions} { foreach ver $lua_versions { lassign [split $ver .] maj min foreach lua_suffix [list /lua${maj}${min} /lua${maj}.${min} /lua-${maj}${min} /lua-${maj}.${min} /lua {}] { msg-checking "Checking for include$lua_suffix/lua.h..." if {[file exists $lua_prefix/include$lua_suffix/lua.h]} { msg-result "yes" set libs [list lua-${maj}.${min} lua${maj}.${min} lua] cc-with [list -libs "-L$lua_prefix/$::libdir_tail"] { if {![cc-check-function-in-lib luaL_openlibs $libs]} { continue } } define-append CFLAGS -I$lua_prefix/include$lua_suffix define-append LDFLAGS -L$lua_prefix/$::libdir_tail define USE_LUA return } msg-result "no" } } user-error "Unable to find Lua" }} [opt-val with-lua $prefix] $lua_versions } } ############################################################################### # Notmuch if {[get-define want-notmuch]} { if {![check-inc-and-lib notmuch [opt-val with-notmuch $prefix] \ notmuch.h notmuch_database_open notmuch]} { user-error "Unable to find Notmuch" } define USE_NOTMUCH msg-checking "Checking for Notmuch API version 3..." if {[cctest -includes {notmuch.h} -libs {-lnotmuch} -link 1 \ -code { notmuch_database_open(NULL, 0, NULL); }]} { define NOTMUCH_API_3 msg-result "yes" } else { msg-result "no" } cc-check-function-in-lib notmuch_database_index_file notmuch cc-check-function-in-lib notmuch_database_open_with_config notmuch } ############################################################################### # Native Language Support (NLS) if {[get-define want-nls]} { if {![check-gettext [opt-val with-nls $prefix]]} { user-error "Unable to find gettext. Consider --disable-nls" } if {![cc-check-progs msgfmt msgmerge xgettext]} { user-error "Unable to find gettext tools (msgfmt, msgmerge, xgettext).\ Consider --disable-nls" } } ############################################################################### # SQLite Support if {[get-define want-sqlite]} { if {![check-inc-and-lib sqlite [opt-val with-sqlite $prefix] \ sqlite3.h sqlite3_open sqlite3]} { user-error "Unable to find SQLite" } define USE_SQLITE } ############################################################################### # zlib Support if {[get-define want-zlib]} { if {![check-inc-and-lib zlib [opt-val with-zlib $prefix] \ zlib.h deflate z]} { user-error "Unable to find zlib" } define USE_ZLIB } ############################################################################### # fmemopen(3) if {[get-define want-fmemopen]} { if {![cc-check-functions fmemopen]} { user-error "Unable to find fmemopen" } if {![cc-check-functions open_memstream]} { user-error "Unable to find open_memstream" } define USE_FMEMOPEN 1 } else { define USE_FMEMOPEN 0 } ############################################################################### # Ncurses define-append CFLAGS -DNCURSES_WIDECHAR set ncurses_prefix [opt-val with-ncurses $prefix] cc-with [list -libs -L$ncurses_prefix/$::libdir_tail] { set tinfo_libs {tinfow tinfo} set ncurses_libs {ncursesw ncurses curses} # Locate the library defining tgetent() # This must be done *before* checking for ncurses functions, see # https://github.com/neomutt/neomutt/issues/1118 foreach tinfo_lib [concat $tinfo_libs $ncurses_libs] { if {[cc-check-function-in-lib tgetent $tinfo_lib]} { break } } # Locate the library defining waddnwstr() foreach ncurses_lib $ncurses_libs { if {[cc-check-function-in-lib waddnwstr $ncurses_lib]} { break } } if {![have-feature waddnwstr] || ![have-feature tgetent]} { user-error "Unable to find ncursesw library" } } # Locate the directory containing ncurses.h # See https://github.com/neomutt/neomutt/pull/679 apply {{ncurses_prefix} { cc-with [list -cflags -I$ncurses_prefix/include] { foreach ncurses_inc {ncursesw/ ncurses/ curses/ {}} { if {[cc-check-includes ${ncurses_inc}ncurses.h] || [cc-check-includes ${ncurses_inc}curses.h]} { return } } user-error "Unable to find ncurses headers" } }} $ncurses_prefix ############################################################################### # Iconv - try to mimic AM_ICONV by preferring an installed libiconv if {![check-iconv $prefix]} { user-error "Unable to find iconv()" } ############################################################################### # Mailpath and homespool if {[get-define want-homespool]} { define MAILPATH [opt-val with-homespool mailbox] define HOMESPOOL 1 } else { define MAILPATH [opt-val with-mailpath /var/mail] } ############################################################################### # Mixmaster if {[get-define want-mixmaster]} { define MIXMASTER [opt-val with-mixmaster mixmaster] } ############################################################################### # Domain if {[opt-val with-domain] ne {}} { define DOMAIN [opt-val with-domain] } ############################################################################### # TLS support if {[get-define want-ssl] && ![get-define want-gnutls]} { # OpenSSL if {[get-define want-pkgconf] && [pkgconf false openssl]} { # cool - we do not make pkg-config mandatory for OpenSSL because BSDs still # ship OpenSSL in the base system. Those aren't available through # pkg-config. } else { set ssl_prefix [opt-val with-ssl $prefix] set ssl_cflags -I$ssl_prefix/include set ssl_ldflags -L$ssl_prefix/$::libdir_tail cc-with [list -libs $ssl_ldflags -cflags $ssl_cflags] { if {![cc-check-includes openssl/bio.h openssl/err.h openssl/ssl.h] || ![cc-check-function-in-lib X509_STORE_CTX_new crypto] || ![cc-check-function-in-lib SSL_new ssl] || ![cc-with {-includes openssl/ssl.h} {cc-check-decls SSL_set_mode}]} { user-error "Unable to find OpenSSL" } define-append CFLAGS $ssl_cflags define-append LDFLAGS $ssl_ldflags } } cc-check-functions RAND_egd cc-check-function-in-lib deflate z define USE_SSL define USE_SSL_OPENSSL if {[cc-with {-includes openssl/ssl.h} { cc-check-decls X509_V_FLAG_PARTIAL_CHAIN}]} { define-feature SSL_PARTIAL_CHAIN } } elseif {[get-define want-gnutls]} { # GnuTLS if {[get-define want-pkgconf]} { pkgconf true gnutls } else { set gnutls_prefix [opt-val with-gnutls $prefix] cc-with [list -cflags -I$gnutls_prefix/include \ -libs -L$gnutls_prefix/$::libdir_tail] { if {![cc-check-function-in-lib gnutls_check_version gnutls]} { user-error "Unable to find GnuTLS" } define-append CFLAGS -I$gnutls_prefix/include define-append LDFLAGS -L$gnutls_prefix/$::libdir_tail } } cc-check-function-in-lib gnutls_priority_set_direct gnutls cc-with {-includes {gnutls/x509.h gnutls/gnutls.h}} { cc-check-decls GNUTLS_VERIFY_DISABLE_TIME_CHECKS cc-check-types gnutls_certificate_credentials_t \ gnutls_certificate_status_t \ gnutls_datum_t \ gnutls_digest_algorithm_t \ gnutls_session_t \ gnutls_transport_ptr_t \ gnutls_x509_crt_t } define USE_SSL define USE_SSL_GNUTLS } ############################################################################### # GNU libidn if {[get-define want-idn] && [get-define want-idn2]} { user-error "Cannot specify both --idn and --idn2" } if {[get-define want-idn]} { proc find-idn1-includes {} { # These are used to figure which header to include if {!([cc-check-includes stringprep.h] || [cc-check-includes idn/stringprep.h]) || !([cc-check-includes idna.h] || [cc-check-includes idn/idna.h])} { user-error "Unable to find GNU libidn" } } if {[get-define want-pkgconf]} { pkgconf true libidn find-idn1-includes } else { set idn_prefix [opt-val with-idn $prefix] cc-with [list -cflags -I$idn_prefix/include \ -libs -L$idn_prefix/$::libdir_tail] { find-idn1-includes define-append CFLAGS -I$idn_prefix/include define-append LDFLAGS -L$idn_prefix/$::libdir_tail } } if {![cc-check-function-in-lib stringprep_check_version idn]} { user-error "Unable to find stringprep_check_version in libidn" } cc-check-functions idna_to_unicode_utf8_from_utf8 idna_to_unicode_8z8z cc-check-functions idna_to_ascii_from_utf8 idna_to_ascii_8z cc-check-functions idna_to_ascii_lz idna_to_ascii_from_locale define-feature libidn } elseif {[get-define want-idn2]} { proc find-idn2-includes {} { # These are used to figure which header to include if {!([cc-check-includes idn2.h] || [cc-check-includes idn/idn2.h])} { user-error "Unable to find GNU libidn2" } } if {[get-define want-pkgconf]} { pkgconf true libidn2 find-idn2-includes } else { set idn_prefix [opt-val with-idn2 $prefix] cc-with [list -cflags -I$idn_prefix/include \ -libs -L$idn_prefix/$::libdir_tail] { find-idn2-includes define-append CFLAGS -I$idn_prefix/include define-append LDFLAGS -L$idn_prefix/$::libdir_tail } } if {![cc-check-function-in-lib idn2_to_ascii_8z idn2] || ![cc-check-function-in-lib idn2_to_unicode_8z8z idn2] || ![cc-check-function-in-lib idn2_check_version idn2]} { user-error "Unable to find required functions in GNU libidn2.\ Please consider using idn1 with './configure --idn'." } define-feature libidn } ############################################################################### # PCRE2 if {[get-define want-pcre2]} { if {[get-define want-pkgconf]} { pkgconf true libpcre2-8 } else { cc-with {-cflags -DPCRE2_CODE_UNIT_WIDTH=8} { if {![check-inc-and-lib pcre2 [opt-val with-pcre2 $prefix] \ pcre2.h pcre2_compile_8 pcre2-8]} { user-error "Unable to find PCRE2" } } } define-feature pcre2 } elseif {[check-inc-and-lib pcre2_unwarranted {} {} pcre2_regcomp {}]} { # See https://bugs.exim.org/show_bug.cgi?id=2707 and # https://github.com/neomutt/neomutt/issues/2865 user-error "Found libpcre2-posix: please reconfigure with --pcre2" } ############################################################################### # Header cache - bdb if {[get-define want-bdb]} { set bdb_versions [opt-val with-bdb-version { 5.3 6.2 4.8 }] ;# Will be checked in order set bdb_prefix [opt-val with-bdb $prefix] foreach ver $bdb_versions { lassign [split $ver .] maj min # This is ugly, but it allows us to not have an inner loop lappend bdb_majors $maj $maj $maj $maj $maj $maj lappend bdb_minors $min $min $min $min $min $min lappend bdb_exploded "" db-$maj-$min db${maj}${min} db$maj.$min db-$maj db$maj } foreach maj $bdb_majors min $bdb_minors ver $bdb_exploded { set ver_inc_dir $bdb_prefix/include/$ver set ver_lib_dir $bdb_prefix/$::libdir_tail/$ver set ver_inc_file $ver_inc_dir/db.h set ver_lib_file db-$maj.$min # File exists? msg-checking "Checking for BerkeleyDB in $ver_inc_dir..." if {![file exists $ver_inc_file]} { msg-result "no" continue } # Version is coherent? set inc_maj [get-define-value $ver_inc_file DB_VERSION_MAJOR] set inc_min [get-define-value $ver_inc_file DB_VERSION_MINOR] if {$inc_maj eq {} || $inc_min eq {} || $inc_maj != $maj || $inc_min != $min} { msg-result "no (expecting $maj.$min, got $inc_maj.$inc_min)" continue } msg-result "yes" # Can link? cc-with [list -libs -L$ver_lib_dir -cflags -I$ver_inc_dir] { if {![check-inc-and-lib bdb {} db.h db_env_create db-$maj.$min]} { msg-result "no" continue } } define-append CFLAGS -I$ver_inc_dir define-append LDFLAGS -L$ver_lib_dir define-append LIBS -ldb-$maj.$min define-append HCACHE_BACKENDS "bdb" define USE_HCACHE break } if {![have-feature bdb]} { user-error "Unable to find BerkeleyDB" } } ############################################################################### # Header cache - QDBM # Note: qdbm must come before gdbm because they share library symbols. if {[get-define want-qdbm]} { if {[get-define want-pkgconf]} { pkgconf true qdbm define-feature qdbm } else { # On Linux, headers are in a dedicated subdirectory set qdbm_prefix [opt-val with-qdbm $prefix] if {[file isdirectory $qdbm_prefix/include/qdbm]} { set qdbm_inc_subdir qdbm/ } else { set qdbm_inc_subdir "" } if {[check-inc-and-lib qdbm [opt-val with-qdbm $qdbm_prefix] \ ${qdbm_inc_subdir}villa.h vlopen qdbm]} { define-append CFLAGS -I$qdbm_prefix/include/$qdbm_inc_subdir } else { user-error "Unable to find QDBM" } } define-append HCACHE_BACKENDS "qdbm" define USE_HCACHE } ############################################################################### # Header Cache - GNU dbm if {[get-define want-gdbm]} { if {![check-inc-and-lib gdbm [opt-val with-gdbm $prefix] \ gdbm.h gdbm_count gdbm]} { user-error "Unable to find GNU dbm" } define-append HCACHE_BACKENDS "gdbm" define USE_HCACHE } ############################################################################### # Header cache - LMDB if {[get-define want-lmdb]} { if {![check-inc-and-lib lmdb [opt-val with-lmdb $prefix] \ lmdb.h mdb_env_create lmdb]} { user-error "Unable to find LMDB" } define-append HCACHE_BACKENDS "lmdb" define USE_HCACHE } ############################################################################### # Header cache - KyotoCabinet if {[get-define want-kyotocabinet]} { if {[get-define want-pkgconf]} { pkgconf true kyotocabinet define-feature kc } else { if {![check-inc-and-lib kc [opt-val with-kyotocabinet $prefix] \ kclangc.h kcdbopen kyotocabinet]} { user-error "Unable to find KyotoCabinet" } } define-append HCACHE_BACKENDS "kyotocabinet" define USE_HCACHE } ############################################################################### # Header cache - RocksDB if {[get-define want-rocksdb]} { if {![check-inc-and-lib rocksdb [opt-val with-rocksdb $prefix] \ rocksdb/c.h rocksdb_open rocksdb]} { user-error "Unable to find RocksDB" } define-append HCACHE_BACKENDS "rocksdb" define USE_HCACHE } ############################################################################### # Header Cache - TDB if {[get-define want-tdb]} { if {[get-define want-pkgconf]} { pkgconf true tdb define-feature tdb } else { cc-with {-includes {sys/stat.h stddef.h} } { if {![check-inc-and-lib tdb [opt-val with-tdb $prefix] \ tdb.h tdb_close tdb]} { user-error "Unable to find TDB" } } } define-append HCACHE_BACKENDS "tdb" define USE_HCACHE } ############################################################################### # Header Cache - TokyoCabinet if {[get-define want-tokyocabinet]} { if {[get-define want-pkgconf]} { pkgconf true tokyocabinet define-feature tc } else { if {![check-inc-and-lib tc [opt-val with-tokyocabinet $prefix] \ tcbdb.h tcbdbopen tokyocabinet]} { user-error "Unable to find TokyoCabinet" } } define-append HCACHE_BACKENDS "tokyocabinet" define USE_HCACHE } ############################################################################### # Header Cache Compression with LZ4 if {[get-define want-lz4]} { if {![check-inc-and-lib lz4 [opt-val with-lz4 $prefix] \ lz4.h LZ4_compress_default lz4]} { user-error "Unable to find LZ4" } define-append LIBS -llz4 define USE_LZ4 define USE_HCACHE_COMPRESSION define-append COMPRESS_BACKENDS "lz4" } ############################################################################### # Header Cache Compression with zlib if {[get-define want-zlib]} { if {![check-inc-and-lib zlib [opt-val with-zlib $prefix] \ zlib.h deflate z]} { user-error "Unable to find zlib" } define-append LIBS -lz define USE_ZLIB define USE_HCACHE_COMPRESSION define-append COMPRESS_BACKENDS "zlib" } ############################################################################### # Header Cache Compression with Zstandard if {[get-define want-zstd]} { if {![check-inc-and-lib zstd [opt-val with-zstd $prefix] \ zstd.h ZSTD_compress zstd]} { user-error "Unable to find Zstandard" } define-append LIBS -lzstd define USE_ZSTD define USE_HCACHE_COMPRESSION define-append COMPRESS_BACKENDS "zstd" } ############################################################################### # GSS if {[get-define want-gss]} { # TODO - Use krb5-config only, which should be enough in any moderately # modern OS. If people report breakage, I'll implement the manual logic # later. set gss_prefix [opt-val with-gss $prefix] set krb5_config_guess [file join $gss_prefix bin krb5-config] if {[file-isexec $krb5_config_guess]} { define KRB5-CONFIG $krb5_config_guess } else { if {![cc-check-progs krb5-config]} { user-error "Unable to find krb5-config" } } msg-checking "Checking for a GSSAPI implementation..." # Cflags set krb5_config [get-define KRB5-CONFIG] if {[catch {exec-with-stderr $krb5_config --cflags gssapi} res err]} { user-error "Could not derive --cflags from $krb5_config" } define-append CFLAGS $res # Libs if {[catch {exec-with-stderr $krb5_config --libs gssapi} res err]} { user-error "Could not derive --libs from $krb5_config" } define-append LDFLAGS $res # Implementation if {[catch {exec-with-stderr $krb5_config --version} res err]} { user-error "Could not derive --version from $krb5_config" } switch -glob $res { "Kerberos 5 *" { set GSSAPI_IMPL "MIT" } "*eimdal*" { set GSSAPI_IMPL "Heimdal" } "Solaris*" { set GSSAPI_IMPL "Solaris" } default { set GSSAPI_IMPL "Unknown" } } msg-result $GSSAPI_IMPL if {$GSSAPI_IMPL in {Heimdal Solaris}} { define HAVE_HEIMDAL } define USE_GSS } ############################################################################### # DEBUG options # Backtrace support with libunwind if {[get-define want-debug-backtrace]} { if {![check-inc-and-lib libunwind [opt-val with-backtrace $prefix] \ libunwind.h unw_backtrace unwind]} { user-error "Unable to find libunwind" } define LIBS "-lunwind-generic [get-define LIBS]" } # Email dump if {[get-define want-debug-email]} { define USE_DEBUG_EMAIL 1 } # Graphviz dump if {[get-define want-debug-graphviz]} { define USE_DEBUG_GRAPHVIZ 1 } # Notifications dump if {[get-define want-debug-notify]} { define USE_DEBUG_NOTIFY 1 } # Parse Test if {[get-define want-debug-parse-test]} { define USE_DEBUG_PARSE_TEST 1 } # Windows dump if {[get-define want-debug-window]} { define USE_DEBUG_WINDOW 1 } ############################################################################### # Address Sanitizer if {[get-define want-asan]} { msg-checking "Checking for ASAN..." if {![cctest -link 1 -cflags -fsanitize=address]} { user-error "Unable to compile with -fsanitize=address" } msg-result "yes" define-append CFLAGS -fsanitize=address -O0 -fno-omit-frame-pointer -fno-common define-append LDFLAGS -fsanitize=address define USE_ASAN } ############################################################################### # Coverage Testing if {[get-define want-coverage]} { define ENABLE_COVERAGE define-append CFLAGS -fprofile-arcs -ftest-coverage define-append LDFLAGS -fprofile-arcs -ftest-coverage } ############################################################################### # Generate conststrings.c set conststrings "\ unsigned char cc_cflags\[\] = {[text2c [expr { [get-define want-include-path-in-cflags] ? [get-define CFLAGS] : [lmap x [get-define CFLAGS] { expr {[string equal -length 2 $x {-I}] ? [continue] : $x} }] }]]};\n\ unsigned char configure_options\[\] = {[text2c $conf_options]};\n" if {[catch {set fd [open conststrings.c w] puts $fd $conststrings close $fd} msg]} { user-error "Cannot write conststrings.c: $msg" } ############################################################################### # Definitions that are going to be substituted in Makefiles and config.h set auto_rep { _* *_TARGETS BINDIR BUILD_DOC CRYPT_* DOMAIN ENABLE_* HAVE_* HOMESPOOL LOCALES_HACK MAILPATH MAKEDOC_FULL MIXMASTER MUTTLOCALEDIR NOTMUCH_API_3 PACKAGE PKGDATADIR PKGDOCDIR SENDMAIL SUN_ATTACHMENT SYSCONFDIR TEST_CASE_MAXSIZE TMPDIR USE_* VPATH WORDS_BIGENDIAN } set bare_rep { ICONV_CONST LOFF_T OFF_T_FMT SIG_ATOMIC_VOLATILE_T } set str_rep { PACKAGE_VERSION } ############################################################################### # Use ccache - don't do it earlier than here if {[get-define CCACHE] ne {none}} { define CC "[get-define CCACHE] [get-define CC]" define CC_FOR_BUILD "[get-define CCACHE] [get-define CC_FOR_BUILD]" } ############################################################################### # Generate targets and Makefile variables for subdirectories set vpath "\$(SRCDIR)" foreach dir $subdirs { append vpath ":\$(SRCDIR)/$dir" define-append ALL_TARGETS all-$dir define-append CLEAN_TARGETS clean-$dir define-append INSTALL_TARGETS install-$dir define-append UNINSTALL_TARGETS uninstall-$dir define-append VPATH } define VPATH $vpath ############################################################################### # Define package timestamp (UTC) based on PACKAGE_VERSION for: # docs/neomuttrc.5, docs/neomutt.1 define PACKAGE_DATE \ [regsub {(....)(..)(..)} [get-define PACKAGE_VERSION] {\1-\2-\3}] ############################################################################### # Generate Makefile and config.h define PWD [pwd] make-template Makefile.autosetup Makefile make-config-header config.h -auto $auto_rep -bare $bare_rep -str $str_rep ############################################################################### # Generate .clang_complete define cflags-one-per-line [string map {" " "\n"} [get-define CFLAGS]] make-template .clang_complete.in ############################################################################### # Print a summary user-notice "Summary of build options: Version: [get-define PACKAGE_VERSION] Host OS: [get-define host_os] Install prefix: [get-define prefix] Compiler: [get-define CC] CFlags: [get-define CFLAGS] LDFlags: [get-define LDFLAGS] Libs: [get-define LIBS] GPGME: [yesno [get-define CRYPT_BACKEND_GPGME]] PGP: [yesno [get-define CRYPT_BACKEND_CLASSIC_PGP]] SMIME: [yesno [get-define CRYPT_BACKEND_CLASSIC_SMIME]] Notmuch: [yesno [get-define USE_NOTMUCH]] Header Cache(s): [get-define HCACHE_BACKENDS {}] Header Compression(s): [get-define COMPRESS_BACKENDS {}] Lua: [yesno [get-define USE_LUA]] "