# Source of configuration for Tkrzw

#================================================================
# Generic Settings
#================================================================

# Package name
AC_INIT([tkrzw], [1.0.32])

# Package information
MYLIBVER=1
MYLIBREV=75
MYLIBFMT=0

# Targets
MYHEADERFILES="tkrzw_lib_common.h tkrzw_str_util.h tkrzw_hash_util.h tkrzw_time_util.h tkrzw_thread_util.h tkrzw_logger.h tkrzw_compress.h tkrzw_containers.h tkrzw_key_comparators.h tkrzw_file.h tkrzw_file_util.h tkrzw_file_std.h tkrzw_file_mmap.h tkrzw_file_pos.h tkrzw_file_poly.h tkrzw_message_queue.h tkrzw_dbm.h tkrzw_dbm_ulog.h tkrzw_dbm_common_impl.h tkrzw_dbm_hash_impl.h tkrzw_dbm_hash.h tkrzw_dbm_tree_impl.h tkrzw_dbm_tree.h tkrzw_dbm_skip_impl.h tkrzw_dbm_skip.h tkrzw_dbm_tiny.h tkrzw_dbm_baby.h tkrzw_dbm_cache.h tkrzw_dbm_std.h tkrzw_dbm_poly.h tkrzw_dbm_shard.h tkrzw_dbm_async.h tkrzw_index.h tkrzw_cmd_util.h tkrzw_langc.h"
MYLIBRARYFILES="libtkrzw.a"
MYLIBOBJFILES="tkrzw_lib_common.o tkrzw_str_util.o tkrzw_hash_util.o tkrzw_time_util.o tkrzw_compress.o tkrzw_file_util.o tkrzw_file_std.o tkrzw_file_mmap.o tkrzw_file_pos.o tkrzw_file_poly.o tkrzw_message_queue.o tkrzw_dbm.o tkrzw_dbm_ulog.o tkrzw_dbm_common_impl.o tkrzw_dbm_hash_impl.o tkrzw_dbm_hash.o tkrzw_dbm_tree_impl.o tkrzw_dbm_tree.o tkrzw_dbm_skip_impl.o tkrzw_dbm_skip.o tkrzw_dbm_tiny.o tkrzw_dbm_baby.o tkrzw_dbm_cache.o tkrzw_dbm_std.o tkrzw_dbm_poly.o tkrzw_dbm_shard.o tkrzw_dbm_async.o tkrzw_cmd_util.o tkrzw_langc.o"
MYCOMMANDFILES="tkrzw_build_util tkrzw_str_perf tkrzw_file_perf tkrzw_dbm_util tkrzw_dbm_perf tkrzw_dbm_tran tkrzw_ulog_util tkrzw_langc_check"
MYTESTFILES="tkrzw_sys_config_test tkrzw_lib_common_test tkrzw_str_util_test tkrzw_hash_util_test tkrzw_time_util_test tkrzw_thread_util_test tkrzw_logger_test tkrzw_compress_test tkrzw_containers_test tkrzw_key_comparators_test tkrzw_file_util_test tkrzw_file_std_test tkrzw_file_mmap_test tkrzw_file_pos_test tkrzw_file_poly_test tkrzw_message_queue_test tkrzw_dbm_common_impl_test tkrzw_dbm_ulog_test tkrzw_dbm_hash_impl_test tkrzw_dbm_tree_impl_test tkrzw_dbm_tree_test tkrzw_dbm_hash_test tkrzw_dbm_skip_impl_test tkrzw_dbm_skip_test tkrzw_dbm_tiny_test tkrzw_dbm_baby_test tkrzw_dbm_cache_test tkrzw_dbm_std_test tkrzw_dbm_poly_test tkrzw_dbm_shard_test tkrzw_dbm_async_test tkrzw_index_test tkrzw_cmd_util_test tkrzw_langc_test"
MYPCFILES="tkrzw.pc"

