# vim:se syn=tcl:
#
use cc cc-shared cc-lib

options {
    shared=1 => "Build a shared library."
    no-debug=0 => "Disable debug build options."
    amal => "Generates a conservative config file for the amalgamation build."
    static=1 => "Build of static library."
    c99=0 => "Enable checks for C99 stdint.h and inttypes.h, and use them if they are available."
    no-long-long=0 => "Set this to force disabling of 'long long' (sqlite3 still needs it, though)."
    loud=0 => "Enables 'loud' build mode."
    system-sqlite=0 => "Use system-level sqlite3 (CURRENTLY A NO-OP!)."
}


# autosetup interceps 'debug' and 'enable-debug' flags :/
#    prefix:=[get-env HOME /usr/local] -> "Installation prefix."

define FSL_PACKAGE_NAME "libfossil"
define FSL_LIBRARY_VERSION 0.0.1-alphabeta

########################################################################
# See if we can get the fossil schema version from the current
# checkout. If so, use that one, otherwise fall back to some hard-coded
# default.
set auxSchema {}
set contentSchema {}

set fossilBin [find-an-executable fossil]
if {[string length $fossilBin] > 0} {
    puts "Found fossil binary: $fossilBin"
    catch {
        set auxSchema [string trimright \
                       [exec echo \
                            {SELECT value FROM config WHERE name='aux-schema';} \
                            "|" $fossilBin sqlite3] ]
        set contentSchema [string trimright \
                       [exec echo \
                            {SELECT value FROM config WHERE name='content-schema';} \
                            "|" $fossilBin sqlite3] ]
    } ex
#    puts "exception=$ex"
}

#set uname [exec $fossilBin version -v "|" grep "Schema version"]
#puts "uname=$uname"
#return

if {[string length $auxSchema] == 16} {
    puts "Got aux-schema value from current repo: $auxSchema"
    puts "Got content-schema value from current repo: $contentSchema"
} else {
    set auxSchema "2011-04-25 19:50"
    set contentSchema 2
    puts "Using hard-coded aux-schema: $auxSchema"
    puts "Using hard-coded content-schema: $contentSchema"
}
define FSL_AUX_SCHEMA $auxSchema
define FSL_CONTENT_SCHEMA $contentSchema

set FSL_PLATFORM_CONFIG_H "
\#if defined(_MSC_VER)
\#define FSL_PLATFORM_OS \"windows\"
\#define FSL_PLATFORM_PLATFORM \"windows\"
\#define FSL_PLATFORM_PATH_SEPARATOR \";\"
\#define FSL_CHECKOUTDB_NAME \"./_FOSSIL_\"
\/* define a __func__ compatibility macro *\/
\#if _MSC_VER < 1500	/* (vc9.0; dev studio 2008) */
/* sorry; cant do much better than nothing at all on those earlier ones */
\#define __func__ \"(func)\"
\#else
\#define __func__ __FUNCTION__
\#endif
/* for the time being at least, don't complain about there being secure crt alternatives: */
\#ifndef _CRT_SECURE_NO_WARNINGS
\#define _CRT_SECURE_NO_WARNINGS
\#endif
/* for the time being at least, don't complain about using POSIX names instead of ISO C++: */
\#pragma warning ( disable : 4996 )
/* for the time being at least, suppresss some int conversion warnings */
\#pragma warning ( disable : 4244 )		/*'fsl_size_t' to 'int'; this masks other problems that should be fixed*/
\#pragma warning ( disable : 4761 )		/*'integral size mismatch in argument'; more size_t problems*/
\#pragma warning ( disable : 4267 )		/*'size_t' to 'int'; crops up especially in 64-bit builds*/
/* these were extracted from fossil's unistd.h */
\#define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
\#include <io.h>
\#elif defined(__MINGW32__)
\#define FSL_PLATFORM_OS \"mingw\"
\#define FSL_PLATFORM_PLATFORM \"windows\"
\#define FSL_PLATFORM_PATH_SEPARATOR \";\"
\#define FSL_CHECKOUTDB_NAME \"./.fslckout\"
\#elif defined(__CYGWIN__)
\#define FSL_PLATFORM_OS \"cygwin\"
\#define FSL_PLATFORM_PLATFORM \"unix\"
\#define FSL_PLATFORM_PATH_SEPARATOR \":\"
\#define FSL_CHECKOUTDB_NAME \"./_FOSSIL_\"
\#else
\#define FSL_PLATFORM_OS \"unknown\"
\#define FSL_PLATFORM_PLATFORM \"unix\"
\#define FSL_PLATFORM_PATH_SEPARATOR \":\"
\#define FSL_CHECKOUTDB_NAME \"./.fslckout\"
\#endif
"

