dnl Process this file with autoconf to produce a configure script.
dnl AC_INIT(libdwarf.h)
AC_INIT()
AC_CONFIG_HEADER(config.h)

AC_PROG_CC
AC_C_BIGENDIAN
AC_GCC_TRADITIONAL
AC_PROG_INSTALL
AC_CHECK_TOOL(RANLIB, ranlib, :)
AC_CHECK_TOOL(AR, ar)

dnl AC_ARFLAGS

AC_CHECK_HEADERS(alloca.h elf.h unistd.h elfaccess.h libelf.h libelf/libelf.h  sys/types.h sys/elf_386.h sys/elf_amd64.h sys/elf_SPARC.h sys/ia64/elf.h)

dnl Windows seems to have libelf.h with the normal elf.h
dnl data embedded. No literal elf.h  is present.
dnl Get a best estimate of elf header data location.
AC_MSG_CHECKING(where is basic elf data)
if test "$ac_cv_header_elf_h" = yes; then
 AC_DEFINE(HAVE_LOCATION_OF_LIBELFHEADER,[<elf.h>], [Define to header that first defines elf])
 AC_MSG_RESULT(<elf.h>)
elif test "$ac_cv_header_libelf_h" = yes; then
 AC_DEFINE(HAVE_LOCATION_OF_LIBELFHEADER, [<libelf.h>],
        [Define to header that first defines elf.])
 AC_MSG_RESULT(<libelf.h>)
elif test "$ac_cv_header_libelf_libelf_h" = yes; then
 AC_DEFINE(HAVE_LOCATION_OF_LIBELFHEADER,[<libelf/libelf.h>],
        [Define to header that first defines elf.])
 AC_MSG_RESULT(<libelf/libelf.h>)
else
 AC_MSG_RESULT(NO standard ELF HEADERS found)
fi

dnl The default libdwarf is the one with struct Elf
echo Assuming struct Elf for the default libdwarf.h
cp $srcdir/libdwarf.h.in libdwarf.h

dnl AC_MSG_CHECKING(is elf64_getehdr function in libelf)
AC_CHECK_LIB(elf,elf64_getehdr,
  [AC_DEFINE(HAVE_ELF64_GETEHDR,1,
	[Define to 1 if the elf64_getehdr function is in libelf.a.])
    AC_MSG_RESULT(yes)], 
  [AC_MSG_RESULT(no)])

dnl AC_MSG_CHECKING(is elf64_getshdr function in libelf)
AC_CHECK_LIB(elf,elf64_getshdr,
  [AC_DEFINE(HAVE_ELF64_GETSHDR,1,
	[Define to 1 if the elf64_getshdr function is in libelf.a.])
    AC_MSG_RESULT(yes)],
  [AC_MSG_RESULT(no)])

AC_MSG_CHECKING(is __uint32_t predefined in the compiler)
AC_TRY_COMPILE( ,  __uint32_t p; p = 2; ,
   [AC_DEFINE(HAVE___UINT32_T,1,
	[See if __uint32_t is predefined in the compiler.])
    AC_MSG_RESULT(yes)],
   [AC_MSG_RESULT(no)])

AC_MSG_CHECKING(is __uint64_t predefined in the compiler)
AC_TRY_COMPILE( ,  __uint64_t p; p = 3; ,
   [AC_DEFINE(HAVE___UINT64_T,1,
	[See if __uint64_t is predefined in the compiler.])
    AC_MSG_RESULT(yes)],
   [AC_MSG_RESULT(no)])