# Building flags
MYCFLAGS="-std=c11 -pthread -fPIC -fsigned-char"
MYCXXFLAGS="-std=c++17 -pthread -fPIC -fsigned-char"
MYCPPFLAGS="-I. -I\$(INCLUDEDIR)"
MYCPPFLAGS="$MYCPPFLAGS -DNDEBUG -D_GNU_SOURCE=1 -D_ISOC99_SOURCE=1"
if uname | egrep "(FreeBSD|SunOS)" >config.tmp
then
  MYCPPFLAGS="$MYCPPFLAGS -U_POSIX_C_SOURCE"
else
  MYCPPFLAGS="$MYCPPFLAGS -D_POSIX_C_SOURCE=999999L"
fi
MYCPPFLAGS="$MYCPPFLAGS -D_FILE_OFFSET_BITS=64 -D_REENTRANT -D__EXTENSIONS__"
MYLDSOFLAGS="-shared -Wl,-soname,libtkrzw.so.\$(LIBVER)"
MYLDFLAGS="-L. -L\$(LIBDIR)"
MYCMDLDFLAGS="-L. -L\$(LIBDIR)"
MYCMDLIBS="-ltkrzw"
MYTESTLIBS="-lgtest -lgmock -lpthread"
MYLDLIBPATH=""
MYLDLIBPATHENV="LD_LIBRARY_PATH"
MYFILEPERFDIRECTIOFLAGS=""
MYDBMPERFDIRECTIOFLAGS=""
MYDBMPERFRECCOMPFLAGS=""
MYDBMTRANRECCOMPPARAMS=""
MYPOSTCMD="true"

# Building paths
PATH=".:/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin:/bin:/sbin:$PATH"
CPATH=".:/usr/local/include:$CPATH"
LIBRARY_PATH=".:/usr/local/lib:$LIBRARY_PATH"
if test -z "$LD_LIBRARY_PATH" -a -n "$DYLD_LIBRARY_PATH"
then
  LD_LIBRARY_PATH="$DYLD_LIBRARY_PATH"
fi
LD_LIBRARY_PATH=".:/usr/local/lib:$LD_LIBRARY_PATH"
PKG_CONFIG_PATH=".:/usr/local/lib/pkgconfig:$PKG_CONFIG_PATH"
export PATH CPATH LIBRARY_PATH LD_LIBRARY_PATH PKG_CONFIG_PATH

#================================================================
# Options
#================================================================

# Internal variables
enables=""
is_static=""
use_zlib=""
use_zstd=""
use_lz4=""
use_lzma=""

# Specify the installation prefix of extra packages
AC_ARG_WITH(extra,
  AS_HELP_STRING([--with-extra=DIR], [search DIR/include and DIR/lib for extra packages]))
if test -n "$with_extra"
then
  MYCPPFLAGS="$MYCPPFLAGS -I$with_extra/include"
  MYLDFLAGS="$MYLDFLAGS -L$with_extra/lib"
  MYCMDLDFLAGS="$MYCMDLDFLAGS -L$with_extra/lib"
  CPATH="$CPATH:$with_extra/include"
  LIBRARY_PATH="$LIBRARY_PATH:$with_extra/lib"
  LD_LIBRARY_PATH="$LD_LIBRARY_PATH:$with_extra/lib"
  PKG_CONFIG_PATH="$PKG_CONFIG_PATH:$with_extra/lib/pkgconfig"
  PATH="$with_extra/bin:$PATH"
fi

# Development mode
AC_ARG_ENABLE(devel,
  AS_HELP_STRING([--enable-devel], [build for development]))
if test "$enable_devel" = "yes"
then
  MYCFLAGS="-std=c11 -pthread -Wall -pedantic -fPIC -fsigned-char -g0 -O2"
  MYCXXFLAGS="-std=c++17 -pthread -Wall -fPIC -fsigned-char -g0 -O2"
  MYCPPFLAGS="$MYCPPFLAGS -I/usr/local/include"
  MYLDFLAGS="$MYLDFLAGS -L/usr/local/lib"
  MYCMDLDFLAGS="$MYCMDLDFLAGS -L/usr/local/lib"
  MYFILEPERFDIRECTIOFLAGS="--direct_io"
  MYDBMPERFDIRECTIOFLAGS="--direct_io"
  enables="$enables (devel)"
