mirror of
https://github.com/sqlite/sqlite.git
synced 2025-07-30 19:03:16 +03:00
Further refactoring of auto.def to simplify creation of variant builds like the autoconf bundle.
FossilOrigin-Name: f806c563a29240c709508316846fbe0cb3ed61b68a6c1d9544eb699e30141d8d
This commit is contained in:
@ -9,7 +9,29 @@ use cc cc-db cc-shared cc-lib pkg-config proj
|
||||
# Object for communicating config-time state across various
|
||||
# auto.def-related pieces.
|
||||
#
|
||||
array set sqliteConfig {}
|
||||
array set sqliteConfig [proj-strip-hash-comments {
|
||||
#
|
||||
# Gets set to 1 when using jimsh for code generation. May affect
|
||||
# later decisions.
|
||||
use-jim-for-codegen 0
|
||||
#
|
||||
# Pass msg-debug=1 to configure to enable obnoxiously loud output
|
||||
# from [msg-debug].
|
||||
msg-debug-enabled 0
|
||||
#
|
||||
# Output file for --dump-defines. Intended only for build debugging
|
||||
# and not part of the public build interface.
|
||||
dump-defines-txt ./config.defines.txt
|
||||
#
|
||||
# Output file for --dump-defines-json. This is the autosetup
|
||||
# counterpart of the historical "DEFS" var which was generated by
|
||||
# the autotools in the pre-processed autotools builds (but not in
|
||||
# the canonical tree). Generation of this file is disabled (via an
|
||||
# empty file name) until/unless someone voices a specific interest
|
||||
# in it. The original motivating use case is handled fine by
|
||||
# sqlite_cfg.h.
|
||||
dump-defines-json ""
|
||||
}]
|
||||
|
||||
#
|
||||
# Set to 1 when cross-compiling This value may be changed by certain
|
||||
@ -19,13 +41,6 @@ array set sqliteConfig {}
|
||||
#
|
||||
set sqliteConfig(is-cross-compiling) [proj-is-cross-compiling]
|
||||
|
||||
#
|
||||
# Gets set to 1 when using jimsh for code generation. May affect later
|
||||
# decisions.
|
||||
#
|
||||
set sqliteConfig(use-jim-for-codegen) 0
|
||||
|
||||
|
||||
########################################################################
|
||||
# Runs some common initialization which must happen immediately after
|
||||
# autosetup's [options] function is called.
|
||||
@ -41,6 +56,23 @@ proc sqlite-post-options-init {} {
|
||||
with-debug => debug
|
||||
}
|
||||
sqlite-autoreconfig
|
||||
proj-file-extensions
|
||||
if {".exe" eq [get-define TARGET_EXEEXT]} {
|
||||
define SQLITE_OS_UNIX 0
|
||||
define SQLITE_OS_WIN 1
|
||||
} else {
|
||||
define SQLITE_OS_UNIX 1
|
||||
define SQLITE_OS_WIN 0
|
||||
}
|
||||
|
||||
set ::sqliteConfig(msg-debug-enabled) [proj-val-truthy [get-env msg-debug 0]]
|
||||
|
||||
}
|
||||
|
||||
proc msg-debug {msg} {
|
||||
if {$::sqliteConfig(msg-debug-enabled)} {
|
||||
puts stderr [proj-bold "** DEBUG: $msg"]
|
||||
}
|
||||
}
|
||||
|
||||
########################################################################
|
||||
@ -92,6 +124,151 @@ proc sqlite-add-shell-opt {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"
|
||||
}
|
||||
define LDFLAGS_MATH [get-define lib_log ""]
|
||||
undefine lib_log
|
||||
}
|
||||
}
|
||||
|
||||
########################################################################
|
||||
# Run checks for required binaries, like ld and ar. In the canonical
|
||||
# build this must come before [sqlite-handle-wasi-sdk].
|
||||
proc sqlite-check-common-bins {} {
|
||||
cc-check-tools ld ar ; # must come before [sqlite-handle-wasi-sdk]
|
||||
if {"" eq [proj-bin-define install]} {
|
||||
proj-warn "Cannot find install binary, so 'make install' will not work."
|
||||
define BIN_INSTALL false
|
||||
}
|
||||
}
|
||||
|
||||
########################################################################
|
||||
# Run checks for system-level includes and libs which are common to
|
||||
# both the canonical build and the "autoconf" bundle.
|
||||
proc sqlite-check-common-system-deps {} {
|
||||
#
|
||||
# Check for needed/wanted data types
|
||||
cc-with {-includes stdint.h} \
|
||||
{cc-check-types int8_t int16_t int32_t int64_t intptr_t \
|
||||
uint8_t uint16_t uint32_t uint64_t uintptr_t}
|
||||
|
||||
#
|
||||
# Check for needed/wanted functions
|
||||
cc-check-functions gmtime_r isnan localtime_r localtime_s \
|
||||
malloc_usable_size strchrnul usleep utime pread pread64 pwrite pwrite64
|
||||
|
||||
proj-check-function-in-lib fdatasync rt
|
||||
define LDFLAGS_FDATASYNC [get-define lib_fdatasync]
|
||||
undefine lib_fdatasync
|
||||
|
||||
#
|
||||
# Check for needed/wanted headers
|
||||
cc-check-includes \
|
||||
sys/types.h sys/stat.h dlfcn.h unistd.h \
|
||||
stdlib.h malloc.h memory.h \
|
||||
string.h strings.h \
|
||||
inttypes.h
|
||||
|
||||
if {[cc-check-includes zlib.h] && [proj-check-function-in-lib deflate z]} {
|
||||
# TODO? port over the more sophisticated zlib search from the fossil auto.def
|
||||
define HAVE_ZLIB 1
|
||||
define LDFLAGS_ZLIB -lz
|
||||
sqlite-add-shell-opt -DSQLITE_HAVE_ZLIB=1
|
||||
} else {
|
||||
define HAVE_ZLIB 0
|
||||
define LDFLAGS_ZLIB ""
|
||||
}
|
||||
}
|
||||
|
||||
proc sqlite-setup-default-cflags {} {
|
||||
########################################################################
|
||||
# We differentiate between two C compilers: the one used for binaries
|
||||
# which are to run on the build system (in autosetup it's called
|
||||
# CC_FOR_BUILD and in Makefile.in it's $(B.cc)) and the one used for
|
||||
# compiling binaries for the target system (CC a.k.a. $(T.cc)).
|
||||
# Normally they're the same, but they will differ when
|
||||
# cross-compiling.
|
||||
#
|
||||
# When cross-compiling we default to not using the -g flag, based on a
|
||||
# /chat discussion prompted by
|
||||
# https://sqlite.org/forum/forumpost/9a67df63eda9925c
|
||||
set defaultCFlags {-O2}
|
||||
if {!$::sqliteConfig(is-cross-compiling)} {
|
||||
lappend defaultCFlags -g
|
||||
}
|
||||
define CFLAGS [proj-get-env CFLAGS $defaultCFlags]
|
||||
# BUILD_CFLAGS is the CFLAGS for CC_FOR_BUILD.
|
||||
define BUILD_CFLAGS [proj-get-env BUILD_CFLAGS {-g}]
|
||||
}
|
||||
|
||||
########################################################################
|
||||
# Handle various SQLITE_ENABLE_... feature flags.
|
||||
proc sqlite-handle-common-feature-flags {} {
|
||||
msg-result "Feature flags..."
|
||||
foreach {boolFlag featureFlag ifSetEvalThis} {
|
||||
all {} {
|
||||
# The 'all' option must be first in this list.
|
||||
proj-opt-set fts4
|
||||
proj-opt-set fts5
|
||||
proj-opt-set geopoly
|
||||
proj-opt-set rtree
|
||||
proj-opt-set session
|
||||
}
|
||||
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 {}
|
||||
memsys5 -DSQLITE_ENABLE_MEMSYS5 {}
|
||||
memsys3 {} {
|
||||
if {[opt-bool memsys5]} {
|
||||
proj-warn "not enabling memsys3 because memsys5 is enabled."
|
||||
expr 0
|
||||
} else {
|
||||
sqlite-add-feature-flag -DSQLITE_ENABLE_MEMSYS3
|
||||
}
|
||||
}
|
||||
scanstatus -DSQLITE_ENABLE_STMT_SCANSTATUS {}
|
||||
} {
|
||||
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"
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#########################################################################
|
||||
# Show the final feature flag sets.
|
||||
proc sqlite-show-feature-flags {} {
|
||||
@ -112,7 +289,7 @@ proc sqlite-show-feature-flags {} {
|
||||
# Checks for the --debug flag, defining SQLITE_DEBUG to 1 if it is
|
||||
# true. TARGET_DEBUG gets defined either way, with content depending
|
||||
# on whether --debug is true or false.
|
||||
proc sqlite-check-debug {} {
|
||||
proc sqlite-handle-debug {} {
|
||||
msg-checking "SQLITE_DEBUG build? "
|
||||
proj-if-opt-truthy debug {
|
||||
define SQLITE_DEBUG 1
|
||||
@ -128,7 +305,7 @@ proc sqlite-check-debug {} {
|
||||
########################################################################
|
||||
# "soname" for libsqlite3.so. See discussion at:
|
||||
# https://sqlite.org/src/forumpost/5a3b44f510df8ded
|
||||
proc sqlite-check-soname {} {
|
||||
proc sqlite-handle-soname {} {
|
||||
define LDFLAGS_LIBSQLITE3_SONAME ""
|
||||
if {[proj-opt-was-provided soname]} {
|
||||
set soname [join [opt-val soname] ""]
|
||||
@ -151,7 +328,7 @@ proc sqlite-check-soname {} {
|
||||
}
|
||||
}
|
||||
}
|
||||
# msg-debug "soname=$soname"
|
||||
msg-debug "soname=$soname"
|
||||
if {[proj-check-soname $soname]} {
|
||||
define LDFLAGS_LIBSQLITE3_SONAME [get-define LDFLAGS_SONAME_PREFIX]$soname
|
||||
msg-result "Setting SONAME using: [get-define LDFLAGS_LIBSQLITE3_SONAME]"
|
||||
@ -170,7 +347,7 @@ proc sqlite-check-soname {} {
|
||||
# needed for linking pthread. If --enable-threadsafe is not set, adds
|
||||
# -DSQLITE_THREADSAFE=0 to OPT_FEATURE_FLAGS and sets LDFLAGS_PTHREAD
|
||||
# to an empty string.
|
||||
proc sqlite-check-threadsafe {} {
|
||||
proc sqlite-handle-threadsafe {} {
|
||||
msg-checking "Support threadsafe operation? "
|
||||
proj-if-opt-truthy threadsafe {
|
||||
msg-result yes
|
||||
@ -190,6 +367,57 @@ proc sqlite-check-threadsafe {} {
|
||||
}
|
||||
}
|
||||
|
||||
########################################################################
|
||||
# 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
|
||||
}
|
||||
}
|
||||
|
||||
########################################################################
|
||||
# Check for the Emscripten SDK for building the web-based wasm
|
||||
# components. The core lib and tools do not require this but ext/wasm
|
||||
# does.
|
||||
proc sqlite-handle-emsdk {} {
|
||||
set srcdir $::autosetup(srcdir)
|
||||
if {$srcdir ne $::autosetup(builddir)} {
|
||||
# The EMSDK pieces require writing to the original source tree
|
||||
# even when doing an out-of-tree build. The ext/wasm pieces do not
|
||||
# support an out-of-tree build so we catch that case and treat it
|
||||
# as if EMSDK were not found.
|
||||
msg-result "Out-of tree build: not checking for EMSDK."
|
||||
define EMCC_WRAPPER ""
|
||||
return
|
||||
}
|
||||
set emccsh $srcdir/tool/emcc.sh
|
||||
if {![get-define HAVE_WASI_SDK] && [proj-check-emsdk]} {
|
||||
define EMCC_WRAPPER $emccsh
|
||||
proj-make-from-dot-in $emccsh
|
||||
catch {exec chmod u+x $emccsh}
|
||||
} else {
|
||||
define EMCC_WRAPPER ""
|
||||
file delete -force $emccsh
|
||||
}
|
||||
}
|
||||
|
||||
########################################################################
|
||||
# sqlite-check-line-editing jumps through proverbial hoops to try to
|
||||
# find a working line-editing library, setting:
|
||||
@ -227,7 +455,6 @@ proc sqlite-check-threadsafe {} {
|
||||
# corresponding --FEATURE flag was explicitly given, fail fatally,
|
||||
# else fail silently.
|
||||
proc sqlite-check-line-editing {} {
|
||||
rename sqlite-check-line-editing ""
|
||||
msg-result "Checking for line-editing capability..."
|
||||
define HAVE_READLINE 0
|
||||
define HAVE_LINENOISE 0
|
||||
@ -430,6 +657,15 @@ proc sqlite-check-line-editing {} {
|
||||
return "none"
|
||||
}; # sqlite-check-line-editing
|
||||
|
||||
########################################################################
|
||||
# Runs sqlite-check-line-editing and adds a message around it In the
|
||||
# canonical build this must not be called before
|
||||
# sqlite-determine-codegen-tcl.
|
||||
proc sqlite-handle-line-editing {} {
|
||||
msg-result "Line-editing support for the sqlite3 shell: [sqlite-check-line-editing]"
|
||||
}
|
||||
|
||||
|
||||
########################################################################
|
||||
# ICU - International Components for Unicode
|
||||
#
|
||||
@ -457,8 +693,7 @@ proc sqlite-check-line-editing {} {
|
||||
# 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-check-icu {} {
|
||||
rename sqlite-check-icu ""
|
||||
proc sqlite-handle-icu {} {
|
||||
define LDFLAGS_ICU [join [opt-val with-icu-ldflags ""]]
|
||||
define CFLAGS_ICU [join [opt-val with-icu-cflags ""]]
|
||||
if {[proj-opt-was-provided with-icu-config]} {
|
||||
@ -516,4 +751,515 @@ proc sqlite-check-icu {} {
|
||||
} else {
|
||||
msg-result "ICU support is disabled."
|
||||
}
|
||||
}; # sqlite-check-icu
|
||||
}; # sqlite-handle-icu
|
||||
|
||||
|
||||
########################################################################
|
||||
# Handles the --enable-load-extension flag.
|
||||
proc sqlite-handle-load-extension {} {
|
||||
proj-if-opt-truthy load-extension {
|
||||
if {[proj-check-function-in-lib dlopen dl]} {
|
||||
define LDFLAGS_DLOPEN [get-define lib_dlopen]
|
||||
undefine lib_dlopen
|
||||
} else {
|
||||
user-error "dlopen() not found. Use --disable-load-extension to bypass this check."
|
||||
}
|
||||
} {
|
||||
define LDFLAGS_DLOPEN ""
|
||||
sqlite-add-feature-flag {-DSQLITE_OMIT_LOAD_EXTENSION=1}
|
||||
msg-result "Disabling loadable extensions."
|
||||
}
|
||||
}
|
||||
|
||||
########################################################################
|
||||
# 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."
|
||||
}
|
||||
define LDFLAGS_MATH [get-define lib_ceil]
|
||||
undefine lib_ceil
|
||||
sqlite-add-feature-flag {-DSQLITE_ENABLE_MATH_FUNCTIONS}
|
||||
msg-result "Enabling math SQL functions [get-define LDFLAGS_MATH]"
|
||||
} {
|
||||
define LDFLAGS_MATH ""
|
||||
msg-result "Disabling math SQL functions"
|
||||
}
|
||||
}
|
||||
|
||||
########################################################################
|
||||
# Generate the configure-process output file(s).
|
||||
proc sqlite-process-dot-in-files {} {
|
||||
########################################################################
|
||||
# When cross-compiling, we have to avoid using the -s flag to
|
||||
# /usr/bin/install: https://sqlite.org/forum/forumpost/9a67df63eda9925c
|
||||
define IS_CROSS_COMPILING $::sqliteConfig(is-cross-compiling)
|
||||
|
||||
########################################################################
|
||||
# "Re-export" the autoconf-conventional --XYZdir flags into something
|
||||
# which is more easily overridable from a make invocation. See the docs
|
||||
# for [proj-remap-autoconf-dir-vars] for the explanation of why.
|
||||
#
|
||||
# We do this late in the config process, immediately before we export
|
||||
# the Makefile and other generated files, so that configure tests
|
||||
# which make make use of the autotools-conventional flags
|
||||
# (e.g. [proj-check-rpath]) may do so before we "mangle" them here.
|
||||
proj-remap-autoconf-dir-vars
|
||||
|
||||
proj-make-from-dot-in -touch Makefile sqlite3.pc
|
||||
make-config-header sqlite_cfg.h \
|
||||
-bare {SIZEOF_* HAVE_DECL_*} \
|
||||
-none {HAVE_CFLAG_* LDFLAGS_* SH_* SQLITE_AUTORECONFIG
|
||||
TARGET_* USE_GCOV TCL_*} \
|
||||
-auto {HAVE_* PACKAGE_*} \
|
||||
-none *
|
||||
proj-touch sqlite_cfg.h ; # help avoid frequent unnecessary @SQLITE_AUTORECONFIG@
|
||||
}
|
||||
|
||||
########################################################################
|
||||
# Perform some high-level validation on the generated files...
|
||||
#
|
||||
# 1) Ensure that no unresolved @VAR@ placeholders are in files which
|
||||
# use those.
|
||||
#
|
||||
# 2) TBD
|
||||
proc sqlite-post-config-validation {} {
|
||||
# Check #1: ensure that files which get filtered for @VAR@ do not
|
||||
# contain any unresolved @VAR@ refs. That may indicate an
|
||||
# unexported/unused var or a typo.
|
||||
foreach f "Makefile sqlite3.pc $::autosetup(srcdir)/tool/emcc.sh" {
|
||||
if {![file exists $f]} continue
|
||||
set lnno 1
|
||||
foreach line [proj-file-content-list $f] {
|
||||
if {[regexp {(@[A-Za-z_]+@)} $line match]} {
|
||||
error "Unresolved reference to $match at line $lnno of $f"
|
||||
}
|
||||
incr lnno
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
########################################################################
|
||||
# Handle --with-wasi-sdk[=DIR]
|
||||
#
|
||||
# This must be run relatively early on because it may change the
|
||||
# toolchain and disable a number of config options. However, in the
|
||||
# canonical build this must come after [sqlite-check-common-bins].
|
||||
proc sqlite-handle-wasi-sdk {} {
|
||||
set wasiSdkDir [opt-val with-wasi-sdk] ; # ??? [lindex [opt-val with-wasi-sdk] end]
|
||||
define HAVE_WASI_SDK 0
|
||||
if {$wasiSdkDir eq ""} {
|
||||
return 0
|
||||
} elseif {$::sqliteConfig(is-cross-compiling)} {
|
||||
proj-fatal "Cannot combine --with-wasi-sdk with cross-compilation"
|
||||
}
|
||||
msg-result "Checking WASI SDK directory \[$wasiSdkDir]... "
|
||||
proj-affirm-files-exist -v {*}[prefix "$wasiSdkDir/bin/" {clang wasm-ld ar}]
|
||||
define HAVE_WASI_SDK 1
|
||||
define WASI_SDK_DIR $wasiSdkDir
|
||||
# Disable numerous options which we know either can't work or are
|
||||
# not useful in this build...
|
||||
msg-result "Using wasi-sdk clang. Disabling CLI shell and modifying config flags:"
|
||||
# Boolean (--enable-/--disable-) flags which must be switched off:
|
||||
foreach opt {
|
||||
dynlink-tools
|
||||
editline
|
||||
gcov
|
||||
icu-collations
|
||||
load-extension
|
||||
readline
|
||||
shared
|
||||
tcl
|
||||
threadsafe
|
||||
} {
|
||||
if {[opt-bool $opt]} {
|
||||
msg-result " --disable-$opt"
|
||||
proj-opt-set $opt 0
|
||||
}
|
||||
}
|
||||
# Non-boolean flags which need to be cleared:
|
||||
foreach opt {
|
||||
with-emsdk
|
||||
with-icu-config
|
||||
with-icu-ldflags
|
||||
with-icu-cflags
|
||||
with-linenoise
|
||||
with-tcl
|
||||
} {
|
||||
if {[proj-opt-was-provided $opt]} {
|
||||
msg-result " removing --$opt"
|
||||
proj-opt-set $opt ""
|
||||
}
|
||||
}
|
||||
# Remember that we now have a discrepancy beteween
|
||||
# $::sqliteConfig(is-cross-compiling) and [proj-is-cross-compiling].
|
||||
set ::sqliteConfig(is-cross-compiling) 1
|
||||
|
||||
#
|
||||
# Changing --host and --target have no effect here except to
|
||||
# possibly cause confusion. Autosetup has finished processing them
|
||||
# by this point.
|
||||
#
|
||||
# host_alias=wasm32-wasi
|
||||
# target=wasm32-wasi
|
||||
#
|
||||
# Merely changing CC, LD, and AR to the wasi-sdk's is enough to get
|
||||
# sqlite3.o building in WASM format.
|
||||
#
|
||||
define CC "${wasiSdkDir}/bin/clang"
|
||||
define LD "${wasiSdkDir}/bin/wasm-ld"
|
||||
define AR "${wasiSdkDir}/bin/ar"
|
||||
#define STRIP "${wasiSdkDir}/bin/strip"
|
||||
return 1
|
||||
}; # sqlite-handle-wasi-sdk
|
||||
|
||||
########################################################################
|
||||
# TCL...
|
||||
#
|
||||
# sqlite-check-tcl performs most of the --with-tcl and --with-tclsh
|
||||
# handling. Some related bits and pieces are performed before and
|
||||
# after that function is called.
|
||||
#
|
||||
# Important [define]'d vars:
|
||||
#
|
||||
# - HAVE_TCL indicates whether we have a tclsh suitable for building
|
||||
# the TCL SQLite extension and, by extension, the testing
|
||||
# infrastructure. This must only be 1 for environments where
|
||||
# tclConfig.sh can be found.
|
||||
#
|
||||
# - TCLSH_CMD is the path to the canonical tclsh or "". It never
|
||||
# refers to jimtcl.
|
||||
#
|
||||
# - TCL_CONFIG_SH is the path to tclConfig.sh or "".
|
||||
#
|
||||
# - TCLLIBDIR is the dir to which libtclsqlite3 gets installed.
|
||||
#
|
||||
# - BTCLSH = the path to the tcl interpreter used for in-tree code
|
||||
# generation. It may be jimtcl or the canonical tclsh but may not
|
||||
# be empty - this tree requires TCL to generated numerous
|
||||
# components.
|
||||
#
|
||||
# If --tcl or --with-tcl are provided but no TCL is found, this
|
||||
# function fails fatally. If they are not explicitly provided then
|
||||
# failure to find TCL is not fatal but a loud warning will be emitted.
|
||||
#
|
||||
proc sqlite-check-tcl {} {
|
||||
define TCLSH_CMD false ; # Significant is that it exits with non-0
|
||||
define HAVE_TCL 0 ; # Will be enabled via --tcl or a successful search
|
||||
define TCLLIBDIR "" ; # Installation dir for TCL extension lib
|
||||
define TCL_CONFIG_SH ""; # full path to tclConfig.sh
|
||||
|
||||
# Clear out all vars which would be set by tclConfigToAutoDef.sh, so
|
||||
# that the late-config validation of @VARS@ works even if
|
||||
# --disable-tcl is used.
|
||||
foreach k {TCL_INCLUDE_SPEC TCL_LIB_SPEC TCL_STUB_LIB_SPEC TCL_EXEC_PREFIX TCL_VERSION} {
|
||||
define $k ""
|
||||
}
|
||||
|
||||
file delete -force ".tclenv.sh"; # ensure no stale state from previous configures.
|
||||
if {![opt-bool tcl]} {
|
||||
proj-indented-notice {
|
||||
NOTE: TCL is disabled via --disable-tcl. This means that none
|
||||
of the TCL-based components will be built, including tests
|
||||
and sqlite3_analyzer.
|
||||
}
|
||||
return
|
||||
}
|
||||
# TODO: document the steps this is taking.
|
||||
set srcdir $::autosetup(srcdir)
|
||||
msg-result "Checking for a suitable tcl... "
|
||||
proj-assert [proj-opt-truthy tcl]
|
||||
set use_tcl 1
|
||||
set with_tclsh [opt-val with-tclsh]
|
||||
set with_tcl [opt-val with-tcl]
|
||||
if {"prefix" eq $with_tcl} {
|
||||
set with_tcl [get-define prefix]
|
||||
}
|
||||
msg-debug "sqlite-check-tcl: use_tcl ${use_tcl}"
|
||||
msg-debug "sqlite-check-tcl: with_tclsh=${with_tclsh}"
|
||||
msg-debug "sqlite-check-tcl: with_tcl=$with_tcl"
|
||||
if {"" eq $with_tclsh && "" eq $with_tcl} {
|
||||
# If neither --with-tclsh nor --with-tcl are provided, try to find
|
||||
# a workable tclsh.
|
||||
set with_tclsh [proj-first-bin-of tclsh9.0 tclsh8.6 tclsh]
|
||||
msg-debug "sqlite-check-tcl: with_tclsh=${with_tclsh}"
|
||||
}
|
||||
|
||||
set doConfigLookup 1 ; # set to 0 to test the tclConfig.sh-not-found cases
|
||||
if {"" ne $with_tclsh} {
|
||||
# --with-tclsh was provided or found above. Validate it and use it
|
||||
# to trump any value passed via --with-tcl=DIR.
|
||||
if {![file isfile $with_tclsh]} {
|
||||
proj-fatal "TCL shell $with_tclsh is not a file"
|
||||
} elseif {![file-isexec $with_tclsh]} {
|
||||
proj-fatal "TCL shell $with_tclsh is not executable"
|
||||
} else {
|
||||
define TCLSH_CMD $with_tclsh
|
||||
#msg-result "Using tclsh: $with_tclsh"
|
||||
}
|
||||
if {$doConfigLookup &&
|
||||
[catch {exec $with_tclsh $srcdir/tool/find_tclconfig.tcl} result] == 0} {
|
||||
set with_tcl $result
|
||||
}
|
||||
if {"" ne $with_tcl && [file isdir $with_tcl]} {
|
||||
msg-result "$with_tclsh recommends the tclConfig.sh from $with_tcl"
|
||||
} else {
|
||||
proj-warn "$with_tclsh is unable to recommend a tclConfig.sh"
|
||||
set use_tcl 0
|
||||
}
|
||||
}
|
||||
set cfg ""
|
||||
set tclSubdirs {tcl9.0 tcl8.6 lib}
|
||||
while {$use_tcl} {
|
||||
if {"" ne $with_tcl} {
|
||||
# Ensure that we can find tclConfig.sh under ${with_tcl}/...
|
||||
if {$doConfigLookup} {
|
||||
if {[file readable "${with_tcl}/tclConfig.sh"]} {
|
||||
set cfg "${with_tcl}/tclConfig.sh"
|
||||
} else {
|
||||
foreach i $tclSubdirs {
|
||||
if {[file readable "${with_tcl}/$i/tclConfig.sh"]} {
|
||||
set cfg "${with_tcl}/$i/tclConfig.sh"
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if {"" eq $cfg} {
|
||||
proj-fatal "No tclConfig.sh found under ${with_tcl}"
|
||||
}
|
||||
} else {
|
||||
# If we have not yet found a tclConfig.sh file, look in
|
||||
# $libdir which is set automatically by autosetup or by the
|
||||
# --prefix command-line option. See
|
||||
# https://sqlite.org/forum/forumpost/e04e693439a22457
|
||||
set libdir [get-define libdir]
|
||||
if {[file readable "${libdir}/tclConfig.sh"]} {
|
||||
set cfg "${libdir}/tclConfig.sh"
|
||||
} else {
|
||||
foreach i $tclSubdirs {
|
||||
if {[file readable "${libdir}/$i/tclConfig.sh"]} {
|
||||
set cfg "${libdir}/$i/tclConfig.sh"
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
if {![file readable $cfg]} {
|
||||
break
|
||||
}
|
||||
}
|
||||
msg-result "Using tclConfig.sh: $cfg"
|
||||
break
|
||||
}
|
||||
define TCL_CONFIG_SH $cfg
|
||||
# Export a subset of tclConfig.sh to the current TCL-space. If $cfg
|
||||
# is an empty string, this emits empty-string entries for the
|
||||
# various options we're interested in.
|
||||
eval [exec "$srcdir/tool/tclConfigShToAutoDef.sh" "$cfg"]
|
||||
|
||||
if {"" eq $with_tclsh && $cfg ne ""} {
|
||||
# We have tclConfig.sh but no tclsh. Attempt to locate a tclsh
|
||||
# based on info from tclConfig.sh.
|
||||
proj-assert {"" ne [get-define TCL_EXEC_PREFIX]}
|
||||
set with_tclsh [get-define TCL_EXEC_PREFIX]/bin/tclsh[get-define TCL_VERSION]
|
||||
if {![file-isexec $with_tclsh]} {
|
||||
set with_tclsh2 [get-define TCL_EXEC_PREFIX]/bin/tclsh
|
||||
if {![file-isexec $with_tclsh2]} {
|
||||
proj-warn "Cannot find a usable tclsh (tried: $with_tclsh $with_tclsh2)"
|
||||
} else {
|
||||
set with_tclsh $with_tclsh2
|
||||
}
|
||||
}
|
||||
}
|
||||
define TCLSH_CMD $with_tclsh
|
||||
if {$use_tcl} {
|
||||
# Set up the TCLLIBDIR
|
||||
#
|
||||
# 2024-10-28: calculation of TCLLIBDIR is now done via the shell
|
||||
# in main.mk (search it for T.tcl.env.sh) so that
|
||||
# static/hand-written makefiles which import main.mk do not have
|
||||
# to define that before importing main.mk. Even so, we export
|
||||
# TCLLIBDIR from here, which will cause the canonical makefile to
|
||||
# use this one rather than to re-calculate it at make-time.
|
||||
set tcllibdir [get-env TCLLIBDIR ""]
|
||||
if {"" eq $tcllibdir} {
|
||||
# Attempt to extract TCLLIBDIR from TCL's $auto_path
|
||||
if {"" ne $with_tclsh &&
|
||||
[catch {exec echo "puts stdout \$auto_path" | "$with_tclsh"} result] == 0} {
|
||||
foreach i $result {
|
||||
if {[file isdir $i]} {
|
||||
set tcllibdir $i/sqlite3
|
||||
break
|
||||
}
|
||||
}
|
||||
} else {
|
||||
proj-warn "Cannot determine TCLLIBDIR."
|
||||
# The makefile will fail fatally in this case if a target is
|
||||
# invoked which requires TCLLIBDIR.
|
||||
}
|
||||
}
|
||||
#if {"" ne $tcllibdir} { msg-result "TCLLIBDIR = ${tcllibdir}"; }
|
||||
define TCLLIBDIR $tcllibdir
|
||||
}; # find TCLLIBDIR
|
||||
|
||||
if {[file-isexec $with_tclsh]} {
|
||||
msg-result "Using tclsh: $with_tclsh"
|
||||
if {$cfg ne ""} {
|
||||
define HAVE_TCL 1
|
||||
} else {
|
||||
proj-warn "Found tclsh but no tclConfig.sh."
|
||||
}
|
||||
}
|
||||
show-notices
|
||||
# If TCL is not found: if it was explicitly requested then fail
|
||||
# fatally, else just emit a warning. If we can find the APIs needed
|
||||
# to generate a working JimTCL then that will suffice for build-time
|
||||
# TCL purposes (see: proc sqlite-determine-codegen-tcl).
|
||||
if {![get-define HAVE_TCL] &&
|
||||
([proj-opt-was-provided tcl] || [proj-opt-was-provided with-tcl])} {
|
||||
proj-fatal "TCL support was requested but no tclConfig.sh could be found."
|
||||
}
|
||||
if {"" eq $cfg} {
|
||||
proj-assert {0 == [get-define HAVE_TCL]}
|
||||
proj-indented-notice {
|
||||
WARNING: Cannot find a usable tclConfig.sh file. Use
|
||||
--with-tcl=DIR to specify a directory where tclConfig.sh can be
|
||||
found. SQLite does not use TCL internally, but some optional
|
||||
components require TCL, including tests and sqlite3_analyzer.
|
||||
}
|
||||
}
|
||||
}; # sqlite-check-tcl
|
||||
|
||||
########################################################################
|
||||
# sqlite-determine-codegen-tcl checks which TCL to use as a code
|
||||
# generator. By default, prefer jimsh simply because we have it
|
||||
# in-tree (it's part of autosetup) unless --with-tclsh=X is used, in
|
||||
# which case prefer X.
|
||||
#
|
||||
# Returns the human-readable name of the TCL it selects. Fails fatally
|
||||
# if it cannot detect a TCL appropriate for code generation.
|
||||
#
|
||||
# Defines:
|
||||
#
|
||||
# - BTCLSH = the TCL shell used for code generation. It may set this
|
||||
# to an unexpanded makefile var name.
|
||||
#
|
||||
# - CFLAGS_JIMSH = any flags needed for buildng a BTCLSH-compatible
|
||||
# jimsh. The defaults may be passed on to configure as
|
||||
# CFLAGS_JIMSH=...
|
||||
proc sqlite-determine-codegen-tcl {} {
|
||||
msg-result "Checking for TCL to use for code generation... "
|
||||
define CFLAGS_JIMSH [proj-get-env CFLAGS_JIMSH {-O1}]
|
||||
set cgtcl [opt-val with-tclsh jimsh]
|
||||
if {"jimsh" ne $cgtcl} {
|
||||
# When --with-tclsh=X is used, use that for all TCL purposes,
|
||||
# including in-tree code generation, per developer request.
|
||||
define BTCLSH "\$(TCLSH_CMD)"
|
||||
return $cgtcl
|
||||
}
|
||||
set flagsToRestore {CC CFLAGS AS_CFLAGS CPPFLAGS AS_CPPFLAGS LDFLAGS LINKFLAGS LIBS CROSS}
|
||||
define-push $flagsToRestore {
|
||||
# We have to swap CC to CC_FOR_BUILD for purposes of the various
|
||||
# [cc-...] tests below. Recall that --with-wasi-sdk may have
|
||||
# swapped out CC with one which is not appropriate for this block.
|
||||
# Per consulation with autosetup's creator, doing this properly
|
||||
# requires us to [define-push] the whole $flagsToRestore list
|
||||
# (plus a few others which are not relevant in this tree).
|
||||
#
|
||||
# These will get set to their previous values at the end of this
|
||||
# block.
|
||||
foreach flag $flagsToRestore {define $flag ""}
|
||||
define CC [get-define CC_FOR_BUILD]
|
||||
# These headers are technically optional for JimTCL but necessary if
|
||||
# we want to use it for code generation:
|
||||
set sysh [cc-check-includes dirent.h sys/time.h]
|
||||
# jimsh0.c hard-codes #define's for HAVE_DIRENT_H and
|
||||
# HAVE_SYS_TIME_H on the platforms it supports, so we do not
|
||||
# need to add -D... flags for those. We check for them here only
|
||||
# so that we can avoid the situation that we later, at
|
||||
# make-time, try to compile jimsh but it then fails due to
|
||||
# missing headers (i.e. fail earlier rather than later).
|
||||
if {$sysh && [cc-check-functions realpath]} {
|
||||
define-append CFLAGS_JIMSH -DHAVE_REALPATH
|
||||
define BTCLSH "\$(JIMSH)"
|
||||
set ::sqliteConfig(use-jim-for-codegen) 1
|
||||
} elseif {$sysh && [cc-check-functions _fullpath]} {
|
||||
# _fullpath() is a Windows API. It's not entirely clear
|
||||
# whether we need to add {-DHAVE_SYS_TIME_H -DHAVE_DIRENT_H}
|
||||
# to CFLAGS_JIMSH in this case. On MinGW32 we definitely do
|
||||
# not want to because it already hard-codes them. On _MSC_VER
|
||||
# builds it does not.
|
||||
define-append CFLAGS_JIMSH -DHAVE__FULLPATH
|
||||
define BTCLSH "\$(JIMSH)"
|
||||
set ::sqliteConfig(use-jim-for-codegen) 1
|
||||
} elseif {[file-isexec [get-define TCLSH_CMD]]} {
|
||||
set cgtcl [get-define TCLSH_CMD]
|
||||
define BTCLSH "\$(TCLSH_CMD)"
|
||||
} else {
|
||||
# One last-ditch effort to find TCLSH_CMD: use info from
|
||||
# tclConfig.sh to try to find a tclsh
|
||||
if {"" eq [get-define TCLSH_CMD]} {
|
||||
set tpre [get-define TCL_EXEC_PREFIX]
|
||||
if {"" ne $tpre} {
|
||||
set tv [get-define TCL_VERSION]
|
||||
if {[file-isexec "${tpre}/bin/tclsh${tv}"]} {
|
||||
define TCLSH_CMD "${tpre}/bin/tclsh${tv}"
|
||||
} elseif {[file-isexec "${tpre}/bin/tclsh"]} {
|
||||
define TCLSH_CMD "${tpre}/bin/tclsh"
|
||||
}
|
||||
}
|
||||
}
|
||||
set cgtcl [get-define TCLSH_CMD]
|
||||
if {![file-isexec $cgtcl]} {
|
||||
proj-fatal "Cannot find a tclsh to use for code generation."
|
||||
}
|
||||
define BTCLSH "\$(TCLSH_CMD)"
|
||||
}
|
||||
}; # CC swap-out
|
||||
return $cgtcl
|
||||
}; # sqlite-determine-codegen-tcl
|
||||
|
||||
########################################################################
|
||||
# Runs sqlite-check-tcl and sqlite-determine-codegen-tcl.
|
||||
proc sqlite-handle-tcl {} {
|
||||
sqlite-check-tcl
|
||||
msg-result "TCL for code generation: [sqlite-determine-codegen-tcl]"
|
||||
}
|
||||
|
||||
########################################################################
|
||||
# If the --dump-defines configure flag is provided then emit a list of
|
||||
# all [define] values to config.defines.txt, else do nothing.
|
||||
proc sqlite-dump-defines {} {
|
||||
proj-if-opt-truthy dump-defines {
|
||||
make-config-header $::sqliteConfig(dump-defines-txt) \
|
||||
-bare {SQLITE_OS* SQLITE_DEBUG USE_*} \
|
||||
-str {BIN_* CC LD AR LDFLAG* OPT_*} \
|
||||
-auto {*}
|
||||
# achtung: ^^^^ whichever SQLITE_OS_foo flag which is set to 0 will
|
||||
# get _undefined_ here unless it's part of the -bare set.
|
||||
if {"" ne $::sqliteConfig(dump-defines-json)} {
|
||||
msg-result "--dump-defines is creating $::sqliteConfig(dump-defines-json)"
|
||||
########################################################################
|
||||
# Dump config-defines.json...
|
||||
# Demonstrate (mis?)handling of spaces in JSON-export array values:
|
||||
# define-append OPT_FOO.list {"-DFOO=bar baz" -DBAR="baz barre"}
|
||||
define OPT_FEATURE_FLAGS.list [get-define OPT_FEATURE_FLAGS]
|
||||
define OPT_SHELL.list [get-define OPT_SHELL]
|
||||
set dumpDefsOpt {
|
||||
-bare {SIZEOF_* HAVE_DECL_*}
|
||||
-none {HAVE_CFLAG_* LDFLAGS_* SH_* SQLITE_AUTORECONFIG TARGET_* USE_GCOV TCL_*}
|
||||
-array {*.list}
|
||||
-auto {OPT_* PACKAGE_* HAVE_*}
|
||||
}
|
||||
if {[opt-bool defines-json-include-lowercase]} {
|
||||
lappend dumpDefsOpt -none {lib_*} ; # remnants from proj-check-function-in-lib and friends
|
||||
lappend dumpDefsOpt -auto {[a-z]*}
|
||||
}
|
||||
lappend dumpDefsOpt -none *
|
||||
proj-dump-defs-json $::sqliteConfig(dump-defines-json) {*}$dumpDefsOpt
|
||||
undefine OPT_FEATURE_FLAGS.list
|
||||
undefine OPT_SHELL.list
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user