AC_MSG_CHECKING(is __uint32_t defined in sys/types.h)
AC_TRY_COMPILE([#include <sys/types.h>],[  __uint32_t p; p = 4;] ,
  [AC_DEFINE(HAVE___UINT32_T_IN_SYS_TYPES_H,1,
	[Define 1 if sys/types.h defines __uint32_t.])
    AC_MSG_RESULT(yes)],
   [AC_MSG_RESULT(no)])

AC_MSG_CHECKING(is __uint64_t defined in sys/types.h)
AC_TRY_COMPILE([#include <sys/types.h>],[  __uint64_t p; p = 5;] ,
  [AC_DEFINE(HAVE___UINT64_T_IN_SYS_TYPES_H,1,
	[Define 1 if sys/types.h defines __uint64_t.])
    AC_MSG_RESULT(yes)],
   [AC_MSG_RESULT(no)])

AC_MSG_CHECKING(compiler supports __attribute__ unused )
AC_TRY_RUN([ 
  static unsigned foo( unsigned x, __attribute__ ((unused)) int y)
  {  unsigned x2 = x + 1;
     return x2;
  }
  int main(void) {
     unsigned y = 0; 
     y = foo(12,y);
     return 0;
  }
] ,
  [AC_DEFINE(HAVE_UNUSED_ATTRIBUTE,1,
	[Define 1 if __attribute__ ((unused)) compiles ok.])
    AC_MSG_RESULT(yes)],
  [AC_MSG_RESULT(no)],[ ])

AC_SUBST(dwfzlib,[])
AC_MSG_CHECKING(zlib.h usability)
AC_TRY_COMPILE([#include "zlib.h"],[ 
    Bytef dest[100]; 
    uLongf destlen = 100; 
    Bytef *src = 0;
    uLong srclen = 3;
    int res = uncompress(dest,&destlen,src,srclen);
    if (res == Z_OK) {
         /* ALL IS WELL */
    }
    ],
    [AC_MSG_RESULT(yes)
     AC_DEFINE(HAVE_ZLIB,1,
	[Define 1 if zlib (decompression library) seems available.])
     AC_SUBST(dwfzlib,[-lz])
    ],
    [AC_MSG_RESULT(no)])

dnl The following are for FreeBSD and others which
dnl use struct _Elf as the actual struct type.
AC_TRY_COMPILE([#include <libelf/libelf.h>  
  struct _Elf; typedef struct _Elf Elf; ],
  [struct _Elf *a = 0; ],
  [ sed 's/struct Elf/struct _Elf/g' <$srcdir/libdwarf.h.in >libdwarf.h ;
    echo Found struct _Elf in libelf/libelf.h, using it in libdwarf.h ],
  [echo libelf/libelf.h does not have struct _Elf]) 

AC_TRY_COMPILE([#include <libelf.h>
  struct _Elf; typedef struct _Elf Elf; ],
  [ struct _Elf *a = 0; ],
  [ sed 's/struct Elf/struct _Elf/g' <$srcdir/libdwarf.h.in >libdwarf.h ;
    echo Found struct _Elf in libelf.h, using it in libdwarf.h ],
  [echo libelf.h does not have struct _Elf]) 


dnl checking for ia 64 types, which might be enums, using HAVE_R_IA_64_DIR32LSB
dnl to stand in for a small set.
AC_MSG_CHECKING(Intel Itanium relocation types defined)
AC_TRY_COMPILE([#include HAVE_LOCATION_OF_LIBELFHEADER],[  int p; p = R_IA_64_DIR32LSB;] ,
  [AC_DEFINE(HAVE_R_IA_64_DIR32LSB,1,
	[Define 1 if  R_IA_64_DIR32LSB is defined (might be enum value).])
    AC_MSG_RESULT(yes)],
   [AC_MSG_RESULT(no)])

AC_MSG_CHECKING(libelf defines struct _Elf)
AC_TRY_COMPILE([#include <libelf.h>],[ struct _Elf a; int i; i = 0; ] ,
  [AC_DEFINE(HAVE_STRUCT_UNDERSCORE_ELF,1,
	[Define 1 if libelf.h defines struct _Elf ]) 
    AC_MSG_RESULT(yes)],
   [AC_MSG_RESULT(no)])


AC_MSG_CHECKING(compile with libelf.h works )
AC_TRY_COMPILE([
#include <libelf.h>
],[  int p; p = 0; ] ,
  [AC_DEFINE(HAVE_RAW_LIBELF_OK,1,
	[Define 1 if plain libelf builds.])
    AC_MSG_RESULT(yes)],
    [AC_MSG_RESULT(no)])

AC_MSG_CHECKING(libelf.h exists and has Elf function declarations)
AC_TRY_COMPILE([
#include <libelf.h>
],[  int p; char *ident; p = 0;ident=elf_getident(0, 0);] ,
  [AC_MSG_RESULT(yes)],
  [AC_MSG_RESULT(no)])

AC_MSG_CHECKING(libelf/libelf.h exists and has Elf function declarations)
AC_TRY_COMPILE([
#include <libelf/libelf.h>
],[  int p; char *ident; p = 0;ident=elf_getident(0, 0);] ,
  [AC_MSG_RESULT(yes)],
  [AC_MSG_RESULT(no)])


AC_MSG_CHECKING(libelf defines off64_t if _GNU_SOURCE defined)
AC_TRY_COMPILE([
#define _GNU_SOURCE
#include <libelf.h>
],[  off64_t  p; p = 0;] ,
  [AC_DEFINE(HAVE_LIBELF_OFF64_OK,1,
	[Define 1 if  off64 is defined via libelf with GNU_SOURCE.])
    AC_MSG_RESULT(yes)],
    [AC_MSG_RESULT(no)])

dnl the existence of sgidefs.h does not prove it's truly SGI, nor
dnl prove that __uint32_t or __uint64_t is defined therein.
AC_MSG_CHECKING(sgidefs.h present and defines __uint32_t)
AC_TRY_COMPILE([#include <sgidefs.h>],[  __uint32_t p; p = 27;] ,
  [AC_DEFINE(HAVE___UINT32_T_IN_SGIDEFS_H,1,
        [Define 1 if __uint32_t is in sgidefs.h.])
    AC_MSG_RESULT(yes)],
    [AC_MSG_RESULT(no)])

AC_MSG_CHECKING(sgidefs.h present and defines __uint64_t)
AC_TRY_COMPILE([#include <sgidefs.h>],[  __uint64_t p; p = 27;] ,
  [AC_DEFINE(HAVE___UINT64_T_IN_SGIDEFS_H,1,
        [Define 1 if __uint64_t is in sgidefs.h.]) 
    AC_MSG_RESULT(yes)],
    [AC_MSG_RESULT(no)])

AC_MSG_CHECKING(is Elf64_Rela defined in elf.h)
AC_TRY_COMPILE([#include HAVE_LOCATION_OF_LIBELFHEADER],
  [  Elf64_Rela p; p.r_offset = 1; ],
  [AC_DEFINE(HAVE_ELF64_RELA,1,
        [Define 1 if Elf64_Rela defined.]) 
    AC_MSG_RESULT(yes)],
    [AC_MSG_RESULT(no)])

AC_MSG_CHECKING(is Elf64_Sym defined in elf.h)
AC_TRY_COMPILE([#include HAVE_LOCATION_OF_LIBELFHEADER],
  [  Elf64_Sym p; p.st_info = 1; ],
  [AC_DEFINE(HAVE_ELF64_SYM,1,
        [Define 1 if Elf64_Sym defined.])
    AC_MSG_RESULT(yes)],
    [AC_MSG_RESULT(no)])



dnl default-disabled shared
AC_SUBST(build_shared,[nosharedlibrary])
AC_SUBST(dwfpic,[-fPIC])


AC_MSG_CHECKING(build shared)
AC_ARG_ENABLE(shared,AC_HELP_STRING([--enable-shared],
		[build shared library libdwarf.so]))
AS_IF([ test "x$enable_shared" = "xyes"], [
   AC_SUBST(build_shared,[libdwarf.so])
   AC_SUBST(dwfpic,[-fPIC])
   AC_MSG_RESULT(yes)
], [
   AC_MSG_RESULT(no)
])


dnl default-enabled nonshared
AC_SUBST(build_nonshared,[libdwarf.a])
AC_MSG_CHECKING(build nonshared)
AC_ARG_ENABLE(nonshared,AC_HELP_STRING([--disable-nonshared],
		[do not build archive library libdwarf.a]))
AS_IF([ test "x$enable_nonshared" = "xno"], [
   dnl We could turn on shared here if not already on.
   AC_SUBST(build_nonshared,[noarchivelibrary])
   AC_MSG_RESULT(no)
],[
   AC_MSG_RESULT(yes)
])

dnl turning off fpic with nonshared build is not going to work,
AC_MSG_CHECKING(build -fPIC) 
AC_ARG_ENABLE(fpic,AC_HELP_STRING([--disable-fpic],
		[do not build with -fPIC]))
AS_IF([ test "x$enable_fpic" = "xno"], [
   dnl  Force -fPIC off, normally nobody needs this.
   AC_SUBST(dwfpic,[])
   AC_MSG_RESULT(no)
],[
   AC_MSG_RESULT(yes)
])

dnl This adds compiler option -Wall (gcc compiler warnings)
AC_SUBST(dwfwall,[])
AC_MSG_CHECKING(build -Wall) 
AC_ARG_ENABLE(wall,AC_HELP_STRING([--enable-wall],
	[Add -Wall (default is none)]),
	[ AC_SUBST(dwfwall,["-Wall -O0 -Wpointer-arith -Wmissing-declarations -Wmissing-prototypes -Wdeclaration-after-statement -Wextra -Wcomment -Wformat -Wpedantic -Wuninitialized -Wno-long-long -Wshadow -Wbad-function-cast -Wmissing-parameter-type -Wnested-externs"])
          AC_MSG_RESULT(yes) ],
	[ AC_SUBST(dwfwall,[]) 
          AC_MSG_RESULT(no)
        ]
        )
dnl This adds compiler option -fsanitize=address etc(gcc compiler run-time checks))
AC_SUBST(dwfsanitize,[])
AC_MSG_CHECKING(build -fsanitize-address) 
AC_ARG_ENABLE(sanitize,AC_HELP_STRING([--enable-sanitize],
	[Add -fsanitize (default is not to)]),
	[ AC_SUBST(dwfsanitize,["-fsanitize=address -fsanitize=leak -fsanitize=undefined"])
          AC_MSG_RESULT(yes) ],
	[ AC_SUBST(dwfsanitize,[]) 
          AC_MSG_RESULT(no)
        ]
        )

dnl  This changes the gennames option from -s  to -t
AC_SUBST(dwarf_namestable,[-s])
AC_ARG_ENABLE(namestable,AC_HELP_STRING([--enable-namestable],
	[Name string functions implemented as binary search (default is with C switch)]),
	[ AC_SUBST(dwarf_namestable,[-s]) ]
	[ AC_SUBST(dwarf_namestable,[-t]) ])

AC_MSG_CHECKING(enable nonstandardprintf)
AC_ARG_ENABLE(nonstandardprintf,AS_HELP_STRING([--enable-nonstandardprintf],
	[Use a special printf format for 64bit (default is NO)]),
	[ AC_DEFINE([HAVE_NONSTANDARD_PRINTF_64_FORMAT],[1], 
	   [Define 1 if need nonstandard printf format for  64bit] )
          AC_MSG_RESULT(yes)],
        [AC_MSG_RESULT(no)])

AC_MSG_CHECKING(enable  windowspath) 
AC_ARG_ENABLE(windowspath,AC_HELP_STRING([--enable-windowspath],
	[Detect certain Windows paths as full paths (default is NO)]),
	[ AC_DEFINE([HAVE_WINDOWS_PATH],[1], 
	   [Define 1 if want to allow Windows full path detection] )
          AC_MSG_RESULT(yes)],
        [AC_MSG_RESULT(no) ])

AC_MSG_CHECKING(enable old frame columns) 
AC_ARG_ENABLE(oldframecol,AC_HELP_STRING([--enable-oldframecol],
	[Use HAVE_OLD_FRAME_CFA_COL (default is to use new DW_FRAME_CFA_COL3)]),
	[ AC_DEFINE([HAVE_OLD_FRAME_CFA_COL],[1], 
	   [Define 1 to default to old DW_FRAME_CFA_COL] )
          AC_MSG_RESULT(yes)],
        [AC_MSG_RESULT(no) ])

AC_MSG_CHECKING(have windows stdafx.h) 
AC_TRY_COMPILE([#include "stdafx.h"],[  int p; p = 27;] ,
  [AC_DEFINE(HAVE_STDAFX_H,1,
        [Define 1 if we have the Windows specific header stdafx.h])
   AC_MSG_RESULT(yes)],
  [AC_MSG_RESULT(no) ] )

dnl See pro_init(), HAVE_DWARF2_99_EXTENSION also generates
dnl 32bit offset dwarf unless DW_DLC_OFFSET_SIZE_64 flag passed to
dnl pro_init.
AC_MSG_CHECKING(producer generates SGI IRIX output) 
AC_ARG_ENABLE(dwarf_format_sgi_irix, AC_HELP_STRING([--enable-dwarf-format-sgi-irix],
	[Force producer to SGI IRIX offset dwarf.]),
  	[AC_DEFINE(HAVE_SGI_IRIX_OFFSETS,1,
		[Define 1 if want producer to build with IRIX offset sizes] )
        AC_MSG_RESULT(yes)], 
        [AC_MSG_RESULT(no)])
        
AC_MSG_CHECKING(producer generates only 32bit) 
AC_ARG_ENABLE(dwarf_format_strict_32bit, AC_HELP_STRING([--enable-dwarf-format-strict-32bit],
	[Force producer to generate only DWARF format 32bit.]),
  	[AC_DEFINE(HAVE_STRICT_DWARF2_32BIT_OFFSET,1,
		[Define 1 if want producer to build with only 32bit section offsets] )
          AC_MSG_RESULT(yes)],
	[AC_DEFINE(HAVE_DWARF2_99_EXTENSION,1,
		[Define 1 if want to allow producer to build with 32/64bit section offsets per dwarf3] )
          AC_MSG_RESULT(no)])

AC_OUTPUT(Makefile)