fi

# Debug mode
AC_ARG_ENABLE(debug,
  AS_HELP_STRING([--enable-debug], [build for debugging]))
if test "$enable_debug" = "yes"
then
  MYCFLAGS="-std=c11 -Wall -pedantic -fPIC -fsigned-char -g -O0"
  MYCXXFLAGS="-std=c++17 -Wall -Wextra -Wno-unused-parameter -Wsuggest-override -fPIC -fsigned-char -g -O0"
  MYCPPFLAGS="$MYCPPFLAGS -UNDEBUG -D_TKRZW_DEBUG"
  MYCPPFLAGS="$MYCPPFLAGS -I/usr/local/include"
  MYLDFLAGS="$MYLDFLAGS -L/usr/local/lib"
  MYCMDLDFLAGS="$MYCMDLDFLAGS -L/usr/local/lib"
  MYFILEPERFDIRECTIOFLAGS="--direct_io"
  MYDBMPERFDIRECTIOFLAGS="--direct_io"
  enables="$enables (debug)"
fi

# Profiling mode
AC_ARG_ENABLE(profile,
  AS_HELP_STRING([--enable-profile], [build for profiling]))
if test "$enable_profile" = "yes"
then
  MYCFLAGS="-std=c11 -Wall -pedantic -fPIC -fsigned-char -g -pg -O2 -fno-inline"
  MYCXXFLAGS="-std=c++17 -Wall -fPIC -fsigned-char -g -pg -O2 -fno-inline"
  MYCPPFLAGS="$MYCPPFLAGS -I/usr/local/include"
  MYLDFLAGS="$MYLDFLAGS -L/usr/local/lib"
  MYCMDLDFLAGS="$MYCMDLDFLAGS -L/usr/local/lib"
  enables="$enables (profile)"
fi

# Address sanitizing mode
AC_ARG_ENABLE(sanitize-address,
  AS_HELP_STRING([--enable-sanitize-address], [build with address sanitizing]))
if test "$enable_sanitize_address" = "yes"
then
  MYCFLAGS="-std=c11 -Wall -pedantic -fPIC -fsigned-char -g -O2 -fno-inline -fno-omit-frame-pointer -fsanitize=address"
  MYCXXFLAGS="-std=c++17 -Wall -fPIC -fsigned-char -g -O2 -fno-inline -fno-omit-frame-pointer -fsanitize=address"
  MYCPPFLAGS="$MYCPPFLAGS -I/usr/local/include"
  MYLDFLAGS="$MYLDFLAGS -L/usr/local/lib"
  MYCMDLDFLAGS="$MYCMDLDFLAGS -L/usr/local/lib"
  enables="$enables (sanitize-address)"
fi

# Thread sanitizing mode
AC_ARG_ENABLE(sanitize-thread,
  AS_HELP_STRING([--enable-sanitize-thread], [build with thread sanitizing]))
if test "$enable_sanitize_thread" = "yes"
then
  MYCFLAGS="-std=c11 -Wall -pedantic -fPIC -fsigned-char -g -O2 -fno-inline -fno-omit-frame-pointer -fsanitize=thread"
  MYCXXFLAGS="-std=c++17 -Wall -fPIC -fsigned-char -g -O2 -fno-inline -fno-omit-frame-pointer -fsanitize=thread"
  MYCPPFLAGS="$MYCPPFLAGS -I/usr/local/include"
  MYLDFLAGS="$MYLDFLAGS -L/usr/local/lib"
  MYCMDLDFLAGS="$MYCMDLDFLAGS -L/usr/local/lib"
  enables="$enables (sanitize-thread)"
fi

# Disable optimization
AC_ARG_ENABLE(opt,
  AS_HELP_STRING([--disable-opt], [build without optimization]))
