# configure.ac - process this file with autoconf to produce a configure script
# Copyright (C) 2015-2021 Alex Vong <alexvong1995 AT protonmail DOT com>
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software Foundation,
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.

# prelude
AC_PREREQ([2.69])
AC_INIT([Mlucas],
        [20.1.1],
        [ewmayer AT aol DOT com],
        [mlucas],
        [https://www.mersenneforum.org/mayer/README.html])
AC_CONFIG_SRCDIR([upstream/src/Mlucas.c])
AC_CONFIG_AUX_DIR([build-aux])
AC_CONFIG_MACRO_DIR([m4])
AM_INIT_AUTOMAKE([-Wall -Werror foreign subdir-objects serial-tests])

# find tools
AC_PROG_SED
AC_CHECK_PROGS([CHMOD], [chmod])
AS_IF([test x"$CHMOD" != 'xchmod'], [AC_MSG_ERROR([cannot find program chmod])])
AC_CHECK_PROGS([CP], [cp])
AS_IF([test x"$CP" != 'xcp'], [AC_MSG_ERROR([cannot find program cp])])

# find c compiler
: "${CC:="$PTHREAD_CC"}"
: "${CFLAGS:=""}"
AC_PROG_CC

# detect thread support
AC_ARG_ENABLE([threads],
              [AS_HELP_STRING([--disable-threads],
                              [disable thread support detection])])
AS_IF([test "x$enable_threads" != 'xno'],
      [AX_PTHREAD([CC="$PTHREAD_CC"
                   AC_DEFINE([USE_THREADS], [1])])])
AM_CONDITIONAL([USE_THREADS], [test "x$ax_pthread_ok" = 'xyes'])

# check for libraries
AC_CHECK_HEADERS([math.h], [], AC_MSG_ERROR([cannot find header math.h]))
AC_SEARCH_LIBS([cos], [m], [], AC_MSG_ERROR([cannot link with library libm]))
AC_CHECK_HEADERS([gmp.h], [], AC_MSG_ERROR([cannot find header gmp.h]))
AC_SEARCH_LIBS([__gmpz_init],
               [gmp],
               [],
               AC_MSG_ERROR([cannot link with library libgmp]))

# enable Large File Support (useful on 32-bit systems)
AC_SYS_LARGEFILE

# allow user to set MLUCAS_DEFAULT_PATH to "$HOME/.mlucas.d/"
AC_ARG_ENABLE([mlucas-default-path],
              [AS_HELP_STRING([--enable-mlucas-default-path],
                              [set MLUCAS_DEFAULT_PATH (unset by default) to
                               "$HOME/.mlucas.d/"])])
AS_IF([test "x$enable_mlucas_default_path" = 'xyes'],
      [AC_DEFINE([MLUCAS_DEFAULT_PATH], ["$HOME/.mlucas.d/"])])

# detect compiler features
AC_ARG_ENABLE([compiler-features],
              [AS_HELP_STRING([[--enable-compiler-features[=feature[,...]]]],
                              [list of compiler features to be detected
                               (default to optimization,debugging,hardening
                                if none is given)])])
AC_ARG_ENABLE([compiler-features],
              [AS_HELP_STRING([--disable-compiler-features],
                              [disable compiler features detection])])

# check for optimization features

# FIXME: workaround the following self-test error by disabling
# link-time optimization for now despite the performance penalty
# --8<---------------cut here---------------start------------->8---
# ERROR: at line 457 of file upstream/src/mi64.c
# Assertion failed: Nonzero carryout of nonoverlapping vector add!
# --8<---------------cut here---------------end--------------->8---
AS_IF([expr ",$enable_compiler_features," : '.*,optimization,' \
            '|' "x$enable_compiler_features" : 'xyes$' \
            '|' "x$enable_compiler_features" : 'x$' >/dev/null],
      [AX_APPEND_COMPILE_FLAGS([m4_normalize([-pipe
                                              -O2 -O3 -Ofast
                                              -ftree-vectorize
                                              -floop-nest-optimize
                                              -fomit-frame-pointer])],
                               [OPTCFLAGS])])

# check for debugging features
AS_IF([expr ",$enable_compiler_features," : '.*,debugging,' \
            '|' "x$enable_compiler_features" : 'xyes$' \
            '|' "x$enable_compiler_features" : 'x$' >/dev/null],
      [AX_APPEND_COMPILE_FLAGS([-g -g3], [DEBUGCFLAGS])])

# check for hardening features
AS_IF([expr ",$enable_compiler_features," : '.*,hardening,' \
            '|' "x$enable_compiler_features" : 'xyes$' \
            '|' "x$enable_compiler_features" : 'x$' >/dev/null],
      [AC_DEFINE([_FORTIFY_SOURCE], [2])
       AX_APPEND_COMPILE_FLAGS([m4_normalize([-fstack-protector-strong
                                              -fstack-clash-protection
                                              -fwrapv])],
                               [HARDENCFLAGS])
       AX_APPEND_LINK_FLAGS([-Wl,-z,relro -Wl,-z,now -Wl,--as-needed],
                            [HARDENLDFLAGS])])

# allow user to specify build variants
AC_ARG_ENABLE([builds],
              [AS_HELP_STRING([[--enable-builds[=build[,...]]]],
                              [list of build variants to be enabled
                               (default to generic-c,sse2 for x86 host,
                                generic-c,sse2,avx,avx2,avx512 for x86_64 host,
                                generic-c,arm-v8-simd for aarch64 host
                                if none is given)])])

# detect host
AC_CANONICAL_HOST
AS_CASE(["$host_cpu"],
        [i?86],
        [AC_DEFINE([CPU_IS_X86], [1])
         AX_APPEND_COMPILE_FLAGS([-m32], [ARCHCFLAGS])],
        [x86_64],
        [AX_APPEND_COMPILE_FLAGS([-m64], [ARCHCFLAGS])],
        [aarch64],
        [AX_APPEND_COMPILE_FLAGS([-march=armv8-a], [ARCHCFLAGS])])

# build variants
AM_CONDITIONAL([BUILD_GENERIC_C],
               [expr ",$enable_builds," : '.*,generic-c,' \
                     '|' "x$enable_builds" : 'xyes$' \
                     '|' "x$enable_builds" : 'x$' >/dev/null])
AM_CONDITIONAL([BUILD_SSE2],
               [expr ",$enable_builds," : '.*,sse2,' \
                      '|' '(' '(' "x$host_cpu" : 'xi.86$' \
                                   '|' "x$host_cpu" : 'xx86_64$' ')' \
                               '&' '(' "x$enable_builds" : 'xyes$' \
                                       '|' "x$enable_builds" : 'x$' ')' ')' \
                      >/dev/null])
AM_CONDITIONAL([BUILD_AVX],
               [expr ",$enable_builds," : '.*,avx,' \
                      '|' '(' "x$host_cpu" : 'xx86_64$' \
                               '&' '(' "x$enable_builds" : 'xyes$' \
                                       '|' "x$enable_builds" : 'x$' ')' ')' \
                      >/dev/null])
AM_CONDITIONAL([BUILD_AVX2],
               [expr ",$enable_builds," : '.*,avx2,' \
                      '|' '(' "x$host_cpu" : 'xx86_64$' \
                               '&' '(' "x$enable_builds" : 'xyes$' \
                                       '|' "x$enable_builds" : 'x$' ')' ')' \
                      >/dev/null])
AM_CONDITIONAL([BUILD_AVX512],
               [expr ",$enable_builds," : '.*,avx512,' \
                      '|' '(' "x$host_cpu" : 'xx86_64$' \
                               '&' '(' "x$enable_builds" : 'xyes$' \
                                       '|' "x$enable_builds" : 'x$' ')' ')' \
                      >/dev/null])
AM_CONDITIONAL([BUILD_ARM_V8_SIMD],
               [expr ",$enable_builds," : '.*,arm-v8-simd,' \
                      '|' '(' "x$host_cpu" : 'xaarch64$' \
                               '&' '(' "x$enable_builds" : 'xyes$' \
                                       '|' "x$enable_builds" : 'x$' ')' ')' \
                      >/dev/null])

# flags used by Makefile.am
AC_SUBST([EXTRACFLAGS],
         ["$PTHREAD_CFLAGS $OPTCFLAGS $DEBUGCFLAGS $HARDENCFLAGS $ARCHCFLAGS"])
AC_SUBST([EXTRALDFLAGS], ["$HARDENLDFLAGS"])
AC_SUBST([EXTRALIBS], ["$PTHREAD_LIBS"])

# deprecated options
AC_ARG_ENABLE([verbose-compiler],
              [AS_HELP_STRING([--enable-verbose-compiler],
                              [ignored and will be removed in the future])])
AS_CASE(["$enable_verbose_compiler"],
        [?*],
        [AC_MSG_WARN([m4_normalize([--enable-verbose-compiler is ignored and
                                    will be removed in the future])])])
AC_ARG_ENABLE([instruction],
              [AS_HELP_STRING([--enable-instruction],
                              [ignored and will be removed in the future])])
AS_CASE(["$enable_instruction"],
        [?*],
        [AC_MSG_WARN([m4_normalize([--enable-instruction is ignored and will be
                                    removed in the future])])])
AC_ARG_ENABLE([MLUCAS-DEFAULT-PATH],
              [AS_HELP_STRING([--enable-MLUCAS-DEFAULT-PATH],
                              [ignored and will be removed in the future])])
AS_CASE(["$enable_MLUCAS_DEFAULT_PATH"],
        [?*],
        [AC_MSG_WARN([m4_normalize([--enable-MLUCAS-DEFAULT-PATH is ignored and
                                    will be removed in the future])])])

# postlude
AC_CONFIG_FILES([Makefile])
AC_OUTPUT
