aa7c9050fa
FossilOrigin-Name: ce6bc4603c27952ca44ff55c81dd50a04b0f6ef8f198720ee0da3aff4c291449
1022 lines
34 KiB
Modula-2
1022 lines
34 KiB
Modula-2
#/usr/bin/tclsh
|
|
# ^^^ help out editors which guess this file's content type.
|
|
#
|
|
# This is the main autosetup-compatible configure script for the
|
|
# SQLite project.
|
|
#
|
|
# This script should be kept compatible with JimTCL, a copy of which
|
|
# is included in this source tree as ./autosetup/jimsh0.c. The number
|
|
# of incompatibilities between canonical TCL and JimTCL is very low
|
|
# and alternative formulations of incompatible constructs have, so
|
|
# far, been easy to find.
|
|
#
|
|
# JimTCL: https://jim.tcl.tk
|
|
#
|
|
use cc cc-db cc-shared cc-lib hwaci-common pkg-config
|
|
set DUMP_DEFINES_FILE ./defines.list
|
|
|
|
########################################################################
|
|
# Regarding flag compatibility with the historical autotool configure
|
|
# script:
|
|
#
|
|
# A very long story made short, autosetup's --flag handling has
|
|
# some behaviors which make it impossible to implement 100% identical
|
|
# flags compared to the historical autotools build. The differences
|
|
# are documented here:
|
|
#
|
|
# 1) --debug is used by autosetup itself, so we have to rename it to
|
|
# --with-debug. We cannot use --enable-debug because that is, for
|
|
# autosetup, and alias for --debug=1.
|
|
#
|
|
# 2) In autosetup, all flags starting with (--enable, --disable) are
|
|
# forced to be booleans and receive special handling in how they're
|
|
# resolved. Because of that we have to rename:
|
|
#
|
|
# 2.1) --enable-tempstore[=no] to --with-tempstore[=no].
|
|
#
|
|
########################################################################
|
|
# A gentle introduction to flags handling in autosetup
|
|
#
|
|
# Reference: https://msteveb.github.io/autosetup/developer/
|
|
#
|
|
# All configure flags must be described in an 'options' call, which
|
|
# must appear very early on in this script. The general syntax is:
|
|
#
|
|
# FLAG => {Help text}
|
|
#
|
|
# Where FLAG can have any of the following formats:
|
|
#
|
|
# boolopt => "a boolean option which defaults to disabled"
|
|
# boolopt2=1 => "a boolean option which defaults to enabled"
|
|
# stringopt: => "an option which takes an argument, e.g. --stringopt=value"
|
|
# stringopt2:=value => "an option where the argument is optional and defaults to 'value'"
|
|
# optalias booltopt3 => "a boolean with a hidden alias. --optalias is not shown in --help"
|
|
#
|
|
# Autosetup does no small amount of specialized handling for flags,
|
|
# especially booleans. Each bool-type --FLAG implicitly gets
|
|
# --enable-FLAG and --disable-FLAG forms, and explicitly adding flags
|
|
# with those prefixes will force them to be boolean flags. e.g. we
|
|
# define a flag "readline", which will be interpreted in one of two
|
|
# ways, depending on how it's invoked and how its default is defined:
|
|
#
|
|
# --enable-readline ==> boolean true
|
|
# --disable-readline ==> boolean false
|
|
#
|
|
# Trying to pass --readline or --readline=1 or --readline=0 will
|
|
# result in an "unrecognized option" error, despite the the options
|
|
# call listing the flag as "readline".
|
|
#
|
|
# The behavior described above can lead lead to some confusion when
|
|
# writing help text. For example:
|
|
#
|
|
# options { json=1 {Disable JSON functions} }
|
|
#
|
|
# The reason the help text says "disable" is because a boolean option
|
|
# defaulting to true is, in the --help text, rendered as:
|
|
#
|
|
# --disable-json Disable JSON functions
|
|
#
|
|
# Whereas a bool flag which defaults to false will instead render as:
|
|
#
|
|
# --enable-FLAG
|
|
#
|
|
# Non-boolean flags, in contrast, use the names specifically given to
|
|
# them in the 'options' invocation. e.g. "with-tcl" is the --with-tcl
|
|
# flag. Autosetup may, however, choose to automatically alter the help
|
|
# text, as demonstrated here:
|
|
#
|
|
# options {
|
|
# readline=1 => {Disable readline support}
|
|
# with-readline-lib: => {Readline library}
|
|
# with-readline-inc: => {Readline include paths}
|
|
# }
|
|
#
|
|
# $ ./configure --help | grep readline
|
|
# --disable-readline disable readline support
|
|
# --with-readline-lib specify readline library
|
|
# --with-readline-inc specify readline include paths
|
|
#
|
|
# Note that it prefixed and lower-case the help message. Whether
|
|
# that's a feature or a bug can be debated.
|
|
#
|
|
# Fetching values for flags:
|
|
#
|
|
# booleans: use one of:
|
|
# - [opt-bool FLAG] is autosetup's built-in command for this, but we
|
|
# have some convenience variants:
|
|
# - [hwaci-opt-truthy FLAG]
|
|
# - [hwaci-opt-if-truthy FLAG {THEN} {ELSE}]
|
|
#
|
|
# Non-boolean (i.e. string) flags:
|
|
# - [opt-val FLAG]
|
|
#
|
|
########################################################################
|
|
options [subst {
|
|
with-debug:=1 => {Enable debug build flags}
|
|
with-tclsh:PATH => {Full pathname of tclsh to use}
|
|
with-tcl:DIR => {Directory containing tclConfig.sh}
|
|
tcl=1 => {Disable components which require TCL-dev}
|
|
test-status => {Enable status of tests}
|
|
threadsafe=1 => {Disable mutexing}
|
|
with-tempstore:=no => {Use an in-ram database for temporary tables: never,no,yes,always.}
|
|
editline=0 => {BSD editline support}
|
|
readline=1 => {Disable readline support}
|
|
largefile=1 => {Disable large file support}
|
|
with-readline-lib: => {Readline library}
|
|
with-readline-inc: => {Readline include paths}
|
|
with-linenoise:DIR => {}
|
|
amalgamation=1 => {Disable the amalgamation and instead build all files separately}
|
|
load-extension=1 => {Disable loading of external extensions}
|
|
math=1 => {Disable math functions}
|
|
json=1 => {Disable JSON functions}
|
|
all => {Enable FTS4, FTS5, Geopoly, RTree, Sessions}
|
|
memsys5 => {Enable MEMSYS5}
|
|
memsys3 => {Enable MEMSYS3}
|
|
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}
|
|
gcov=0 => {Enable coverage testing using gcov}
|
|
linemacros => {Enable #line macros in the amalgamation.}
|
|
with-wasi-sdk:=/opt/wasi-sdk
|
|
=> {Top-most dir of the wasi-sdk for a WASI build.}
|
|
with-emsdk:DIR => {Top-most dir of the Emscripten SDK installation}
|
|
dump-defines=0 => {Dump autosetup defines to $DUMP_DEFINES_FILE (for build debugging)}
|
|
}]
|
|
|
|
# Are we cross-compiling?
|
|
set cross_compiling 0
|
|
if {[get-define host] ne [get-define build]} {
|
|
set cross_compiling 1
|
|
}
|
|
|
|
########################################################################
|
|
# Notes about certain historical flags:
|
|
#
|
|
# --releasemode: libtool-specific (which we don't have now)
|
|
#
|
|
#
|
|
set srcdir $::autosetup(srcdir)
|
|
set top_srcdir [get-define abs_top_srcdir]
|
|
msg-result "srcdir = $srcdir"
|
|
msg-result "top_srcdir = $top_srcdir"
|
|
set VERSION_XYZ [readfile $::autosetup(srcdir)/VERSION]
|
|
regsub {([0-9]*\.*[0-9]*).*} $VERSION_XYZ {\1} VERSION_XY
|
|
define VERSION_XY $VERSION_XY
|
|
define VERSION_XYZ $VERSION_XYZ
|
|
msg-result "RELEASE = $VERSION_XYZ"
|
|
msg-result "VERSION = $VERSION_XY"
|
|
|
|
define-append SQLITE_AUTOREMAKE cd $::autosetup(srcdir) && $top_srcdir/configure {*}$::autosetup(argv)
|
|
|
|
set outOfTreeBuild 0
|
|
if {![file exists sqlite3.pc.in]} {
|
|
msg-result "This appears to be an out-of-tree build."
|
|
set outOfTreeBuild 1
|
|
}
|
|
|
|
cc-check-tools ld ar
|
|
|
|
########################################################################
|
|
# The build process allows for using a cross-compiler. But the default
|
|
# action is to target the same platform that we are running on. The
|
|
# configure script needs to discover the following properties of the
|
|
# build and target systems:
|
|
#
|
|
# srcdir
|
|
#
|
|
# The is the name of the directory that contains the
|
|
# "configure" shell script. All source files are
|
|
# located relative to this directory.
|
|
#
|
|
# bindir
|
|
#
|
|
# The name of the directory where executables should be
|
|
# written by the "install" target of the makefile.
|
|
#
|
|
# program_prefix
|
|
#
|
|
# Add this prefix to the names of all executables that run
|
|
# on the target machine. Default: ""
|
|
#
|
|
# ENABLE_SHARED
|
|
#
|
|
# True if shared libraries should be generated.
|
|
#
|
|
# BUILD_CC
|
|
#
|
|
# The name of a command that is used to convert C
|
|
# source files into executables that run on the build
|
|
# platform.
|
|
#
|
|
# BUILD_CFLAGS
|
|
#
|
|
# Switches that the build compiler needs in order to construct
|
|
# command-line programs.
|
|
#
|
|
# BUILD_LIBS
|
|
#
|
|
# Libraries that the build compiler needs in order to construct
|
|
# command-line programs.
|
|
#
|
|
# TCL_*
|
|
#
|
|
# Lots of values are read in from the tclConfig.sh script,
|
|
# if that script is available. This values are used for
|
|
# constructing and installing the TCL extension.
|
|
#
|
|
# TARGET_READLINE_LIBS
|
|
#
|
|
# This is the library directives passed to the target linker
|
|
# that cause the executable to link against the readline library.
|
|
# This might be a switch like "-lreadline" or pathnames of library
|
|
# file like "../../src/libreadline.a".
|
|
#
|
|
# TARGET_READLINE_INC
|
|
#
|
|
# This variables define the directory that contain header
|
|
# files for the readline library. If the compiler is able
|
|
# to find <readline.h> on its own, then this can be blank.
|
|
|
|
#
|
|
# OPT_FEATURE_FLAGS = -DSQLITE_OMIT/ENABLE flags.
|
|
define OPT_FEATURE_FLAGS {}
|
|
define OPT_SHELL {}; # CFLAGS for the sqlite3 CLI app
|
|
|
|
# Adds $args, if not empty, to OPT_FEATURE_FLAGS.
|
|
proc add-feature-flag {args} {
|
|
if {"" ne $args} {
|
|
define-append OPT_FEATURE_FLAGS {*}$args
|
|
}
|
|
}
|
|
# add-feature-flag -DSQLITE_JUST_TESTING=3
|
|
|
|
# Adds $args, if not empty, to OPT_SHELL.
|
|
proc add-shell-opt {args} {
|
|
if {"" ne $args} {
|
|
define-append OPT_SHELL {*}$args
|
|
}
|
|
}
|
|
|
|
hwaci-file-extensions
|
|
if {".exe" eq [get-define TARGET_EXEEXT]} {
|
|
define SQLITE_OS_UNIX 0
|
|
define SQLITE_OS_WIN 1
|
|
# todo? add -DSQLITE_OS_WIN=1 to CFLAGS?
|
|
} else {
|
|
define SQLITE_OS_UNIX 1
|
|
define SQLITE_OS_WIN 0
|
|
# todo? add -DSQLITE_OS_UNIX=1 to CFLAGS?
|
|
}
|
|
|
|
#########
|
|
# Programs needed
|
|
if {"" eq [hwaci-bin-define install]} {
|
|
hwaci-warn "Cannot find install binary, so 'make install' will not work."
|
|
# Reminder: we historically have ./install-sh in the source tree.
|
|
# Can we not simply use that?
|
|
#
|
|
# define BIN_INSTALL "$top_srcdir/install-sh"
|
|
#
|
|
# Nope: it MOVES its source files over the target, which breaks the
|
|
# installation in some cases, e.g. when libtclsqlite3.so is built in
|
|
# response to 'make install' and libsqlite3.a is moved before
|
|
# libtclsqlite3.so is linked. It's easy to hack to use cp instead
|
|
# of mv (simply replace the instcmd=... bit) but that won't retain
|
|
# the source timestamp and permissions unless we use cp's -p flag,
|
|
# which may not be portable enough.
|
|
}
|
|
|
|
########################################################################
|
|
# We differentiate between two C compilers: the one used for binaries
|
|
# which are to run on the build system (BUILD_CC, a.k.a. BCC) and the
|
|
# one used for compiling binaries for the target system (CC,
|
|
# a.k.a. TCC). Normally they're the same, but they will differ when
|
|
# cross-compiling.
|
|
define BUILD_CC [get-define CC_FOR_BUILD]
|
|
define BUILD_CFLAGS [get-env CFLAGS {-g}]
|
|
define ENABLE_SHARED 1
|
|
define HAVE_TCL 0
|
|
|
|
########################################################################
|
|
# Handle --with-wasi-sdk=DIR
|
|
#
|
|
# This must be early because it may change the toolchain and disable
|
|
# several config options.
|
|
proc hwaci-check-wasi-sdk {} {
|
|
set wasiSdkDir [opt-val with-wasi-sdk] ; # ??? [lindex [opt-val with-wasi-sdk] end]
|
|
define HAVE_WASI_SDK 0
|
|
#puts "x wasiSdkDir=$wasiSdkDir foo=[lindex [opt-val with-wasi-sdk] end]"
|
|
if {$wasiSdkDir eq ""} {
|
|
return 0
|
|
} elseif {$::cross_compiling} {
|
|
hwaci-fatal "Cannot combine --with-wasi-sdk with cross-compilation"
|
|
}
|
|
msg-result "Checking WASI SDK directory \[$wasiSdkDir]... "
|
|
#puts "prefix = [prefix $wasiSdkDir/bin {clang ld}]"
|
|
hwaci-affirm-files-exist -v {*}[prefix "$wasiSdkDir/bin/" {clang wasm-ld}]
|
|
msg-result "Using wasi-sdk clang, disabling: tcl, CLI shell, DLL, loadable extensions, threading"
|
|
define HAVE_WASI_SDK 1
|
|
define WASI_SDK_DIR $wasiSdkDir
|
|
hwaci-opt-set load-extension 0; # ==> --disable-load-extension
|
|
hwaci-opt-set threadsafe 0; # ==> --threadsafe=0
|
|
hwaci-opt-set tcl 0; # ==> --disable-tcl
|
|
define HAVE_TCL 0
|
|
set cross_compiling 1
|
|
define ENABLE_SHARED 0
|
|
|
|
# Changing --host and --target have no effect here except to possibly
|
|
# cause confusion. autoconf has finished processing them by this
|
|
# point.
|
|
#
|
|
# host_alias=wasm32-wasi
|
|
# target=wasm32-wasi
|
|
#
|
|
# Merely changing CC and LD to the wasi-sdk's is enough to get
|
|
# sqlite3.o building in WASM format.
|
|
# XXX CC="${wasiSdkDir}/bin/clang"
|
|
# XXX LD="${wasiSdkDir}/bin/wasm-ld"
|
|
# XXX RANLIB="${wasiSdkDir}/bin/llvm-ranlib"
|
|
define CC "${wasiSdkDir}/bin/clang"
|
|
define LD "${wasiSdkDir}/bin/wasm-ld"
|
|
#define STRIP "${wasiSdkDir}/bin/strip"
|
|
return 1
|
|
}; # hwaci-check-wasi-sdk
|
|
hwaci-check-wasi-sdk
|
|
|
|
#
|
|
# Enable large file support (if special flags are necessary)
|
|
cc-check-lfs
|
|
|
|
#
|
|
# Check for needed/wanted data types
|
|
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
|
|
|
|
hwaci-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 \
|
|
stdint.h inttypes.h
|
|
|
|
# These are optional for JimTCL but necessary if we want to use it for
|
|
# code generation:
|
|
cc-check-includes dirent.h sys/time.h
|
|
|
|
if {[cc-check-includes zlib.h] && [hwaci-check-function-in-lib deflate z]} {
|
|
# TODO: port over the more sophisticated zlib search from the fossil auto.def
|
|
define HAVE_ZLIB 1; # "-DSQLITE_HAVE_ZLIB=1"
|
|
define LDFLAGS_ZLIB -lz
|
|
# Note that -DSQLITE_HAVE_ZLIB=1 is handled separately from the
|
|
# other feature flags in the autotools build. Do we need to emulate
|
|
# that?
|
|
add-shell-opt -DSQLITE_HAVE_ZLIB=1
|
|
} else {
|
|
define HAVE_ZLIB 0
|
|
define LDFLAGS_ZLIB ""
|
|
}
|
|
|
|
hwaci-define-if-opt-truthy amalgamation USE_AMALGAMATION \
|
|
"Use amalgamation for builds?"
|
|
|
|
hwaci-define-if-opt-truthy gcov USE_GCOV "Use gcov?"
|
|
|
|
hwaci-define-if-opt-truthy test-status TSTRNNR_OPTS \
|
|
"test-runner flags:" {--status} {}
|
|
|
|
hwaci-define-if-opt-truthy linemacros AMALGAMATION_LINE_MACROS \
|
|
"Use #line macros in the amalgamation:"
|
|
|
|
msg-checking "Debug build? "
|
|
|
|
hwaci-if-opt-truthy with-debug {
|
|
define SQLITE_DEBUG 1
|
|
define TARGET_DEBUG {-g -DSQLITE_DEBUG=1 -DSQLITE_ENABLE_SELECTTRACE -DSQLITE_ENABLE_WHERETRACE -O0 -Wall}
|
|
msg-result yes
|
|
} {
|
|
define TARGET_DEBUG {-DNDEBUG}
|
|
msg-result no
|
|
}
|
|
|
|
########################################################################
|
|
# TCL...
|
|
#
|
|
# hwaci-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.
|
|
#
|
|
# - TCLLIB_RPATH = the -rpath flag specific to libtclsqlite3, which
|
|
# will usually differ from the rpath used by the rest of the lib.
|
|
#
|
|
# - 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.
|
|
#
|
|
define TCLSH_CMD {exit 1}
|
|
proc hwaci-check-tcl {} {
|
|
# TODO: document the steps this is taking.
|
|
global top_srcdir
|
|
puts "Checking for a suitable tcl... "
|
|
set optTcl [hwaci-opt-truthy tcl]
|
|
set use_tcl $optTcl
|
|
set with_tclsh [opt-val with-tclsh]
|
|
set with_tcl [opt-val with-tcl]
|
|
#puts "hwaci-check-tcl: use_tcl ${use_tcl}"
|
|
#puts "hwaci-check-tcl: with_tclsh=${with_tclsh}"
|
|
#puts "hwaci-check-tcl: with_tcl=$with_tcl"
|
|
if {"" eq $with_tclsh && "" eq $with_tcl} {
|
|
set with_tclsh [hwaci-first-bin-of tclsh9.0 tclsh8.6 tclsh]
|
|
}
|
|
#puts "hwaci-check-tcl: with_tclsh=${with_tclsh}"
|
|
|
|
if {"" ne $with_tclsh} {
|
|
if {![file isfile $with_tclsh]} {
|
|
hwaci-fatal "TCL shell $with_tclsh is not a file"
|
|
} elseif {![file-isexec $with_tclsh]} {
|
|
hwaci-fatal "TCL shell $with_tclsh is not executable"
|
|
} else {
|
|
define TCLSH_CMD $with_tclsh
|
|
msg-result "Using tclsh: $with_tclsh"
|
|
}
|
|
if {$use_tcl} {
|
|
if {[catch {exec $with_tclsh $top_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 {
|
|
hwaci-warn "$with_tclsh is unable to recommand a tclConfig.sh"
|
|
set use_tcl 0
|
|
}
|
|
}
|
|
}
|
|
|
|
set cfg ""
|
|
set tclSubdirs {tcl9.0 tcl8.6 lib}
|
|
while {1} {
|
|
if {$use_tcl} {
|
|
if {"" ne $with_tcl} {
|
|
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} {
|
|
hwaci-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]} {
|
|
hwaci-warn {
|
|
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 TCL is required to build SQLite
|
|
from canonical sources and TCL is required for testing.
|
|
}
|
|
break
|
|
}
|
|
}
|
|
msg-result "Using tclConfig.sh: $cfg"
|
|
} elseif {!$optTcl} {
|
|
hwaci-warn "Unable to run tests because of --disable-tcl"
|
|
} else {
|
|
hwaci-warn "Unable to run tests because no tclConfig.sh file could be located"
|
|
}
|
|
break
|
|
}
|
|
|
|
define TCL_CONFIG_SH $cfg
|
|
# The historical configure.ac sources tclConfig.sh so that it can
|
|
# use the several TCL_... env vars. We obviously cannot do that from
|
|
# TCL, so we apply a level of indirection which sources that script
|
|
# then emits the pieces we're interested in as TCL code. If the
|
|
# config is not available, this emits empty-string entries for the
|
|
# various options we're interested in.
|
|
eval [exec "${top_srcdir}/tool/tclConfigShToTcl.sh" "[get-define TCL_CONFIG_SH]"]
|
|
#puts "hwaci-check-tcl: with_tclsh=$with_tclsh"
|
|
#puts "hwaci-check-tcl: with_tcl=$with_tcl"
|
|
#puts "hwaci-check-tcl: cfg=$cfg"
|
|
#puts "hwaci-check-tcl: use_tcl ${use_tcl}"
|
|
|
|
if {"" eq $with_tclsh} {
|
|
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]} {
|
|
hwaci-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 and TCLLIB_RPATH
|
|
set tcllibdir [get-env TCLLIBDIR ""]
|
|
if {"" eq $tcllibdir} {
|
|
if {[catch {exec echo "puts stdout \$auto_path" | "$with_tclsh"} result] == 0} {
|
|
foreach i $result {
|
|
if {[file isdir $i]} {
|
|
set tcllibdir $i
|
|
break
|
|
}
|
|
}
|
|
} else {
|
|
hwaci-warn "Cannot determine TCLLIBDIR"
|
|
}
|
|
}
|
|
set tclrpath ""
|
|
if {"" ne $tcllibdir} {
|
|
set tcllibdir "${tcllibdir}/sqlite3"
|
|
set rp [get-define SH_LINKRPATH]
|
|
set tclrpath [string map [list "%s" $tcllibdir] $rp]
|
|
# Reminder: tclConfig.sh has TCL_LD_SEARCH_FLAGS to set the
|
|
# rpath but (A) it includes an unexpand var ref to
|
|
# ${LIB_RUNTIME_DIR}, which must be set in the makefile and (B)
|
|
# that flag is inherently compiler-dependent so it's not as
|
|
# portable as tclConfig.sh assumes. We'll instead use the rpath
|
|
# flag which autosetup determines for the current compiler.
|
|
}
|
|
define TCLLIBDIR $tcllibdir
|
|
define TCLLIB_RPATH $tclrpath
|
|
#hwaci-fatal "TCLLIB_RPATH = [get-define TCLLIB_RPATH]"
|
|
} else {
|
|
define TCLLIBDIR ""
|
|
define TCLLIB_RPATH ""
|
|
}
|
|
|
|
if {[file exists $with_tclsh]} {
|
|
msg-result "Using tclsh: $with_tclsh"
|
|
define HAVE_TCL 1
|
|
} else {
|
|
hwaci-warn "Cannot find a usable tclsh, so cannot run tests."
|
|
}
|
|
}; # hwaci-check-tcl
|
|
|
|
hwaci-check-tcl
|
|
|
|
########################################################################
|
|
# Check which TCL to use as a code generator. Prefer jimsh simply
|
|
# because we have it in-tree (it's part of autosetup).
|
|
#
|
|
# Building jimsh0.c with -DJIM_COMPAT changes certain behavior to be
|
|
# compatible with canonical TCL. Specifically: jim's [expr] only
|
|
# accepts one arg unless JIM_COMPAT is defined. As of 2024-10-23,
|
|
# jimsh0.c defines JIM_COMPAT automatically (prior to that it intended
|
|
# to but a typo of JIM_TCL_COMPAT made it a no-op).
|
|
define CFLAGS_JIMSH {}
|
|
set useOwnJimsh 0
|
|
msg-result "Which TCL to use for code generation... "
|
|
set cgtcl jimtcl
|
|
if {[cc-check-functions realpath]} {
|
|
define-append CFLAGS_JIMSH -DHAVE_REALPATH
|
|
define BTCLSH "\$(JIMSH)"
|
|
set useOwnJimsh 1
|
|
} elseif {[cc-check-functions _fullpath]} {
|
|
# _fullpath() is a Windows API
|
|
define-append CFLAGS_JIMSH -DHAVE__FULLPATH
|
|
define BTCLSH "\$(JIMSH)"
|
|
set useOwnJimsh 1
|
|
} elseif {[file exists [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"
|
|
}
|
|
unset tv
|
|
}
|
|
unset tpre
|
|
}
|
|
set cgtcl [get-define TCLSH_CMD]
|
|
if {![file exists $cgtcl]} {
|
|
hwaci-fatal "Cannot find a tclsh to use for code generation."
|
|
}
|
|
define BTCLSH "\$(TCLSH_CMD)"
|
|
}
|
|
msg-result "TCL for code generation: $cgtcl"
|
|
unset cgtcl
|
|
#define CFLAGS_JIMSH {-DJUST_TESTING}
|
|
|
|
# /TCL
|
|
########################################################################
|
|
|
|
########################################################################
|
|
# Thread safety?
|
|
msg-checking "Support threadsafe operation? "
|
|
hwaci-if-opt-truthy threadsafe {
|
|
msg-result yes
|
|
add-feature-flag -DSQLITE_THREADSAFE=1
|
|
if {![hwaci-check-function-in-lib pthread_create pthread]
|
|
|| ![hwaci-check-function-in-lib pthread_mutexattr_init pthread]} {
|
|
user-error "Missing required pthread bits"
|
|
}
|
|
define LDFLAGS_PTHREAD [get-define lib_pthread_create]
|
|
undefine lib_pthread_create
|
|
} {
|
|
msg-result no
|
|
add-feature-flag -DSQLITE_THREADSAFE=0
|
|
define LDFLAGS_PTHREAD ""
|
|
}
|
|
|
|
########################################################################
|
|
# Do we want temporary databases in memory?
|
|
#
|
|
if {1} {
|
|
set ts [opt-val with-tempstore no]
|
|
set tsn 1
|
|
msg-checking "Use an in-ram database for temporary tables? "
|
|
switch -- $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
|
|
define TEMP_STORE $tsn
|
|
unset ts tsn
|
|
}
|
|
|
|
if {1} {
|
|
##########
|
|
# Figure out what C libraries are required to compile programs
|
|
# that use "readline()" library.
|
|
add-shell-opt -DHAVE_READLINE=[hwaci-check-readline]
|
|
} else {
|
|
# Older impl solely for reference while porting...
|
|
#
|
|
# XXX TARGET_READLINE_LIBS=""
|
|
# XXX TARGET_READLINE_INC=""
|
|
# XXX TARGET_HAVE_READLINE=0
|
|
# XXX TARGET_HAVE_EDITLINE=0
|
|
if {[opt-bool editline]} {
|
|
set with_editline $enableval
|
|
} else {
|
|
set with_editline auto
|
|
}
|
|
if {![opt-bool readline]} {
|
|
set with_readline $enableval
|
|
} else {
|
|
set with_readline auto
|
|
}
|
|
|
|
# XXX if test x"$with_editline" != xno; then
|
|
# XXX sLIBS=$LIBS
|
|
# XXX LIBS=""
|
|
# XXX TARGET_HAVE_EDITLINE=1
|
|
if {[hwaci-check-function-in-lib readline edit]} {
|
|
set with_readline no
|
|
} else {
|
|
# XXX TARGET_HAVE_EDITLINE=0
|
|
}
|
|
# XXX TARGET_READLINE_LIBS=$LIBS
|
|
# XXX LIBS=$sLIBS
|
|
# XXX fi
|
|
# XXX if test x"$with_readline" != xno; then
|
|
set found "yes"
|
|
|
|
if {[opt-val with-readline-lib] ne {}} {
|
|
set withval [lindex [opt-val with-readline-lib] end]
|
|
set with_readline_lib $withval
|
|
} else {
|
|
set with_readline_lib "auto"
|
|
}
|
|
# XXX if test "x$with_readline_lib" = xauto; then
|
|
# XXX save_LIBS="$LIBS"
|
|
# XXX LIBS=""
|
|
if {[hwaci-check-function-in-lib tgetent readline ncurses curses termcap]} {
|
|
# XXX term_LIBS="$LIBS"
|
|
} else {
|
|
# XXX term_LIBS=""
|
|
}
|
|
if {[hwaci-check-function-in-lib readline readline]} {
|
|
# XXX TARGET_READLINE_LIBS="-lreadline"
|
|
} else {
|
|
set found "no"
|
|
}
|
|
# XXX TARGET_READLINE_LIBS="$TARGET_READLINE_LIBS $term_LIBS"
|
|
# XXX LIBS="$save_LIBS"
|
|
# XXX else
|
|
# XXX TARGET_READLINE_LIBS="$with_readline_lib"
|
|
# XXX fi
|
|
|
|
if {[opt-val with-readline-inc] ne {}} {
|
|
set withval [lindex [opt-val with-readline-inc] end]
|
|
set with_readline_inc $withval
|
|
} else {
|
|
set with_readline_inc "auto"
|
|
}
|
|
# XXX if test "x$with_readline_inc" = xauto; then
|
|
if {[cc-check-includes readline.h]} {
|
|
set found "yes"
|
|
} else {
|
|
set found "no"
|
|
# XXX if test "$cross_compiling" != yes; then
|
|
# XXX for dir in /usr /usr/local /usr/local/readline /usr/contrib /mingw; do
|
|
# XXX for subdir in include include/readline; do
|
|
# XXX AC_CHECK_FILE $dir/$subdir/readline.h found=yes
|
|
# XXX if test "$found" = "yes"; then
|
|
# XXX TARGET_READLINE_INC="-I$dir/$subdir"
|
|
# XXX break
|
|
# XXX fi
|
|
# XXX done
|
|
# XXX test "$found" = "yes" && break
|
|
# XXX done
|
|
# XXX fi
|
|
}
|
|
# XXX else
|
|
# XXX TARGET_READLINE_INC="$with_readline_inc"
|
|
# XXX fi
|
|
|
|
# XXX if test x"$found" = xno; then
|
|
# XXX TARGET_READLINE_LIBS=""
|
|
# XXX TARGET_READLINE_INC=""
|
|
# XXX TARGET_HAVE_READLINE=0
|
|
# XXX else
|
|
# XXX TARGET_HAVE_READLINE=1
|
|
# XXX fi
|
|
# XXX fi
|
|
if {[opt-val with-linenoise] ne {}} {
|
|
set withval [lindex [opt-val with-linenoise] end]
|
|
set with_linenoise $withval
|
|
} else {
|
|
set with_linenoise "no"
|
|
}
|
|
# XXX if test "x$with_linenoise" != "xno"; then
|
|
# XXX TARGET_HAVE_READLINE=0
|
|
# XXX TARGET_HAVE_EDITLINE=0
|
|
# XXX TARGET_HAVE_LINENOISE=1
|
|
# XXX TARGET_READLINE_INC="-I${with_linenoise}"
|
|
# XXX TARGET_READLINE_LIBS="${with_linenoise}/linenoise.c"
|
|
# XXX echo "using linenoise source code at ${with_linenoise}"
|
|
# XXX else
|
|
# XXX TARGET_HAVE_LINENOISE=0
|
|
# XXX echo "not using linenoise"
|
|
# XXX fi
|
|
|
|
# XXX AC_SUBST TARGET_READLINE_LIBS
|
|
# XXX AC_SUBST TARGET_READLINE_INC
|
|
# XXX AC_SUBST TARGET_HAVE_READLINE
|
|
# XXX AC_SUBST TARGET_HAVE_EDITLINE
|
|
# XXX AC_SUBST TARGET_HAVE_LINENOISE
|
|
}
|
|
|
|
hwaci-if-opt-truthy load-extension {
|
|
if {[hwaci-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 ""
|
|
add-feature-flag {-DSQLITE_OMIT_LOAD_EXTENSION=1}
|
|
msg-result "Disabling loadable extensions."
|
|
}
|
|
|
|
hwaci-if-opt-truthy math {
|
|
if {![hwaci-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
|
|
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"
|
|
}
|
|
|
|
define cross_compiling ${cross_compiling}
|
|
|
|
########################################################################
|
|
# Emscripten SDK for building the web-based wasm components.
|
|
#
|
|
set emccsh $srcdir/tool/emcc.sh
|
|
if {![get-define HAVE_WASI_SDK] && [hwaci-check-emsdk]} {
|
|
define EMCC_WRAPPER $emccsh
|
|
hwaci-make-from-dot-in $emccsh
|
|
catch {exec chmod u+x $emccsh}
|
|
} else {
|
|
define EMCC_WRAPPER ""
|
|
file delete -force $emccsh
|
|
}
|
|
unset emccsh
|
|
|
|
########################################################################
|
|
# Check for log(3) in libm and die with an error if it is not
|
|
# found. $why 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 affirm-have-math {why} {
|
|
if {![hwaci-check-function-in-lib log m]} {
|
|
user-error "Missing math APIs for $why"
|
|
}
|
|
define LDFLAGS_MATH [get-define lib_log ""]
|
|
undefine lib_log
|
|
}
|
|
|
|
########################################################################
|
|
# Handle various SQLITE_ENABLE_... feature flags.
|
|
foreach {boolFlag featureFlag ifSetEvalThis} {
|
|
all {} {
|
|
hwaci-opt-set fts4
|
|
hwaci-opt-set fts5
|
|
hwaci-opt-set geopoly
|
|
hwaci-opt-set rtree
|
|
hwaci-opt-set session
|
|
}
|
|
fts4 -DSQLITE_ENABLE_FTS4 {affirm-have-math fts4}
|
|
fts5 -DSQLITE_ENABLE_FTS5 {affirm-have-math fts5}
|
|
geopoly -DSQLITE_ENABLE_GEOPOLY {hwaci-opt-set rtree}
|
|
rtree -DSQLITE_ENABLE_RTREE {}
|
|
session {-DSQLITE_ENABLE_SESSION -DSQLITE_ENABLE_PREUPDATE_HOOK} {}
|
|
update-limit -DSQLITE_ENABLE_UPDATE_DELETE_LIMIT {}
|
|
memsys3 {} {
|
|
if {[opt-bool memsys5]} {
|
|
msg-result "NOT enabling memsys3 because memsys5 is enabled."
|
|
} else {
|
|
add-feature-flag -DSQLITE_ENABLE_MEMSYS3
|
|
}
|
|
}
|
|
memsys5 -DSQLITE_ENABLE_MEMSYS5 {}
|
|
} {
|
|
hwaci-if-opt-truthy $boolFlag {
|
|
add-feature-flag $featureFlag
|
|
eval $ifSetEvalThis
|
|
if {"all" ne $boolFlag} {
|
|
msg-result "Enabling $boolFlag"
|
|
}
|
|
} {
|
|
msg-result "Not enabling $boolFlag"
|
|
}
|
|
}
|
|
|
|
########################################################################
|
|
# Invert the above loop's logic for some explicit SQLITE_OMIT_...
|
|
# cases. If config option $boolFlag is set, [add-feature-flag
|
|
# $featureFlag], where $featureFlag is intended to be
|
|
# -DSQLITE_OMIT_...
|
|
foreach {boolFlag featureFlag} {
|
|
json -DSQLITE_OMIT_JSON
|
|
} {
|
|
if {[hwaci-opt-truthy $boolFlag]} {
|
|
msg-result "Enabling $boolFlag"
|
|
} else {
|
|
add-feature-flag $featureFlag
|
|
msg-result "Disabling $boolFlag"
|
|
}
|
|
}
|
|
|
|
########################################################################
|
|
# Maybe extend JimTCL a bit. As of this writing (2024-09-27) it only
|
|
# needs (-DHAVE_REALPATH or -DHAVE__FULLPATH) and -DHAVE_DIRENT_H to
|
|
# be compatible with our code generators. It can, however, be slightly
|
|
# extended via easy-to-detect features, should we need them.
|
|
if {0 && "" ne [get-define CFLAGS_JIMSH]} {
|
|
foreach jimFunc {opendir fsync isascii} {
|
|
if {[cc-check-functions $jimFunc]} {
|
|
define-append CFLAGS_JIMSH -DHAVE_[string toupper $jimFunc]
|
|
}
|
|
}
|
|
#These are hard-coded into jimsh0.c, so we must not -D them:
|
|
#foreach jimDef {HAVE_UNISTD_H HAVE_DIRENT_H} {
|
|
# if {[is-defined $jimDef]} {
|
|
# define-append CFLAGS_JIMSH -D$jimDef
|
|
# }
|
|
#}
|
|
define-append CFLAGS_JIMSH -DHAVE_LONG_LONG; # SQLite relies on long long, so we know it's available
|
|
}; # JimTCL
|
|
|
|
########################################################################
|
|
# Determine proper rpath-handling flags
|
|
hwaci-check-rpath
|
|
|
|
########################################################################
|
|
# Generate the output files.
|
|
#
|
|
hwaci-make-from-dot-in -touch Makefile sqlite3.pc
|
|
# for sqlite_cfg.h and config-defs.json
|
|
define PACKAGE_URL {https://sqlite.org}
|
|
define PACKAGE_VERSION [get-define VERSION_XYZ]
|
|
define PACKAGE_STRING "sqlite [get-define VERSION_XYZ]"
|
|
define PACKAGE_BUGREPORT [get-define PACKAGE_URL]
|
|
if {0} {
|
|
# Requires a hand-written sqlite_cfg.h.in...
|
|
hwaci-make-from-dot-in sqlite_cfg.h
|
|
# vs...
|
|
} else {
|
|
# Requires no input template...
|
|
make-config-header sqlite_cfg.h \
|
|
-bare {SIZEOF_* HAVE_DECL_*} \
|
|
-none {HAVE_CFLAG_* LDFLAGS_* SH_* SQLITE_AUTOREMAKE
|
|
TARGET_* USE_GCOV TCL_*} \
|
|
-auto {HAVE_* PACKAGE_*} \
|
|
-none *
|
|
hwaci-touch sqlite_cfg.h ; # help avoid frequent unnecessary @SQLITE_AUTOREMAKE@
|
|
}
|
|
#TODO hwaci-make-from-dot-in ext/wasm/GNUmakefile
|
|
|
|
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]"
|
|
}
|
|
set oFF [get-define OPT_SHELL]
|
|
if {"" ne $oFF} {
|
|
define OPT_SHELL [lsort -unique $oFF]
|
|
msg-result "Shell options: [get-define OPT_SHELL]"
|
|
}
|
|
unset oFF
|
|
|
|
define OPT_FEATURE_FLAGS.list [get-define OPT_FEATURE_FLAGS]
|
|
define OPT_SHELL.list [get-define OPT_SHELL]
|
|
|
|
hwaci-dump-defs-json config-defs.json \
|
|
-bare {SIZEOF_* HAVE_DECL_*} \
|
|
-none {HAVE_CFLAG_* LDFLAGS_* SH_* SQLITE_AUTOREMAKE TARGET_* USE_GCOV TCL_*} \
|
|
-array {*.list} \
|
|
-auto {OPT_* PACKAGE_* HAVE_*} \
|
|
-none *
|
|
|
|
|
|
########################################################################
|
|
# Some build-dev/debug-only output
|
|
hwaci-if-opt-truthy dump-defines {
|
|
global DUMP_DEFINES_FILE
|
|
msg-result "--dump-defines is creating file: $DUMP_DEFINES_FILE"
|
|
make-config-header $DUMP_DEFINES_FILE \
|
|
-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 {0} {
|
|
foreach x [all-defines] {
|
|
puts "\t$x"
|
|
}
|
|
}
|
|
}
|
|
|
|
msg-result "Done! Now run make."
|