if test "$enable_opt" = "no"
then
  MYCFLAGS="$MYCFLAGS -O0"
  MYCXXFLAGS="$MYCXXFLAGS -O0"
  enables="$enables (no-opt)"
fi

# Optimize for the native architecture
AC_ARG_ENABLE(opt-native,
  AS_HELP_STRING([--enable-opt-native], [build with optimization for the native architecture]))
if test "$enable_opt_native" = "yes"
then
  if uname | grep Darwin >config.tmp && uname -m | grep arm64 >config.tmp
  then
    MYCFLAGS="$MYCFLAGS -O3 -mcpu=native"
    MYCXXFLAGS="$MYCXXFLAGS -O3 -mcpu=native"
  else
    MYCFLAGS="$MYCFLAGS -O3 -march=native"
    MYCXXFLAGS="$MYCXXFLAGS -O3 -march=native"
  fi
  enables="$enables (opt-native)"
fi

# Static mode
AC_ARG_ENABLE(static,
  AS_HELP_STRING([--enable-static], [build by static linking]))
if test "$enable_static" = "yes"
then
  is_static="yes"
  enables="$enables (static)"
fi

# Disable shared object
AC_ARG_ENABLE(shared,
  AS_HELP_STRING([--disable-shared], [avoid to build shared libraries]))
if test "$enable_shared" = "no"
then
  enables="$enables (no-shared)"
fi

# Use the standard library only
AC_ARG_ENABLE(stdonly,
  AS_HELP_STRING([--enable-stdonly], [use the standard library only]))
if test "$enable_stdonly" = "yes"
then
  enables="$enables (stdonly)"
  MYCPPFLAGS="$MYCPPFLAGS -D_TKRZW_STDONLY"
fi

# Enable the zlib compression feature
AC_ARG_ENABLE(zlib,
  AS_HELP_STRING([--enable-zlib], [enable the zlib compressin feature]))
if test "$enable_zlib" = "yes"
then
  use_zlib="yes"
  enables="$enables (zlib)"
fi

# Enable the zstd compression feature
AC_ARG_ENABLE(zstd,
  AS_HELP_STRING([--enable-zstd], [enable the zstd compressin feature]))
if test "$enable_zstd" = "yes"
then
  use_zstd="yes"
  enables="$enables (zstd)"
fi

# Enable the lz4 compression feature
AC_ARG_ENABLE(lz4,
  AS_HELP_STRING([--enable-lz4], [enable the LZ4 compressin feature]))
if test "$enable_lz4" = "yes"
then
  use_lz4="yes"
  enables="$enables (lz4)"
fi

# Enable the LZMA compression feature
AC_ARG_ENABLE(lzma,
  AS_HELP_STRING([--enable-lzma], [enable the LZMA compressin feature]))
if test "$enable_lzma" = "yes"
then
  use_lzma="yes"
  enables="$enables (lzma)"
fi

# Enable as many features as possible
AC_ARG_ENABLE(most-features,
  AS_HELP_STRING([--enable-most-features], [enable as many features as poissble]))
if test "$enable_most_features" = "yes"
then
  enables="$enables (most-features)"
fi

# Messages
printf '#================================================================\n'
printf '# Configuring Tkrzw version %s%s.\n' "$PACKAGE_VERSION" "$enables"
printf '#================================================================\n'

#================================================================
# Checking Commands and Libraries
#================================================================

# C and C++ compilers
AC_PROG_CC
AC_PROG_CXX
AC_LANG(C++)

# Reset variables
if test "$GCC" != "yes"
then
  AC_MSG_WARN([another compiler except for GCC was detected])
  MYCFLAGS=""
  MYCXXFLAGS=""
fi
test -n "$CFLAGS" && MYCFLAGS="$CFLAGS $MYCFLAGS"
test -n "$CXXFLAGS" && MYCXXFLAGS="$CXXFLAGS $MYCXXFLAGS"
test -n "$CPPFLAGS" && MYCPPFLAGS="$CPPFLAGS $MYCPPFLAGS"
test -n "$LDFLAGS" && MYLDFLAGS="$LDFLAGS $MYLDFLAGS"

