diff third_party/sqlite3/tea/teaish.tcl @ 173:827c6ac504cd hg-web

Merged in default here.
author MrJuneJune <me@mrjunejune.com>
date Mon, 19 Jan 2026 18:59:10 -0800
parents 589bab390fb4
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/third_party/sqlite3/tea/teaish.tcl	Mon Jan 19 18:59:10 2026 -0800
@@ -0,0 +1,569 @@
+# Teaish configure script for the SQLite Tcl extension
+
+#
+# State for disparate config-time pieces.
+#
+array set sqlite__Config [proj-strip-hash-comments {
+  #
+  # The list of feature --flags which the --all flag implies. This
+  # requires special handling in a few places.
+  #
+  all-flag-enables {fts3 fts4 fts5 rtree geopoly}
+
+  # >0 if building in the canonical tree. -1=undetermined
+  is-canonical -1
+}]
+
+#
+# Set up the package info for teaish...
+#
+apply {{dir} {
+  # Figure out the version number...
+  set version ""
+  if {[file exists $dir/../VERSION]} {
+    # The canonical SQLite TEA(ish) build
+    set version [proj-file-content -trim $dir/../VERSION]
+    set ::sqlite__Config(is-canonical) 1
+    set distname sqlite-tcl
+  } elseif {[file exists $dir/generic/tclsqlite3.c]} {
+    # The copy from the teaish tree, used as a dev/test bed before
+    # updating SQLite's tree.
+    set ::sqlite__Config(is-canonical) 0
+    set fd [open $dir/generic/tclsqlite3.c rb]
+    while {[gets $fd line] >=0} {
+      if {[regexp {^#define[ ]+SQLITE_VERSION[ ]+"(3.+)"} \
+             $line - version]} {
+        set distname sqlite-teaish
+        break
+      }
+    }
+    close $fd
+  }
+
+  if {"" eq $version} {
+    proj-fatal "Cannot determine the SQLite version number"
+  }
+
+  proj-assert {$::sqlite__Config(is-canonical) > -1}
+  proj-assert {[string match 3.*.* $version]} \
+    "Unexpected SQLite version: $version"
+
+  set pragmas {}
+  if {$::sqlite__Config(is-canonical)} {
+    # Disable "make dist" in the canonical tree.  That tree is
+    # generated from several pieces and creating/testing working
+    # "dist" rules for that sub-build currently feels unnecessary. The
+    # copy in the teaish tree, though, should be able to "make dist".
+    lappend pragmas no-dist
+  } else {
+    lappend pragmas full-dist
+  }
+
+  teaish-pkginfo-set -vars {
+    -name sqlite
+    -name.pkg sqlite3
+    -version $version
+    -name.dist $distname
+    -libDir sqlite$version
+    -pragmas $pragmas
+    -src generic/tclsqlite3.c
+  }
+  # We should also have:
+  #    -vsatisfies 8.6-
+  # But at least one platform is failing this vsatisfies check
+  # for no apparent reason:
+  # https://sqlite.org/forum/forumpost/fde857fb8101a4be
+}} [teaish-get -dir]
+
+
+#
+# Must return either an empty string or a list in the form accepted by
+# autosetup's [options] function.
+#
+proc teaish-options {} {
+  # These flags and defaults mostly derive from the historical TEA
+  # build.  Some, like ICU, are taken from the canonical SQLite tree.
+  return [subst -nocommands -nobackslashes {
+    with-system-sqlite=0
+      => {Use the system-level SQLite instead of the copy in this tree.
+          Also requires use of --override-sqlite-version so that the build
+          knows what version number to associate with the system-level SQLite.}
+    override-sqlite-version:VERSION
+      => {For use with --with-system-sqlite to set the version number.}
+    threadsafe=1         => {Disable mutexing}
+    with-tempstore:=no   => {Use an in-RAM database for temporary tables: never,no,yes,always}
+    load-extension=0     => {Enable loading of external extensions}
+    math=1               => {Disable math functions}
+    json=1               => {Disable JSON functions}
+    fts3                 => {Enable the FTS3 extension}
+    fts4                 => {Enable the FTS4 extension}
+    fts5                 => {Enable the FTS5 extension}
+    update-limit         => {Enable the UPDATE/DELETE LIMIT clause}
+    geopoly              => {Enable the GEOPOLY extension}
+    rtree                => {Enable the RTREE extension}
+    session              => {Enable the SESSION extension}
+    all=1                => {Disable $::sqlite__Config(all-flag-enables)}
+    with-icu-ldflags:LDFLAGS
+      => {Enable SQLITE_ENABLE_ICU and add the given linker flags for the
+          ICU libraries. e.g. on Ubuntu systems, try '-licui18n -licuuc -licudata'.}
+    with-icu-cflags:CFLAGS
+      => {Apply extra CFLAGS/CPPFLAGS necessary for building with ICU.
+          e.g. -I/usr/local/include}
+    with-icu-config:=auto
+      => {Enable SQLITE_ENABLE_ICU. Value must be one of: auto, pkg-config,
+          /path/to/icu-config}
+    icu-collations=0
+      => {Enable SQLITE_ENABLE_ICU_COLLATIONS. Requires --with-icu-ldflags=...
+          or --with-icu-config}
+  }]
+}
+
+#
+# Gets called by tea-configure-core. Must perform any configuration
+# work needed for this extension.
+#
+proc teaish-configure {} {
+  use teaish/feature
+
+  if {[proj-opt-was-provided override-sqlite-version]} {
+    teaish-pkginfo-set -version [opt-val override-sqlite-version]
+    proj-warn "overriding sqlite version number:" [teaish-pkginfo-get -version]
+  } elseif {[proj-opt-was-provided with-system-sqlite]
+            && [opt-val with-system-sqlite] ne "0"} {
+    proj-fatal "when using --with-system-sqlite also use" \
+      "--override-sqlite-version to specify a library version number."
+  }
+
+  define CFLAGS [proj-get-env CFLAGS {-O2}]
+  sqlite-munge-cflags
+
+  #
+  # Add feature flags from legacy configure.ac which are not covered by
+  # --flags.
+  #
+  sqlite-add-feature-flag {
+    -DSQLITE_3_SUFFIX_ONLY=1
+    -DSQLITE_ENABLE_DESERIALIZE=1
+    -DSQLITE_ENABLE_DBPAGE_VTAB=1
+    -DSQLITE_ENABLE_BYTECODE_VTAB=1
+    -DSQLITE_ENABLE_DBSTAT_VTAB=1
+  }
+
+  if {[opt-bool with-system-sqlite]} {
+    msg-result "Using system-level sqlite3."
+    teaish-cflags-add -DUSE_SYSTEM_SQLITE
+    teaish-ldflags-add -lsqlite3
+  } elseif {$::sqlite__Config(is-canonical)} {
+    teaish-cflags-add -I[teaish-get -dir]/..
+  }
+
+  teaish-check-librt
+  teaish-check-libz
+  sqlite-handle-threadsafe
+  sqlite-handle-tempstore
+  sqlite-handle-load-extension
+  sqlite-handle-math
+  sqlite-handle-icu
+
+  sqlite-handle-common-feature-flags; # must be late in the process
+}; # teaish-configure
+
+define OPT_FEATURE_FLAGS {} ; # -DSQLITE_OMIT/ENABLE flags.
+#
+# Adds $args, if not empty, to OPT_FEATURE_FLAGS. This is intended only for holding
+# -DSQLITE_ENABLE/OMIT/... flags, but that is not enforced here.
+proc sqlite-add-feature-flag {args} {
+  if {"" ne $args} {
+    define-append OPT_FEATURE_FLAGS {*}$args
+  }
+}
+
+#
+# Check for log(3) in libm and die with an error if it is not
+# found. $featureName should be the feature name which requires that
+# function (it's used only in error messages). defines LDFLAGS_MATH to
+# the required linker flags (which may be empty even if the math APIs
+# are found, depending on the OS).
+proc sqlite-affirm-have-math {featureName} {
+  if {"" eq [get-define LDFLAGS_MATH ""]} {
+    if {![msg-quiet proj-check-function-in-lib log m]} {
+      user-error "Missing math APIs for $featureName"
+    }
+    set lfl [get-define lib_log ""]
+    undefine lib_log
+    if {"" ne $lfl} {
+      user-notice "Forcing requirement of $lfl for $featureName"
+    }
+    define LDFLAGS_MATH $lfl
+    teaish-ldflags-prepend $lfl
+  }
+}
+
+#
+# Handle various SQLITE_ENABLE/OMIT_... feature flags.
+proc sqlite-handle-common-feature-flags {} {
+  msg-result "Feature flags..."
+  if {![opt-bool all]} {
+    # Special handling for --disable-all
+    foreach flag $::sqlite__Config(all-flag-enables) {
+      if {![proj-opt-was-provided $flag]} {
+        proj-opt-set $flag 0
+      }
+    }
+  }
+  foreach {boolFlag featureFlag ifSetEvalThis} [proj-strip-hash-comments {
+    all         {} {
+      # The 'all' option must be first in this list.  This impl makes
+      # an effort to only apply flags which the user did not already
+      # apply, so that combinations like (--all --disable-geopoly)
+      # will indeed disable geopoly. There are corner cases where
+      # flags which depend on each other will behave in non-intuitive
+      # ways:
+      #
+      # --all --disable-rtree
+      #
+      # Will NOT disable geopoly, though geopoly depends on rtree.
+      # The --geopoly flag, though, will automatically re-enable
+      # --rtree, so --disable-rtree won't actually disable anything in
+      # that case.
+      foreach k $::sqlite__Config(all-flag-enables) {
+        if {![proj-opt-was-provided $k]} {
+          proj-opt-set $k 1
+        }
+      }
+    }
+    fts3         -DSQLITE_ENABLE_FTS3    {sqlite-affirm-have-math fts3}
+    fts4         -DSQLITE_ENABLE_FTS4    {sqlite-affirm-have-math fts4}
+    fts5         -DSQLITE_ENABLE_FTS5    {sqlite-affirm-have-math fts5}
+    geopoly      -DSQLITE_ENABLE_GEOPOLY {proj-opt-set rtree}
+    rtree        -DSQLITE_ENABLE_RTREE   {}
+    session      {-DSQLITE_ENABLE_SESSION -DSQLITE_ENABLE_PREUPDATE_HOOK} {}
+    update-limit -DSQLITE_ENABLE_UPDATE_DELETE_LIMIT {}
+    scanstatus     -DSQLITE_ENABLE_STMT_SCANSTATUS {}
+  }] {
+    if {$boolFlag ni $::autosetup(options)} {
+      # Skip flags which are in the canonical build but not
+      # the autoconf bundle.
+      continue
+    }
+    proj-if-opt-truthy $boolFlag {
+      sqlite-add-feature-flag $featureFlag
+      if {0 != [eval $ifSetEvalThis] && "all" ne $boolFlag} {
+        msg-result "  + $boolFlag"
+      }
+    } {
+      if {"all" ne $boolFlag} {
+        msg-result "  - $boolFlag"
+      }
+    }
+  }
+  #
+  # Invert the above loop's logic for some SQLITE_OMIT_...  cases. If
+  # config option $boolFlag is false, [sqlite-add-feature-flag
+  # $featureFlag], where $featureFlag is intended to be
+  # -DSQLITE_OMIT_...
+  foreach {boolFlag featureFlag} {
+    json        -DSQLITE_OMIT_JSON
+  } {
+    if {[proj-opt-truthy $boolFlag]} {
+      msg-result "  + $boolFlag"
+    } else {
+      sqlite-add-feature-flag $featureFlag
+      msg-result "  - $boolFlag"
+    }
+  }
+
+  ##
+  # Remove duplicates from the final feature flag sets and show them
+  # to the user.
+  set oFF [get-define OPT_FEATURE_FLAGS]
+  if {"" ne $oFF} {
+    define OPT_FEATURE_FLAGS [lsort -unique $oFF]
+    msg-result "Library feature flags: [get-define OPT_FEATURE_FLAGS]"
+  }
+  if {[lsearch [get-define TARGET_DEBUG ""] -DSQLITE_DEBUG=1] > -1} {
+    msg-result "Note: this is a debug build, so performance will suffer."
+  }
+  teaish-cflags-add -define OPT_FEATURE_FLAGS
+}; # sqlite-handle-common-feature-flags
+
+#
+# If --enable-threadsafe is set, this adds -DSQLITE_THREADSAFE=1 to
+# OPT_FEATURE_FLAGS and sets LDFLAGS_PTHREAD to the linker flags
+# needed for linking pthread (possibly an empty string). If
+# --enable-threadsafe is not set, adds -DSQLITE_THREADSAFE=0 to
+# OPT_FEATURE_FLAGS and sets LDFLAGS_PTHREAD to an empty string.
+#
+# It prepends the flags to the global LDFLAGS.
+proc sqlite-handle-threadsafe {} {
+  msg-checking "Support threadsafe operation? "
+  define LDFLAGS_PTHREAD ""
+  set enable 0
+  if {[proj-opt-was-provided threadsafe]} {
+    proj-if-opt-truthy threadsafe {
+      if {[proj-check-function-in-lib pthread_create pthread]
+          && [proj-check-function-in-lib pthread_mutexattr_init pthread]} {
+        incr enable
+        set ldf [get-define lib_pthread_create]
+        define LDFLAGS_PTHREAD $ldf
+        teaish-ldflags-prepend $ldf
+        undefine lib_pthread_create
+        undefine lib_pthread_mutexattr_init
+      } else {
+        user-error "Missing required pthread libraries. Use --disable-threadsafe to disable this check."
+      }
+      # Recall that LDFLAGS_PTHREAD might be empty even if pthreads if
+      # found because it's in -lc on some platforms.
+    } {
+      msg-result "Disabled using --disable-threadsafe"
+    }
+  } else {
+    #
+    # If user does not specify --[disable-]threadsafe then select a
+    # default based on whether it looks like Tcl has threading
+    # support.
+    #
+    catch {
+      scan [exec echo {puts [tcl::pkgconfig get threaded]} | [get-define TCLSH_CMD]] \
+        %d enable
+    }
+    if {$enable} {
+      set flagName "--threadsafe"
+      set lblAbled "enabled"
+      msg-result yes
+    } else {
+      set flagName "--disable-threadsafe"
+      set lblAbled "disabled"
+      msg-result no
+    }
+    msg-result "Defaulting to ${flagName} because Tcl has threading ${lblAbled}."
+    # ^^^ We (probably) don't need to link against -lpthread in the
+    # is-enabled case. We might in the case of static linking. Unsure.
+  }
+  sqlite-add-feature-flag -DSQLITE_THREADSAFE=${enable}
+  return $enable
+}
+
+#
+# Handles the --enable-load-extension flag. Returns 1 if the support
+# is enabled, else 0. If support for that feature is not found, a
+# fatal error is triggered if --enable-load-extension is explicitly
+# provided, else a loud warning is instead emitted. If
+# --disable-load-extension is used, no check is performed.
+#
+# Makes the following environment changes:
+#
+# - defines LDFLAGS_DLOPEN to any linker flags needed for this
+#   feature.  It may legally be empty on some systems where dlopen()
+#   is in libc.
+#
+# - If the feature is not available, adds
+#   -DSQLITE_OMIT_LOAD_EXTENSION=1 to the feature flags list.
+proc sqlite-handle-load-extension {} {
+  define LDFLAGS_DLOPEN ""
+  set found 0
+  proj-if-opt-truthy load-extension {
+    set found [proj-check-function-in-lib dlopen dl]
+    if {$found} {
+      set ldf [get-define lib_dlopen]
+      define LDFLAGS_DLOPEN $ldf
+      teaish-ldflags-prepend $ldf
+      undefine lib_dlopen
+    } else {
+      if {[proj-opt-was-provided load-extension]} {
+        # Explicit --enable-load-extension: fail if not found
+        proj-indented-notice -error {
+          --enable-load-extension was provided but dlopen()
+          not found. Use --disable-load-extension to bypass this
+          check.
+        }
+      } else {
+        # It was implicitly enabled: warn if not found
+        proj-indented-notice {
+          WARNING: dlopen() not found, so loadable module support will
+          be disabled. Use --disable-load-extension to bypass this
+          check.
+        }
+      }
+    }
+  }
+  if {$found} {
+    msg-result "Loadable extension support enabled."
+  } else {
+    msg-result "Disabling loadable extension support. Use --enable-load-extension to enable them."
+    sqlite-add-feature-flag -DSQLITE_OMIT_LOAD_EXTENSION=1
+  }
+  return $found
+}
+
+#
+# ICU - International Components for Unicode
+#
+# Handles these flags:
+#
+#  --with-icu-ldflags=LDFLAGS
+#  --with-icu-cflags=CFLAGS
+#  --with-icu-config[=auto | pkg-config | /path/to/icu-config]
+#  --enable-icu-collations
+#
+# --with-icu-config values:
+#
+#   - auto: use the first one of (pkg-config, icu-config) found on the
+#     system.
+#   - pkg-config: use only pkg-config to determine flags
+#   - /path/to/icu-config: use that to determine flags
+#
+# If --with-icu-config is used as neither pkg-config nor icu-config
+# are found, fail fatally.
+#
+# If both --with-icu-ldflags and --with-icu-config are provided, they
+# are cumulative.  If neither are provided, icu-collations is not
+# honored and a warning is emitted if it is provided.
+#
+# Design note: though we could automatically enable ICU if the
+# icu-config binary or (pkg-config icu-io) are found, we specifically
+# do not. ICU is always an opt-in feature.
+proc sqlite-handle-icu {} {
+  define LDFLAGS_LIBICU [join [opt-val with-icu-ldflags ""]]
+  define CFLAGS_LIBICU [join [opt-val with-icu-cflags ""]]
+  if {[proj-opt-was-provided with-icu-config]} {
+    msg-result "Checking for ICU support..."
+    set icuConfigBin [opt-val with-icu-config]
+    set tryIcuConfigBin 1; # set to 0 if we end up using pkg-config
+    if {$icuConfigBin in {auto pkg-config}} {
+      uplevel 3 { use pkg-config }
+      if {[pkg-config-init 0] && [pkg-config icu-io]} {
+        # Maintenance reminder: historical docs say to use both of
+        # (icu-io, icu-uc). icu-uc lacks a required lib and icu-io has
+        # all of them on tested OSes.
+        set tryIcuConfigBin 0
+        define LDFLAGS_LIBICU [get-define PKG_ICU_IO_LDFLAGS]
+        define-append LDFLAGS_LIBICU [get-define PKG_ICU_IO_LIBS]
+        define CFLAGS_LIBICU [get-define PKG_ICU_IO_CFLAGS]
+      } elseif {"pkg-config" eq $icuConfigBin} {
+        proj-fatal "pkg-config cannot find package icu-io"
+      } else {
+        proj-assert {"auto" eq $icuConfigBin}
+      }
+    }
+    if {$tryIcuConfigBin} {
+      if {"auto" eq $icuConfigBin} {
+        set icuConfigBin [proj-first-bin-of \
+                            /usr/local/bin/icu-config \
+                            /usr/bin/icu-config]
+        if {"" eq $icuConfigBin} {
+          proj-indented-notice -error {
+            --with-icu-config=auto cannot find (pkg-config icu-io) or icu-config binary.
+            On Ubuntu-like systems try:
+            --with-icu-ldflags='-licui18n -licuuc -licudata'
+          }
+        }
+      }
+      if {[file-isexec $icuConfigBin]} {
+        set x [exec $icuConfigBin --ldflags]
+        if {"" eq $x} {
+          proj-indented-notice -error \
+            [subst {
+              $icuConfigBin --ldflags returned no data.
+              On Ubuntu-like systems try:
+              --with-icu-ldflags='-licui18n -licuuc -licudata'
+            }]
+        }
+        define-append LDFLAGS_LIBICU $x
+        set x [exec $icuConfigBin --cppflags]
+        define-append CFLAGS_LIBICU $x
+      } else {
+        proj-fatal "--with-icu-config=$icuConfigBin does not refer to an executable"
+      }
+    }
+  }
+  set ldflags [define LDFLAGS_LIBICU [string trim [get-define LDFLAGS_LIBICU]]]
+  set cflags [define CFLAGS_LIBICU [string trim [get-define CFLAGS_LIBICU]]]
+  if {"" ne $ldflags} {
+    sqlite-add-feature-flag -DSQLITE_ENABLE_ICU
+    msg-result "Enabling ICU support with flags: $ldflags $cflags"
+    if {[opt-bool icu-collations]} {
+      msg-result "Enabling ICU collations."
+      sqlite-add-feature-flag -DSQLITE_ENABLE_ICU_COLLATIONS
+    }
+    teaish-ldflags-prepend $ldflags
+    teaish-cflags-add $cflags
+  } elseif {[opt-bool icu-collations]} {
+    proj-warn "ignoring --enable-icu-collations because neither --with-icu-ldflags nor --with-icu-config provided any linker flags"
+  } else {
+    msg-result "ICU support is disabled."
+  }
+}; # sqlite-handle-icu
+
+
+#
+# Handles the --with-tempstore flag.
+#
+# The test fixture likes to set SQLITE_TEMP_STORE on its own, so do
+# not set that feature flag unless it was explicitly provided to the
+# configure script.
+proc sqlite-handle-tempstore {} {
+  if {[proj-opt-was-provided with-tempstore]} {
+    set ts [opt-val with-tempstore no]
+    set tsn 1
+    msg-checking "Use an in-RAM database for temporary tables? "
+    switch -exact -- $ts {
+      never  { set tsn 0 }
+      no     { set tsn 1 }
+      yes    { set tsn 2 }
+      always { set tsn 3 }
+      default {
+        user-error "Invalid --with-tempstore value '$ts'. Use one of: never, no, yes, always"
+      }
+    }
+    msg-result $ts
+    sqlite-add-feature-flag -DSQLITE_TEMP_STORE=$tsn
+  }
+}
+
+#
+# Handles the --enable-math flag.
+proc sqlite-handle-math {} {
+  proj-if-opt-truthy math {
+    if {![proj-check-function-in-lib ceil m]} {
+      user-error "Cannot find libm functions. Use --disable-math to bypass this."
+    }
+    set lfl [get-define lib_ceil]
+    undefine lib_ceil
+    define LDFLAGS_MATH $lfl
+    teaish-ldflags-prepend $lfl
+    sqlite-add-feature-flag -DSQLITE_ENABLE_MATH_FUNCTIONS
+    msg-result "Enabling math SQL functions"
+  } {
+    define LDFLAGS_MATH ""
+    msg-result "Disabling math SQL functions"
+  }
+}
+
+#
+# Move -DSQLITE_OMIT... and -DSQLITE_ENABLE... flags from CFLAGS and
+# CPPFLAGS to OPT_FEATURE_FLAGS and remove them from BUILD_CFLAGS.
+proc sqlite-munge-cflags {} {
+  # Move CFLAGS and CPPFLAGS entries matching -DSQLITE_OMIT* and
+  # -DSQLITE_ENABLE* to OPT_FEATURE_FLAGS. This behavior is derived
+  # from the pre-3.48 build.
+  #
+  # If any configure flags for features are in conflict with
+  # CFLAGS/CPPFLAGS-specified feature flags, all bets are off.  There
+  # are no guarantees about which one will take precedence.
+  foreach flagDef {CFLAGS CPPFLAGS} {
+    set tmp ""
+    foreach cf [get-define $flagDef ""] {
+      switch -glob -- $cf {
+        -DSQLITE_OMIT* -
+        -DSQLITE_ENABLE* {
+          sqlite-add-feature-flag $cf
+        }
+        default {
+          lappend tmp $cf
+        }
+      }
+    }
+    define $flagDef $tmp
+  }
+}