Home | History | Annotate | Line # | Download | only in tea
teaish.tcl revision 1.1
      1  1.1  christos # Teaish configure script for the SQLite Tcl extension
      2  1.1  christos 
      3  1.1  christos #
      4  1.1  christos # State for disparate config-time pieces.
      5  1.1  christos #
      6  1.1  christos array set sqlite__Config [proj-strip-hash-comments {
      7  1.1  christos   #
      8  1.1  christos   # The list of feature --flags which the --all flag implies. This
      9  1.1  christos   # requires special handling in a few places.
     10  1.1  christos   #
     11  1.1  christos   all-flag-enables {fts3 fts4 fts5 rtree geopoly}
     12  1.1  christos 
     13  1.1  christos   # >0 if building in the canonical tree. -1=undetermined
     14  1.1  christos   is-canonical -1
     15  1.1  christos }]
     16  1.1  christos 
     17  1.1  christos #
     18  1.1  christos # Set up the package info for teaish...
     19  1.1  christos #
     20  1.1  christos apply {{dir} {
     21  1.1  christos   # Figure out the version number...
     22  1.1  christos   set version ""
     23  1.1  christos   if {[file exists $dir/../VERSION]} {
     24  1.1  christos     # The canonical SQLite TEA(ish) build
     25  1.1  christos     set version [proj-file-content -trim $dir/../VERSION]
     26  1.1  christos     set ::sqlite__Config(is-canonical) 1
     27  1.1  christos     set distname sqlite-tcl
     28  1.1  christos   } elseif {[file exists $dir/generic/tclsqlite3.c]} {
     29  1.1  christos     # The copy from the teaish tree, used as a dev/test bed before
     30  1.1  christos     # updating SQLite's tree.
     31  1.1  christos     set ::sqlite__Config(is-canonical) 0
     32  1.1  christos     set fd [open $dir/generic/tclsqlite3.c rb]
     33  1.1  christos     while {[gets $fd line] >=0} {
     34  1.1  christos       if {[regexp {^#define[ ]+SQLITE_VERSION[ ]+"(3.+)"} \
     35  1.1  christos              $line - version]} {
     36  1.1  christos         set distname sqlite-teaish
     37  1.1  christos         break
     38  1.1  christos       }
     39  1.1  christos     }
     40  1.1  christos     close $fd
     41  1.1  christos   }
     42  1.1  christos 
     43  1.1  christos   if {"" eq $version} {
     44  1.1  christos     proj-fatal "Cannot determine the SQLite version number"
     45  1.1  christos   }
     46  1.1  christos 
     47  1.1  christos   proj-assert {$::sqlite__Config(is-canonical) > -1}
     48  1.1  christos   proj-assert {[string match 3.*.* $version]} \
     49  1.1  christos     "Unexpected SQLite version: $version"
     50  1.1  christos 
     51  1.1  christos   set pragmas {}
     52  1.1  christos   if {$::sqlite__Config(is-canonical)} {
     53  1.1  christos     # Disable "make dist" in the canonical tree.  That tree is
     54  1.1  christos     # generated from several pieces and creating/testing working
     55  1.1  christos     # "dist" rules for that sub-build currently feels unnecessary. The
     56  1.1  christos     # copy in the teaish tree, though, should be able to "make dist".
     57  1.1  christos     lappend pragmas no-dist
     58  1.1  christos   } else {
     59  1.1  christos     lappend pragmas full-dist
     60  1.1  christos   }
     61  1.1  christos 
     62  1.1  christos   teaish-pkginfo-set -vars {
     63  1.1  christos     -name sqlite
     64  1.1  christos     -name.pkg sqlite3
     65  1.1  christos     -version $version
     66  1.1  christos     -name.dist $distname
     67  1.1  christos     -libDir sqlite$version
     68  1.1  christos     -pragmas $pragmas
     69  1.1  christos     -src generic/tclsqlite3.c
     70  1.1  christos   }
     71  1.1  christos   # We should also have:
     72  1.1  christos   #    -vsatisfies 8.6-
     73  1.1  christos   # But at least one platform is failing this vsatisfies check
     74  1.1  christos   # for no apparent reason:
     75  1.1  christos   # https://sqlite.org/forum/forumpost/fde857fb8101a4be
     76  1.1  christos }} [teaish-get -dir]
     77  1.1  christos 
     78  1.1  christos 
     79  1.1  christos #
     80  1.1  christos # Must return either an empty string or a list in the form accepted by
     81  1.1  christos # autosetup's [options] function.
     82  1.1  christos #
     83  1.1  christos proc teaish-options {} {
     84  1.1  christos   # These flags and defaults mostly derive from the historical TEA
     85  1.1  christos   # build.  Some, like ICU, are taken from the canonical SQLite tree.
     86  1.1  christos   return [subst -nocommands -nobackslashes {
     87  1.1  christos     with-system-sqlite=0
     88  1.1  christos       => {Use the system-level SQLite instead of the copy in this tree.
     89  1.1  christos           Also requires use of --override-sqlite-version so that the build
     90  1.1  christos           knows what version number to associate with the system-level SQLite.}
     91  1.1  christos     override-sqlite-version:VERSION
     92  1.1  christos       => {For use with --with-system-sqlite to set the version number.}
     93  1.1  christos     threadsafe=1         => {Disable mutexing}
     94  1.1  christos     with-tempstore:=no   => {Use an in-RAM database for temporary tables: never,no,yes,always}
     95  1.1  christos     load-extension=0     => {Enable loading of external extensions}
     96  1.1  christos     math=1               => {Disable math functions}
     97  1.1  christos     json=1               => {Disable JSON functions}
     98  1.1  christos     fts3                 => {Enable the FTS3 extension}
     99  1.1  christos     fts4                 => {Enable the FTS4 extension}
    100  1.1  christos     fts5                 => {Enable the FTS5 extension}
    101  1.1  christos     update-limit         => {Enable the UPDATE/DELETE LIMIT clause}
    102  1.1  christos     geopoly              => {Enable the GEOPOLY extension}
    103  1.1  christos     rtree                => {Enable the RTREE extension}
    104  1.1  christos     session              => {Enable the SESSION extension}
    105  1.1  christos     all=1                => {Disable $::sqlite__Config(all-flag-enables)}
    106  1.1  christos     with-icu-ldflags:LDFLAGS
    107  1.1  christos       => {Enable SQLITE_ENABLE_ICU and add the given linker flags for the
    108  1.1  christos           ICU libraries. e.g. on Ubuntu systems, try '-licui18n -licuuc -licudata'.}
    109  1.1  christos     with-icu-cflags:CFLAGS
    110  1.1  christos       => {Apply extra CFLAGS/CPPFLAGS necessary for building with ICU.
    111  1.1  christos           e.g. -I/usr/local/include}
    112  1.1  christos     with-icu-config:=auto
    113  1.1  christos       => {Enable SQLITE_ENABLE_ICU. Value must be one of: auto, pkg-config,
    114  1.1  christos           /path/to/icu-config}
    115  1.1  christos     icu-collations=0
    116  1.1  christos       => {Enable SQLITE_ENABLE_ICU_COLLATIONS. Requires --with-icu-ldflags=...
    117  1.1  christos           or --with-icu-config}
    118  1.1  christos   }]
    119  1.1  christos }
    120  1.1  christos 
    121  1.1  christos #
    122  1.1  christos # Gets called by tea-configure-core. Must perform any configuration
    123  1.1  christos # work needed for this extension.
    124  1.1  christos #
    125  1.1  christos proc teaish-configure {} {
    126  1.1  christos   use teaish/feature
    127  1.1  christos 
    128  1.1  christos   if {[proj-opt-was-provided override-sqlite-version]} {
    129  1.1  christos     teaish-pkginfo-set -version [opt-val override-sqlite-version]
    130  1.1  christos     proj-warn "overriding sqlite version number:" [teaish-pkginfo-get -version]
    131  1.1  christos   } elseif {[proj-opt-was-provided with-system-sqlite]
    132  1.1  christos             && [opt-val with-system-sqlite] ne "0"} {
    133  1.1  christos     proj-fatal "when using --with-system-sqlite also use" \
    134  1.1  christos       "--override-sqlite-version to specify a library version number."
    135  1.1  christos   }
    136  1.1  christos 
    137  1.1  christos   define CFLAGS [proj-get-env CFLAGS {-O2}]
    138  1.1  christos   sqlite-munge-cflags
    139  1.1  christos 
    140  1.1  christos   #
    141  1.1  christos   # Add feature flags from legacy configure.ac which are not covered by
    142  1.1  christos   # --flags.
    143  1.1  christos   #
    144  1.1  christos   sqlite-add-feature-flag {
    145  1.1  christos     -DSQLITE_3_SUFFIX_ONLY=1
    146  1.1  christos     -DSQLITE_ENABLE_DESERIALIZE=1
    147  1.1  christos     -DSQLITE_ENABLE_DBPAGE_VTAB=1
    148  1.1  christos     -DSQLITE_ENABLE_BYTECODE_VTAB=1
    149  1.1  christos     -DSQLITE_ENABLE_DBSTAT_VTAB=1
    150  1.1  christos   }
    151  1.1  christos 
    152  1.1  christos   if {[opt-bool with-system-sqlite]} {
    153  1.1  christos     msg-result "Using system-level sqlite3."
    154  1.1  christos     teaish-cflags-add -DUSE_SYSTEM_SQLITE
    155  1.1  christos     teaish-ldflags-add -lsqlite3
    156  1.1  christos   } elseif {$::sqlite__Config(is-canonical)} {
    157  1.1  christos     teaish-cflags-add -I[teaish-get -dir]/..
    158  1.1  christos   }
    159  1.1  christos 
    160  1.1  christos   teaish-check-librt
    161  1.1  christos   teaish-check-libz
    162  1.1  christos   sqlite-handle-threadsafe
    163  1.1  christos   sqlite-handle-tempstore
    164  1.1  christos   sqlite-handle-load-extension
    165  1.1  christos   sqlite-handle-math
    166  1.1  christos   sqlite-handle-icu
    167  1.1  christos 
    168  1.1  christos   sqlite-handle-common-feature-flags; # must be late in the process
    169  1.1  christos }; # teaish-configure
    170  1.1  christos 
    171  1.1  christos define OPT_FEATURE_FLAGS {} ; # -DSQLITE_OMIT/ENABLE flags.
    172  1.1  christos #
    173  1.1  christos # Adds $args, if not empty, to OPT_FEATURE_FLAGS. This is intended only for holding
    174  1.1  christos # -DSQLITE_ENABLE/OMIT/... flags, but that is not enforced here.
    175  1.1  christos proc sqlite-add-feature-flag {args} {
    176  1.1  christos   if {"" ne $args} {
    177  1.1  christos     define-append OPT_FEATURE_FLAGS {*}$args
    178  1.1  christos   }
    179  1.1  christos }
    180  1.1  christos 
    181  1.1  christos #
    182  1.1  christos # Check for log(3) in libm and die with an error if it is not
    183  1.1  christos # found. $featureName should be the feature name which requires that
    184  1.1  christos # function (it's used only in error messages). defines LDFLAGS_MATH to
    185  1.1  christos # the required linker flags (which may be empty even if the math APIs
    186  1.1  christos # are found, depending on the OS).
    187  1.1  christos proc sqlite-affirm-have-math {featureName} {
    188  1.1  christos   if {"" eq [get-define LDFLAGS_MATH ""]} {
    189  1.1  christos     if {![msg-quiet proj-check-function-in-lib log m]} {
    190  1.1  christos       user-error "Missing math APIs for $featureName"
    191  1.1  christos     }
    192  1.1  christos     set lfl [get-define lib_log ""]
    193  1.1  christos     undefine lib_log
    194  1.1  christos     if {"" ne $lfl} {
    195  1.1  christos       user-notice "Forcing requirement of $lfl for $featureName"
    196  1.1  christos     }
    197  1.1  christos     define LDFLAGS_MATH $lfl
    198  1.1  christos     teaish-ldflags-prepend $lfl
    199  1.1  christos   }
    200  1.1  christos }
    201  1.1  christos 
    202  1.1  christos #
    203  1.1  christos # Handle various SQLITE_ENABLE/OMIT_... feature flags.
    204  1.1  christos proc sqlite-handle-common-feature-flags {} {
    205  1.1  christos   msg-result "Feature flags..."
    206  1.1  christos   if {![opt-bool all]} {
    207  1.1  christos     # Special handling for --disable-all
    208  1.1  christos     foreach flag $::sqlite__Config(all-flag-enables) {
    209  1.1  christos       if {![proj-opt-was-provided $flag]} {
    210  1.1  christos         proj-opt-set $flag 0
    211  1.1  christos       }
    212  1.1  christos     }
    213  1.1  christos   }
    214  1.1  christos   foreach {boolFlag featureFlag ifSetEvalThis} [proj-strip-hash-comments {
    215  1.1  christos     all         {} {
    216  1.1  christos       # The 'all' option must be first in this list.  This impl makes
    217  1.1  christos       # an effort to only apply flags which the user did not already
    218  1.1  christos       # apply, so that combinations like (--all --disable-geopoly)
    219  1.1  christos       # will indeed disable geopoly. There are corner cases where
    220  1.1  christos       # flags which depend on each other will behave in non-intuitive
    221  1.1  christos       # ways:
    222  1.1  christos       #
    223  1.1  christos       # --all --disable-rtree
    224  1.1  christos       #
    225  1.1  christos       # Will NOT disable geopoly, though geopoly depends on rtree.
    226  1.1  christos       # The --geopoly flag, though, will automatically re-enable
    227  1.1  christos       # --rtree, so --disable-rtree won't actually disable anything in
    228  1.1  christos       # that case.
    229  1.1  christos       foreach k $::sqlite__Config(all-flag-enables) {
    230  1.1  christos         if {![proj-opt-was-provided $k]} {
    231  1.1  christos           proj-opt-set $k 1
    232  1.1  christos         }
    233  1.1  christos       }
    234  1.1  christos     }
    235  1.1  christos     fts3         -DSQLITE_ENABLE_FTS3    {sqlite-affirm-have-math fts3}
    236  1.1  christos     fts4         -DSQLITE_ENABLE_FTS4    {sqlite-affirm-have-math fts4}
    237  1.1  christos     fts5         -DSQLITE_ENABLE_FTS5    {sqlite-affirm-have-math fts5}
    238  1.1  christos     geopoly      -DSQLITE_ENABLE_GEOPOLY {proj-opt-set rtree}
    239  1.1  christos     rtree        -DSQLITE_ENABLE_RTREE   {}
    240  1.1  christos     session      {-DSQLITE_ENABLE_SESSION -DSQLITE_ENABLE_PREUPDATE_HOOK} {}
    241  1.1  christos     update-limit -DSQLITE_ENABLE_UPDATE_DELETE_LIMIT {}
    242  1.1  christos     scanstatus     -DSQLITE_ENABLE_STMT_SCANSTATUS {}
    243  1.1  christos   }] {
    244  1.1  christos     if {$boolFlag ni $::autosetup(options)} {
    245  1.1  christos       # Skip flags which are in the canonical build but not
    246  1.1  christos       # the autoconf bundle.
    247  1.1  christos       continue
    248  1.1  christos     }
    249  1.1  christos     proj-if-opt-truthy $boolFlag {
    250  1.1  christos       sqlite-add-feature-flag $featureFlag
    251  1.1  christos       if {0 != [eval $ifSetEvalThis] && "all" ne $boolFlag} {
    252  1.1  christos         msg-result "  + $boolFlag"
    253  1.1  christos       }
    254  1.1  christos     } {
    255  1.1  christos       if {"all" ne $boolFlag} {
    256  1.1  christos         msg-result "  - $boolFlag"
    257  1.1  christos       }
    258  1.1  christos     }
    259  1.1  christos   }
    260  1.1  christos   #
    261  1.1  christos   # Invert the above loop's logic for some SQLITE_OMIT_...  cases. If
    262  1.1  christos   # config option $boolFlag is false, [sqlite-add-feature-flag
    263  1.1  christos   # $featureFlag], where $featureFlag is intended to be
    264  1.1  christos   # -DSQLITE_OMIT_...
    265  1.1  christos   foreach {boolFlag featureFlag} {
    266  1.1  christos     json        -DSQLITE_OMIT_JSON
    267  1.1  christos   } {
    268  1.1  christos     if {[proj-opt-truthy $boolFlag]} {
    269  1.1  christos       msg-result "  + $boolFlag"
    270  1.1  christos     } else {
    271  1.1  christos       sqlite-add-feature-flag $featureFlag
    272  1.1  christos       msg-result "  - $boolFlag"
    273  1.1  christos     }
    274  1.1  christos   }
    275  1.1  christos 
    276  1.1  christos   ##
    277  1.1  christos   # Remove duplicates from the final feature flag sets and show them
    278  1.1  christos   # to the user.
    279  1.1  christos   set oFF [get-define OPT_FEATURE_FLAGS]
    280  1.1  christos   if {"" ne $oFF} {
    281  1.1  christos     define OPT_FEATURE_FLAGS [lsort -unique $oFF]
    282  1.1  christos     msg-result "Library feature flags: [get-define OPT_FEATURE_FLAGS]"
    283  1.1  christos   }
    284  1.1  christos   if {[lsearch [get-define TARGET_DEBUG ""] -DSQLITE_DEBUG=1] > -1} {
    285  1.1  christos     msg-result "Note: this is a debug build, so performance will suffer."
    286  1.1  christos   }
    287  1.1  christos   teaish-cflags-add -define OPT_FEATURE_FLAGS
    288  1.1  christos }; # sqlite-handle-common-feature-flags
    289  1.1  christos 
    290  1.1  christos #
    291  1.1  christos # If --enable-threadsafe is set, this adds -DSQLITE_THREADSAFE=1 to
    292  1.1  christos # OPT_FEATURE_FLAGS and sets LDFLAGS_PTHREAD to the linker flags
    293  1.1  christos # needed for linking pthread (possibly an empty string). If
    294  1.1  christos # --enable-threadsafe is not set, adds -DSQLITE_THREADSAFE=0 to
    295  1.1  christos # OPT_FEATURE_FLAGS and sets LDFLAGS_PTHREAD to an empty string.
    296  1.1  christos #
    297  1.1  christos # It prepends the flags to the global LDFLAGS.
    298  1.1  christos proc sqlite-handle-threadsafe {} {
    299  1.1  christos   msg-checking "Support threadsafe operation? "
    300  1.1  christos   define LDFLAGS_PTHREAD ""
    301  1.1  christos   set enable 0
    302  1.1  christos   if {[proj-opt-was-provided threadsafe]} {
    303  1.1  christos     proj-if-opt-truthy threadsafe {
    304  1.1  christos       if {[proj-check-function-in-lib pthread_create pthread]
    305  1.1  christos           && [proj-check-function-in-lib pthread_mutexattr_init pthread]} {
    306  1.1  christos         incr enable
    307  1.1  christos         set ldf [get-define lib_pthread_create]
    308  1.1  christos         define LDFLAGS_PTHREAD $ldf
    309  1.1  christos         teaish-ldflags-prepend $ldf
    310  1.1  christos         undefine lib_pthread_create
    311  1.1  christos         undefine lib_pthread_mutexattr_init
    312  1.1  christos       } else {
    313  1.1  christos         user-error "Missing required pthread libraries. Use --disable-threadsafe to disable this check."
    314  1.1  christos       }
    315  1.1  christos       # Recall that LDFLAGS_PTHREAD might be empty even if pthreads if
    316  1.1  christos       # found because it's in -lc on some platforms.
    317  1.1  christos     } {
    318  1.1  christos       msg-result "Disabled using --disable-threadsafe"
    319  1.1  christos     }
    320  1.1  christos   } else {
    321  1.1  christos     #
    322  1.1  christos     # If user does not specify --[disable-]threadsafe then select a
    323  1.1  christos     # default based on whether it looks like Tcl has threading
    324  1.1  christos     # support.
    325  1.1  christos     #
    326  1.1  christos     catch {
    327  1.1  christos       scan [exec echo {puts [tcl::pkgconfig get threaded]} | [get-define TCLSH_CMD]] \
    328  1.1  christos         %d enable
    329  1.1  christos     }
    330  1.1  christos     if {$enable} {
    331  1.1  christos       set flagName "--threadsafe"
    332  1.1  christos       set lblAbled "enabled"
    333  1.1  christos       msg-result yes
    334  1.1  christos     } else {
    335  1.1  christos       set flagName "--disable-threadsafe"
    336  1.1  christos       set lblAbled "disabled"
    337  1.1  christos       msg-result no
    338  1.1  christos     }
    339  1.1  christos     msg-result "Defaulting to ${flagName} because Tcl has threading ${lblAbled}."
    340  1.1  christos     # ^^^ We (probably) don't need to link against -lpthread in the
    341  1.1  christos     # is-enabled case. We might in the case of static linking. Unsure.
    342  1.1  christos   }
    343  1.1  christos   sqlite-add-feature-flag -DSQLITE_THREADSAFE=${enable}
    344  1.1  christos   return $enable
    345  1.1  christos }
    346  1.1  christos 
    347  1.1  christos #
    348  1.1  christos # Handles the --enable-load-extension flag. Returns 1 if the support
    349  1.1  christos # is enabled, else 0. If support for that feature is not found, a
    350  1.1  christos # fatal error is triggered if --enable-load-extension is explicitly
    351  1.1  christos # provided, else a loud warning is instead emitted. If
    352  1.1  christos # --disable-load-extension is used, no check is performed.
    353  1.1  christos #
    354  1.1  christos # Makes the following environment changes:
    355  1.1  christos #
    356  1.1  christos # - defines LDFLAGS_DLOPEN to any linker flags needed for this
    357  1.1  christos #   feature.  It may legally be empty on some systems where dlopen()
    358  1.1  christos #   is in libc.
    359  1.1  christos #
    360  1.1  christos # - If the feature is not available, adds
    361  1.1  christos #   -DSQLITE_OMIT_LOAD_EXTENSION=1 to the feature flags list.
    362  1.1  christos proc sqlite-handle-load-extension {} {
    363  1.1  christos   define LDFLAGS_DLOPEN ""
    364  1.1  christos   set found 0
    365  1.1  christos   proj-if-opt-truthy load-extension {
    366  1.1  christos     set found [proj-check-function-in-lib dlopen dl]
    367  1.1  christos     if {$found} {
    368  1.1  christos       set ldf [get-define lib_dlopen]
    369  1.1  christos       define LDFLAGS_DLOPEN $ldf
    370  1.1  christos       teaish-ldflags-prepend $ldf
    371  1.1  christos       undefine lib_dlopen
    372  1.1  christos     } else {
    373  1.1  christos       if {[proj-opt-was-provided load-extension]} {
    374  1.1  christos         # Explicit --enable-load-extension: fail if not found
    375  1.1  christos         proj-indented-notice -error {
    376  1.1  christos           --enable-load-extension was provided but dlopen()
    377  1.1  christos           not found. Use --disable-load-extension to bypass this
    378  1.1  christos           check.
    379  1.1  christos         }
    380  1.1  christos       } else {
    381  1.1  christos         # It was implicitly enabled: warn if not found
    382  1.1  christos         proj-indented-notice {
    383  1.1  christos           WARNING: dlopen() not found, so loadable module support will
    384  1.1  christos           be disabled. Use --disable-load-extension to bypass this
    385  1.1  christos           check.
    386  1.1  christos         }
    387  1.1  christos       }
    388  1.1  christos     }
    389  1.1  christos   }
    390  1.1  christos   if {$found} {
    391  1.1  christos     msg-result "Loadable extension support enabled."
    392  1.1  christos   } else {
    393  1.1  christos     msg-result "Disabling loadable extension support. Use --enable-load-extension to enable them."
    394  1.1  christos     sqlite-add-feature-flag -DSQLITE_OMIT_LOAD_EXTENSION=1
    395  1.1  christos   }
    396  1.1  christos   return $found
    397  1.1  christos }
    398  1.1  christos 
    399  1.1  christos #
    400  1.1  christos # ICU - International Components for Unicode
    401  1.1  christos #
    402  1.1  christos # Handles these flags:
    403  1.1  christos #
    404  1.1  christos #  --with-icu-ldflags=LDFLAGS
    405  1.1  christos #  --with-icu-cflags=CFLAGS
    406  1.1  christos #  --with-icu-config[=auto | pkg-config | /path/to/icu-config]
    407  1.1  christos #  --enable-icu-collations
    408  1.1  christos #
    409  1.1  christos # --with-icu-config values:
    410  1.1  christos #
    411  1.1  christos #   - auto: use the first one of (pkg-config, icu-config) found on the
    412  1.1  christos #     system.
    413  1.1  christos #   - pkg-config: use only pkg-config to determine flags
    414  1.1  christos #   - /path/to/icu-config: use that to determine flags
    415  1.1  christos #
    416  1.1  christos # If --with-icu-config is used as neither pkg-config nor icu-config
    417  1.1  christos # are found, fail fatally.
    418  1.1  christos #
    419  1.1  christos # If both --with-icu-ldflags and --with-icu-config are provided, they
    420  1.1  christos # are cumulative.  If neither are provided, icu-collations is not
    421  1.1  christos # honored and a warning is emitted if it is provided.
    422  1.1  christos #
    423  1.1  christos # Design note: though we could automatically enable ICU if the
    424  1.1  christos # icu-config binary or (pkg-config icu-io) are found, we specifically
    425  1.1  christos # do not. ICU is always an opt-in feature.
    426  1.1  christos proc sqlite-handle-icu {} {
    427  1.1  christos   define LDFLAGS_LIBICU [join [opt-val with-icu-ldflags ""]]
    428  1.1  christos   define CFLAGS_LIBICU [join [opt-val with-icu-cflags ""]]
    429  1.1  christos   if {[proj-opt-was-provided with-icu-config]} {
    430  1.1  christos     msg-result "Checking for ICU support..."
    431  1.1  christos     set icuConfigBin [opt-val with-icu-config]
    432  1.1  christos     set tryIcuConfigBin 1; # set to 0 if we end up using pkg-config
    433  1.1  christos     if {$icuConfigBin in {auto pkg-config}} {
    434  1.1  christos       uplevel 3 { use pkg-config }
    435  1.1  christos       if {[pkg-config-init 0] && [pkg-config icu-io]} {
    436  1.1  christos         # Maintenance reminder: historical docs say to use both of
    437  1.1  christos         # (icu-io, icu-uc). icu-uc lacks a required lib and icu-io has
    438  1.1  christos         # all of them on tested OSes.
    439  1.1  christos         set tryIcuConfigBin 0
    440  1.1  christos         define LDFLAGS_LIBICU [get-define PKG_ICU_IO_LDFLAGS]
    441  1.1  christos         define-append LDFLAGS_LIBICU [get-define PKG_ICU_IO_LIBS]
    442  1.1  christos         define CFLAGS_LIBICU [get-define PKG_ICU_IO_CFLAGS]
    443  1.1  christos       } elseif {"pkg-config" eq $icuConfigBin} {
    444  1.1  christos         proj-fatal "pkg-config cannot find package icu-io"
    445  1.1  christos       } else {
    446  1.1  christos         proj-assert {"auto" eq $icuConfigBin}
    447  1.1  christos       }
    448  1.1  christos     }
    449  1.1  christos     if {$tryIcuConfigBin} {
    450  1.1  christos       if {"auto" eq $icuConfigBin} {
    451  1.1  christos         set icuConfigBin [proj-first-bin-of \
    452  1.1  christos                             /usr/local/bin/icu-config \
    453  1.1  christos                             /usr/bin/icu-config]
    454  1.1  christos         if {"" eq $icuConfigBin} {
    455  1.1  christos           proj-indented-notice -error {
    456  1.1  christos             --with-icu-config=auto cannot find (pkg-config icu-io) or icu-config binary.
    457  1.1  christos             On Ubuntu-like systems try:
    458  1.1  christos             --with-icu-ldflags='-licui18n -licuuc -licudata'
    459  1.1  christos           }
    460  1.1  christos         }
    461  1.1  christos       }
    462  1.1  christos       if {[file-isexec $icuConfigBin]} {
    463  1.1  christos         set x [exec $icuConfigBin --ldflags]
    464  1.1  christos         if {"" eq $x} {
    465  1.1  christos           proj-indented-notice -error \
    466  1.1  christos             [subst {
    467  1.1  christos               $icuConfigBin --ldflags returned no data.
    468  1.1  christos               On Ubuntu-like systems try:
    469  1.1  christos               --with-icu-ldflags='-licui18n -licuuc -licudata'
    470  1.1  christos             }]
    471  1.1  christos         }
    472  1.1  christos         define-append LDFLAGS_LIBICU $x
    473  1.1  christos         set x [exec $icuConfigBin --cppflags]
    474  1.1  christos         define-append CFLAGS_LIBICU $x
    475  1.1  christos       } else {
    476  1.1  christos         proj-fatal "--with-icu-config=$icuConfigBin does not refer to an executable"
    477  1.1  christos       }
    478  1.1  christos     }
    479  1.1  christos   }
    480  1.1  christos   set ldflags [define LDFLAGS_LIBICU [string trim [get-define LDFLAGS_LIBICU]]]
    481  1.1  christos   set cflags [define CFLAGS_LIBICU [string trim [get-define CFLAGS_LIBICU]]]
    482  1.1  christos   if {"" ne $ldflags} {
    483  1.1  christos     sqlite-add-feature-flag -DSQLITE_ENABLE_ICU
    484  1.1  christos     msg-result "Enabling ICU support with flags: $ldflags $cflags"
    485  1.1  christos     if {[opt-bool icu-collations]} {
    486  1.1  christos       msg-result "Enabling ICU collations."
    487  1.1  christos       sqlite-add-feature-flag -DSQLITE_ENABLE_ICU_COLLATIONS
    488  1.1  christos     }
    489  1.1  christos     teaish-ldflags-prepend $ldflags
    490  1.1  christos     teaish-cflags-add $cflags
    491  1.1  christos   } elseif {[opt-bool icu-collations]} {
    492  1.1  christos     proj-warn "ignoring --enable-icu-collations because neither --with-icu-ldflags nor --with-icu-config provided any linker flags"
    493  1.1  christos   } else {
    494  1.1  christos     msg-result "ICU support is disabled."
    495  1.1  christos   }
    496  1.1  christos }; # sqlite-handle-icu
    497  1.1  christos 
    498  1.1  christos 
    499  1.1  christos #
    500  1.1  christos # Handles the --with-tempstore flag.
    501  1.1  christos #
    502  1.1  christos # The test fixture likes to set SQLITE_TEMP_STORE on its own, so do
    503  1.1  christos # not set that feature flag unless it was explicitly provided to the
    504  1.1  christos # configure script.
    505  1.1  christos proc sqlite-handle-tempstore {} {
    506  1.1  christos   if {[proj-opt-was-provided with-tempstore]} {
    507  1.1  christos     set ts [opt-val with-tempstore no]
    508  1.1  christos     set tsn 1
    509  1.1  christos     msg-checking "Use an in-RAM database for temporary tables? "
    510  1.1  christos     switch -exact -- $ts {
    511  1.1  christos       never  { set tsn 0 }
    512  1.1  christos       no     { set tsn 1 }
    513  1.1  christos       yes    { set tsn 2 }
    514  1.1  christos       always { set tsn 3 }
    515  1.1  christos       default {
    516  1.1  christos         user-error "Invalid --with-tempstore value '$ts'. Use one of: never, no, yes, always"
    517  1.1  christos       }
    518  1.1  christos     }
    519  1.1  christos     msg-result $ts
    520  1.1  christos     sqlite-add-feature-flag -DSQLITE_TEMP_STORE=$tsn
    521  1.1  christos   }
    522  1.1  christos }
    523  1.1  christos 
    524  1.1  christos #
    525  1.1  christos # Handles the --enable-math flag.
    526  1.1  christos proc sqlite-handle-math {} {
    527  1.1  christos   proj-if-opt-truthy math {
    528  1.1  christos     if {![proj-check-function-in-lib ceil m]} {
    529  1.1  christos       user-error "Cannot find libm functions. Use --disable-math to bypass this."
    530  1.1  christos     }
    531  1.1  christos     set lfl [get-define lib_ceil]
    532  1.1  christos     undefine lib_ceil
    533  1.1  christos     define LDFLAGS_MATH $lfl
    534  1.1  christos     teaish-ldflags-prepend $lfl
    535  1.1  christos     sqlite-add-feature-flag -DSQLITE_ENABLE_MATH_FUNCTIONS
    536  1.1  christos     msg-result "Enabling math SQL functions"
    537  1.1  christos   } {
    538  1.1  christos     define LDFLAGS_MATH ""
    539  1.1  christos     msg-result "Disabling math SQL functions"
    540  1.1  christos   }
    541  1.1  christos }
    542  1.1  christos 
    543  1.1  christos #
    544  1.1  christos # Move -DSQLITE_OMIT... and -DSQLITE_ENABLE... flags from CFLAGS and
    545  1.1  christos # CPPFLAGS to OPT_FEATURE_FLAGS and remove them from BUILD_CFLAGS.
    546  1.1  christos proc sqlite-munge-cflags {} {
    547  1.1  christos   # Move CFLAGS and CPPFLAGS entries matching -DSQLITE_OMIT* and
    548  1.1  christos   # -DSQLITE_ENABLE* to OPT_FEATURE_FLAGS. This behavior is derived
    549  1.1  christos   # from the pre-3.48 build.
    550  1.1  christos   #
    551  1.1  christos   # If any configure flags for features are in conflict with
    552  1.1  christos   # CFLAGS/CPPFLAGS-specified feature flags, all bets are off.  There
    553  1.1  christos   # are no guarantees about which one will take precedence.
    554  1.1  christos   foreach flagDef {CFLAGS CPPFLAGS} {
    555  1.1  christos     set tmp ""
    556  1.1  christos     foreach cf [get-define $flagDef ""] {
    557  1.1  christos       switch -glob -- $cf {
    558  1.1  christos         -DSQLITE_OMIT* -
    559  1.1  christos         -DSQLITE_ENABLE* {
    560  1.1  christos           sqlite-add-feature-flag $cf
    561  1.1  christos         }
    562  1.1  christos         default {
    563  1.1  christos           lappend tmp $cf
    564  1.1  christos         }
    565  1.1  christos       }
    566  1.1  christos     }
    567  1.1  christos     define $flagDef $tmp
    568  1.1  christos   }
    569  1.1  christos }
    570