# Byte order
AC_C_BIGENDIAN(MYCPPFLAGS="$MYCPPFLAGS -D_TKRZW_BIGEND")

# Underlying libraries
AC_CHECK_LIB(c, main)
AC_CHECK_LIB(m, main)
AC_CHECK_LIB(pthread, main)
AC_CHECK_LIB(atomic, main)
AC_CHECK_LIB(rt, main)
AC_CHECK_LIB(stdc++, main)
AC_CHECK_LIB(tkrzw, main, AC_MSG_WARN([old version of Tkrzw was detected]))
MYLDLIBPATH="$LD_LIBRARY_PATH"

# Necessary headers
AC_CHECK_HEADER(stdlib.h, true, AC_MSG_ERROR([stdlib.h is required]))
AC_CHECK_HEADER(stdint.h, true, AC_MSG_ERROR([stdint.h is required]))
AC_CHECK_HEADER(unistd.h, true, AC_MSG_ERROR([unistd.h is required]))
AC_CHECK_HEADER(fcntl.h, true, AC_MSG_ERROR([fcntl.h is required]))
AC_CHECK_HEADER(dirent.h, true, AC_MSG_ERROR([dirent.h is required]))
AC_CHECK_HEADER(pthread.h, true, AC_MSG_ERROR([pthread.h is required]))
AC_CHECK_HEADER(utility, true, AC_MSG_ERROR([utility is required]))
AC_CHECK_HEADER(string, true, AC_MSG_ERROR([string is required]))
AC_CHECK_HEADER(atomic, true, AC_MSG_ERROR([atomic is required]))
AC_CHECK_HEADER(mutex, true, AC_MSG_ERROR([mutex is required]))
AC_CHECK_HEADER(thread, true, AC_MSG_ERROR([thread is required]))
AC_CHECK_HEADER(regex, true, AC_MSG_ERROR([regex is required]))
AC_CHECK_HEADER(cstdint, true, AC_MSG_ERROR([cstdint is required]))

# Optional features
if test "$use_zlib" = "yes" -o "$enable_most_features" = "yes"
then
  AC_CHECK_HEADER(zlib.h, has_zlib="yes")
  if test "$has_zlib" = "yes"
  then
    AC_CHECK_LIB(z, main)
    MYCPPFLAGS="$MYCPPFLAGS -D_TKRZW_COMP_ZLIB"
    MYDBMPERFRECCOMPFLAGS="--record_comp zlib"
    MYDBMTRANRECCOMPPARAMS="record_comp_mode=zlib"
  elif test "$enable_most_features" != "yes"
  then
    AC_MSG_ERROR([zlib.h is required])
  fi
fi
if test "$use_zstd" = "yes" -o "$enable_most_features" = "yes"
then
  AC_CHECK_HEADER(zstd.h, has_zstd="yes")
  if test "$has_zstd" = "yes"
  then
    AC_CHECK_LIB(zstd, main)
    MYCPPFLAGS="$MYCPPFLAGS -D_TKRZW_COMP_ZSTD"
    MYDBMPERFRECCOMPFLAGS="--record_comp zstd"
    MYDBMTRANRECCOMPPARAMS="record_comp_mode=zstd"
  elif test "$enable_most_features" != "yes"
  then
    AC_MSG_ERROR([zstd.h is required])
  fi
fi
if test "$use_lz4" = "yes" -o "$enable_most_features" = "yes"
then
  AC_CHECK_HEADER(lz4.h, has_lz4="yes")
  if test "$has_lz4" = "yes"
  then
    AC_CHECK_LIB(lz4, main)
    MYCPPFLAGS="$MYCPPFLAGS -D_TKRZW_COMP_LZ4"
    MYDBMPERFRECCOMPFLAGS="--record_comp lz4"
    MYDBMTRANRECCOMPPARAMS="record_comp_mode=lz4"
  elif test "$enable_most_features" != "yes"
  then
    AC_MSG_ERROR([lz4.h is required])
  fi