if {[opt-bool amal]} {
    puts "Generating conservative config for the amalgamation build..."
    set incGuard _NET_FOSSIL_SCM_FSL_AMALGAMATION_CONFIG_H_INCLUDED_
    set ofile libfossil-config.h
    set out [open $ofile w]
    puts $out "\#if !defined($incGuard)
\#define $incGuard 1
\#define FSL_AUX_SCHEMA \"$auxSchema\"
\#define FSL_CONTENT_SCHEMA \"$contentSchema\"
\#define FSL_PACKAGE_NAME \"[get-define FSL_PACKAGE_NAME]\"
\#define FSL_LIBRARY_VERSION \"[get-define FSL_LIBRARY_VERSION]\"
/* Tweak the following for your system... */
\#define HAVE_C99_INT 0
\#define HAVE_COMPRESS 1
\#define HAVE_DLFCN_H 0
\#define HAVE_DLOPEN 0
\#define HAVE_GETADDRINFO 0
\#define HAVE_INET_NTOP 0
\#define HAVE_INTTYPES_H 0
\#define HAVE_LIBDL 0
\#define HAVE_LIBLTDL 0
\#define HAVE_LONG_LONG 0
\#if !defined(_WIN32)
\#define HAVE_LSTAT 1
\#define HAVE_LTDL_H 0
\#define HAVE_LT_DLOPEN 0
\#define HAVE_OPENDIR 1
\#define HAVE_PIPE 1
\#define HAVE_STAT 1
\#define HAVE_STDINT_H 0
\#ifndef _BSD_SOURCE
\#define _BSD_SOURCE 1
\#endif
\#ifndef _XOPEN_SOURCE
\#define _XOPEN_SOURCE 500
\#endif
\#else
\#define HAVE_LSTAT 0
\#define HAVE_LTDL_H 0
\#define HAVE_LT_DLOPEN 0
\#define HAVE_OPENDIR 1
\#define HAVE_PIPE 0
\#define HAVE_STAT 0
\#define HAVE_STDINT_H 0
\#endif
/* _WIN32 */

$FSL_PLATFORM_CONFIG_H

\#endif
/* $incGuard */
"
    close $out
    puts "Generated $ofile."
    return
}
# end of --amal bootstrap config generation

cc-check-c11

if {![opt-bool no-long-long]} {
    if {[cc-check-types "long long"]} {
        set llSize [cc-check-sizeof "long long"]
        #    puts llSize=$llSize
    }
} else {
    puts "Disabling long long."
    define HAVE_LONG_LONG 0
}

cc-check-sizeof "void *"

if {[opt-bool system-sqlite]} {
   if {![cc-check-function-in-lib sqlite3_open sqlite3]} {
       user-error "Missing sqlite3"
   }
}

if {![cc-check-includes zlib.h] ||
    ![cc-check-function-in-lib compress z]} {
    user-error "Missing functional zlib"
}

if {[opt-bool c99]} {
    if {[cc-check-includes inttypes.h stdint.h]} {
        define HAVE_C99_INT 1
        msg-result "Enabling C99 integer headers."
    } else {
        msg-result "C99 stdint/inttypes.h not found. Falling back to hand-rolled variants."
    }
} else {
    msg-result "Not checking for C99 stdint/inttypes.h. Use --c99 to enable them."
}

define HAVE_LIBLTDL 0
define HAVE_LIBDL 0
define LDFLAGS_MODULE_LOADER ""
define FSL_ENABLE_MODULE_LOADER 0
if {[cc-check-includes ltdl.h] && [cc-check-function-in-lib lt_dlopen ltdl]} {
    define HAVE_LIBLTDL 1
    define LDFLAGS_MODULE_LOADER "-lltdl"
    define FSL_ENABLE_MODULE_LOADER 1
}


if {[cc-check-includes dlfcn.h]} {
    msg-result "Found dlfcn.h."
    define HAVE_LIBDL 1
    if {[cc-check-function-in-lib dlopen dl]} {
      msg-result "Found libdl."
      define LDFLAGS_MODULE_LOADER "-ldl"
    } else {
      msg-result "No libdl found. Assuming dlopen is built-in."
      define LDFLAGS_MODULE_LOADER ""
    }
    define FSL_ENABLE_MODULE_LOADER 1
} elseif {[cctest -includes dlfcn.h -source {dlerror();}]} {
    msg-result "This system can use dlopen() w/o -ldl"
    define HAVE_LIBDL 1
    define LDFLAGS_MODULE_LOADER ""
    define FSL_ENABLE_MODULE_LOADER 1
}