fi
if test "$use_lzma" = "yes" -o "$enable_most_features" = "yes"
then
  AC_CHECK_HEADER(lzma.h, has_lzma="yes")
  if test "$has_lzma" = "yes"
  then
    AC_CHECK_LIB(lzma, main)
    MYCPPFLAGS="$MYCPPFLAGS -D_TKRZW_COMP_LZMA"
  elif test "$enable_most_features" != "yes"
  then
    AC_MSG_ERROR([lzma.h is required])
  fi
fi

# Static linking
if test "$is_static" = "yes"
then
  MYCMDLDFLAGS="$MYCMDLDFLAGS -static"
  LIBS=`echo "${LIBS}" |\
    sed -e 's/-lpthread/-Wl,--whole-archive -lpthread -Wl,--no-whole-archive/'`
fi

# As-needed linking
if uname | grep Linux >config.tmp
then
  MYLDFLAGS="$MYLDFLAGS -Wl,-rpath-link,.:/usr/local/lib:$MYLDLIBPATH"
  MYLDFLAGS="$MYLDFLAGS -Wl,--as-needed"
fi
if uname -a | grep -i 'SunOS' >config.tmp
then
  MYLDSOFLAGS="-shared -Wl,-soname,libtkrzw.so.\$(LIBVER)"
fi

# Shared libraries
if test "$enable_shared" != "no" && test "$enable_profile" != "yes"
then
  if uname | grep Darwin >config.tmp
  then
    MYLIBRARYFILES="$MYLIBRARYFILES libtkrzw.$MYLIBVER.$MYLIBREV.$MYLIBFMT.dylib"
    MYLIBRARYFILES="$MYLIBRARYFILES libtkrzw.$MYLIBVER.dylib"
    MYLIBRARYFILES="$MYLIBRARYFILES libtkrzw.dylib"
    MYCPPFLAGS="$MYCPPFLAGS -D_DARWIN_C_SOURCE"
    MYLDLIBPATHENV="DYLD_LIBRARY_PATH"
  else
    MYLIBRARYFILES="$MYLIBRARYFILES libtkrzw.so.$MYLIBVER.$MYLIBREV.$MYLIBFMT"
    MYLIBRARYFILES="$MYLIBRARYFILES libtkrzw.so.$MYLIBVER"
    MYLIBRARYFILES="$MYLIBRARYFILES libtkrzw.so"
  fi
fi

#================================================================
# Generic Settings
#================================================================

# Export variables
AC_SUBST(MYLIBVER)
AC_SUBST(MYLIBREV)
AC_SUBST(MYLIBFMT)
AC_SUBST(MYHEADERFILES)
AC_SUBST(MYLIBRARYFILES)
AC_SUBST(MYLIBOBJFILES)
AC_SUBST(MYCOMMANDFILES)
AC_SUBST(MYTESTFILES)
AC_SUBST(MYPCFILES)
AC_SUBST(MYCFLAGS)
AC_SUBST(MYCXXFLAGS)
AC_SUBST(MYCPPFLAGS)
AC_SUBST(MYLDSOFLAGS)
AC_SUBST(MYLDFLAGS)
AC_SUBST(MYCMDLDFLAGS)
AC_SUBST(MYCMDLIBS)
AC_SUBST(MYTESTLIBS)
AC_SUBST(MYLDLIBPATH)
AC_SUBST(MYLDLIBPATHENV)
AC_SUBST(MYFILEPERFDIRECTIOFLAGS)
AC_SUBST(MYDBMPERFDIRECTIOFLAGS)
AC_SUBST(MYDBMPERFRECCOMPFLAGS)
AC_SUBST(MYDBMTRANRECCOMPPARAMS)
AC_SUBST(MYPOSTCMD)

# Targets
AC_CONFIG_FILES([Makefile tkrzw.pc])
AC_OUTPUT

# Messages
printf '#================================================================\n'
printf '# Ready to make.\n'
printf '#================================================================\n'

# END OF FILE