if {![get-define FSL_ENABLE_MODULE_LOADER]} {
    msg-result {No usable module loading library found. No worries, because we won't have a module system yet. :-D}
} else {
    msg-result {Found a module loader. Now we just need something to do with it.}
}


# cc-check-functions getcwd fopen
cc-check-functions opendir stat pipe inet_ntop getaddrinfo
#msg-result [cc-check-functions lstat]

if {[cc-check-functions lstat]} {
    # for lstat() on Linux:
    define _XOPEN_SOURCE 500
    # alternate for lstat() on Linux:
    define _BSD_SOURCE 1
}


# Find some tools
cc-check-tools ar ranlib strip

set extra_objs {}

if {[find-an-executable cygpath] ne "" || $::tcl_platform(os)=="Windows NT"} {
  set cFlags {}
} else {
  set cFlags {-fPIC}
}

if {[opt-bool no-debug]} {
    msg-result "Non-debug build."
    set cFlags "$cFlags -O2"
} else {
    msg-result "Debug build enabled. Use --no-debug to build in non-debug mode."
    set cFlags "$cFlags -g -DDEBUG -O0"
}

define CFLAGS $cFlags

if {[opt-bool shared]} {
    msg-result "Enabling build of shared library."
    define LIBFOSSIL_SHARED 1
} else {
    define LIBFOSSIL_SHARED 0
    msg-result "Disabling build of shared library."
}

if {[opt-bool static]} {
    msg-result "Enabling build of static library."
    define LIBFOSSIL_STATIC 1
} else {
    define LIBFOSSIL_STATIC 0
    msg-result "Disabling build of static library."
}


if {[opt-bool loud]} {
    define BUILD_QUIETLY 0
    puts "Using 'loud' build mode."
} else {
    define BUILD_QUIETLY 1
    puts "Enabling quiet build mode. Use --loud to enable loud mode."
}

set dotBin [find-an-executable dot]
if {[string length $dotBin]} {
    define DOXYGEN_HAVE_DOT YES
    msg-result "Adding HAVE_DOT=YES to doxyfile."
} else {
    define DOXYGEN_HAVE_DOT NO
}


# Creates mkefile(-like) file $name from $name.in
proc makeFromDotIn {name} {
    catch { exec chmod u+w $name }
    make-template $name.in $name
    catch { exec chmod u-w $name }
}
# Each generated Makefile requires an input file with a .in extension:
set makefiles {
    config.make
    Makefile
    doc/Doxyfile
    src/Makefile
    f-apps/Makefile
    th1ish/Makefile
    cpp/Makefile
}
foreach {f} $makefiles {
    makeFromDotIn $f
}

if {0} {
    # Achtung: ordering of the -bare/-str options here is important
    # because of the mixed use of strings and integers for #defines...
    make-config-header include/fossil-scm/autoconfig.h \
        -none {DOXYGEN_*} \
        -bare {HAVE_*  FSL_ENABLE_* _BSD_SOURCE _XOPEN_SOURCE} \
        -str {FSL_* PACKAGE_*}
}

########################################################################
# Generate our autconf header by hand to allow finer control
# over the structure....
set confH include/fossil-scm/autoconfig.h
set incGuard _NET_FOSSIL_SCM_FSL_AUTO_CONFIG_H_INCLUDED_
if {[opt-bool amal]} {
    set confH libfossil-config.h
    set incGuard _NET_FOSSIL_SCM_FSL_AMALGAMATION_CONFIG_H_INCLUDED_
}
puts "Generating config header $confH"
    set out [open $confH w]
    puts $out "\#if !defined($incGuard)
\#define $incGuard 1
\#define FSL_AUX_SCHEMA \"$auxSchema\"
\#define FSL_CONTENT_SCHEMA \"$contentSchema\"
\#define FSL_PACKAGE_NAME \"[get-define FSL_PACKAGE_NAME]\"
\#define FSL_LIBRARY_VERSION \"[get-define FSL_LIBRARY_VERSION]\"
/* Tweak the following for your system... */
\#define HAVE_C99_INT [get-define HAVE_C99_INT 0]
\#define HAVE_GETADDRINFO [get-define HAVE_GETADDRINFO 0]
\#define HAVE_INET_NTOP [get-define HAVE_INET_NTOP 0]
\#define HAVE_LONG_LONG [get-define HAVE_LONG_LONG 0]
\#if !defined(_WIN32)
\#define HAVE_DLFCN_H [get-define HAVE_DLFCN_H 0]
\#define HAVE_DLOPEN [get-define HAVE_DLOPEN 0]
\#define HAVE_LIBDL [get-define HAVE_LIBDL 0]
\#define HAVE_LIBLTDL [get-define HAVE_LIBLTDL 0]
\#define HAVE_LSTAT [get-define HAVE_LSTAT 1]
\#define HAVE_LTDL_H [get-define HAVE_LTDL_H 0]
\#define HAVE_LT_DLOPEN [get-define HAVE_LT_DLOPEN 0]
\#define HAVE_OPENDIR [get-define HAVE_OPENDIR 1]
\#define HAVE_PIPE [get-define HAVE_PIPE 1]
\#define HAVE_STAT [get-define HAVE_STAT 1]
\#ifndef _BSD_SOURCE
\#define _BSD_SOURCE [get-define _BSD_SOURCE 1]
\#endif
\#ifndef _XOPEN_SOURCE
\#define _XOPEN_SOURCE [get-define _XOPEN_SOURCE 500]
\#endif
\#else
\#define HAVE_DLFCN_H 0
\#define HAVE_DLOPEN 0
\#define HAVE_LIBDL 0
\#define HAVE_LIBLTDL 0
\#define HAVE_LSTAT 0
\#define HAVE_LTDL_H 0
\#define HAVE_LT_DLOPEN 0
\#define HAVE_OPENDIR 1
\#define HAVE_PIPE 0
\#define HAVE_STAT 0
\#endif
/*_WIN32*/

$FSL_PLATFORM_CONFIG_H

\#endif
/* $incGuard */
"
    close $out
    puts "Generated $confH."
    return
}
