--- /dev/null
+Maintaining Autosetup in the SQLite Tree
+========================================================================
+
+This document provides some tips and reminders for the SQLite
+developers regarding using and maintaining the [Autosetup][]-based
+build infrastructure. It is not an [Autosetup][] reference.
+
+**Table of Contents**:
+
+- [Autosetup API Reference](#apiref)
+- [API Tips](#apitips)
+- [Ensuring TCL Compatibility](#tclcompat)
+- [Updating Autosetup](#updating)
+
+------------------------------------------------------------------------
+
+<a name="apiref"></a>
+Autosetup API Reference
+========================================================================
+
+The Autosetup API is quite extensive and can be read either in
+the [files in the `autosetup` dir](/dir/autosetup) or using:
+
+>
+```
+$ ./configure --reference | less
+```
+
+That will include any docs from any TCL files in the `./autosetup` dir
+which contain certain (simple) markup defined by autosetup.
+
+This project's own autosetup-related APIs are in [proj.tcl][] or
+[auto.def][]. The former contains helper APIs which are, more or
+less, portable across projects (that file is re-used as-is in other
+projects) and all have a `proj-` name prefix. The latter is the main
+configure script driver and contains related functions which are
+specific to this tree.
+
+<a name="apitips"></a>
+Autosetup API Tips
+========================================================================
+
+This section briefly covers only APIs which are frequently useful in
+day-to-day maintenance and might not be immediately recognized as such
+obvious from a casual perusal of `auto.def`. Their complete docs can be
+found in [proj.tcl][].
+
+In (mostly) alphabetical order:
+
+- **`get-env VAR ?default?`**\
+ Will fetch an "environment variable"
+ from the first of either: (A) a KEY=VALUE passed to the configure
+ script or (B) the system's environment variables. Not to be confused
+ with `getenv`, which only does the latter and is rarely, if ever,
+ useful in this tree.
+ - **`proj-get-env VAR ?default?`**\
+ Works like `get-env` but will, if that function finds no match,
+ look for a file named `./.env-$VAR` and, if found, return its
+ trimmed contents. This can be used, e.g., to set a developer's
+ local preferences for the default `CFLAGS`.
+
+- **`proj-define-if-opt-truthy flag defineName checkingMsg ?yesVal=1? ?noVal=0?`**\
+ Defines `defineName` to either `yesVal` or `noVal`, depending on
+ whether `--flag` is truthy or not.
+
+- **`proj-if-opt-truthy flag thenScript ?elseScript?`**\
+ Evals `thenScript` if the given `--flag` is truthy, else it
+ evals the optional `elseScript`.
+
+- **`proj-indented-notice ?-error? msg`**\
+ Breaks its `msg` argument into lines, trims them, and emits them
+ with consistent indentation. If the `-error` flag is used, it them
+ exits with non-0. This will stick out starkly from normal output
+ and is intended to be used only for important notices.
+
+- **`proj-opt-truthy flag`**\
+ Returns 1 if `--flag`'s value is "truthy," i.e. one of (1, on,
+ enabled, yes).
+
+- **`proj-opt-was-provided FLAG`**\
+ Returns 1 if `--FLAG` was explicitly provided to configure,
+ else 0. This distinction can be used to determine, e.g., whether
+ `--with-readline` was provided or whether we're searching for
+ readline by default. In the former case, failure to find it should
+ be treated as fatal.
+
+- **`proj-val-truthy value`**\
+ Returns 1 if `$value` is "truthy," i.e. one of (1, on, enabled,
+ yes).
+
+
+<a name="tclcompat"></a>
+Ensuring TCL Compatibility
+========================================================================
+
+It is important that any TCL files used by the configure process
+remain compatible with both [JimTCL][] and the canonical TCL. Though
+JimTCL has outstanding compatibility with canonical TCL, it does have
+a few corners with incompatibilities, e.g. regular expressions. If a
+script runs in JimTCL without using any JimTCL-specific features, then
+it's a certainty that it will run in canonical TCL as well. The
+opposite, however, is not _always_ the case.
+
+By default, the configure script will search for an available `tclsh`
+(under several common names, e.g. `tclsh8.6`) before falling back to
+compiling the copy of `jimsh0.c` included in the source tree.
+
+There are two simple ways to ensure that the configure process uses
+JimTCL instead of the canonical `tclsh`, and either approach ensures
+configure script compatibility:
+
+1. Build on a system with no `tclsh` installed. In that case, the
+ configure process will fall back to building the in-tree copy of
+ JimTCL.
+
+2. Manually build `./jimsh0` in the top of the checkout with:\
+ `cc -o jimsh0 autosetup/jimsh0.c`\
+ With that in place, the configure script will prefer to use that
+ before looking for a system-level `tclsh`. Note that `make distclean`
+ will remove that file.
+
+**Note that `jimsh0` is distinctly different** from the `jimsh` which
+gets built for code-generation purposes. The latter requires
+non-default build flags to enable features which are
+platform-dependent, most notably to make its `[file normalize]`
+work. This means, for example, that the configure script and its
+utility APIs must not use `[file normalize]`, but autosetup provides a
+TCL implementation of `[file-normalize]` (note the dash) for portable
+use in the configure script.
+
+<a name="updating"></a>
+Updating Autosetup
+========================================================================
+
+Updating autosetup is, more often than not, painless. It requires having
+a checked-out copy of [the autosetup git repository][autosetup-git]:
+
+>
+```
+$ git clone https://github.com/msteveb/autosetup
+$ cd autosetup
+# Or, if it's already checked out:
+$ git pull
+```
+
+Then, from the top-most directory of an SQLite checkout:
+
+>
+```
+$ /path/to/autosetup-checkout/autosetup --install .
+$ fossil status # show the modified files
+```
+
+Unless the upgrade made any incompatible changes (which is exceedingly
+rare), that's all there is to it. Check over the diff, test the
+configure process, and check it in.
+
+
+
+[Autosetup]: https://msteveb.github.io/autosetup/
+[auto.def]: ../auto.def?mimetype=text/plain
+[autosetup-git]: https://github.com/msteveb/autosetup
+[proj.tcl]: ./proj.tcl?mimetype=text/plain
+[JimTCL]: https://jim.tcl.tk
# updating global state via feature tests.
########################################################################
+# ----- @module proj.tcl -----
+# @section Project Helper APIs
+
########################################################################
# $proj_ is an internal-use-only array for storing whatever generic
# internal stuff we need stored.
array set proj_ {}
set proj_(isatty) [isatty? stdout]
+########################################################################
+# @proj-warn msg
+#
+# Emits a warning message to stderr.
proc proj-warn {msg} {
puts stderr [proj-bold "WARNING: $msg"]
}
+########################################################################
+# @proj-error msg
+#
+# Emits an error message to stderr and exits with non-0.
proc proj-fatal {msg} {
show-notices
puts stderr [proj-bold "ERROR: $msg"]
}
########################################################################
+# @proj-assert script
+#
# Kind of like a C assert if uplevel (eval) of $script is false,
# triggers a fatal error.
proc proj-assert {script} {
}
########################################################################
+# @proj-bold str
+#
# If this function believes that the current console might support
# ANSI escape sequences then this returns $str wrapped in a sequence
# to bold that text, else it returns $str as-is.
}
########################################################################
+# @proj-indented-notice ?-error? msg
+#
# Takes a multi-line message and emits it with consistent indentation
# using [user-notice] (which means its rendering will (A) go to stderr
# and (B) be delayed until the next time autosetup goes to output a
}
########################################################################
+# @proj-search-for-header-dir ?-dirs LIST? ?-subdirs LIST? header
+#
# Searches for $header in a combination of dirs and subdirs, specified
# by the -dirs {LIST} and -subdirs {LIST} flags (each of which have
# sane defaults). Returns either the first matching dir or an empty
}
########################################################################
-# Usage: proj-find-executable-path ?-v? binaryName
+# @proj-find-executable-path ?-v? binaryName
#
# Works similarly to autosetup's [find-executable-path $binName] but:
#
}
########################################################################
+# @proj-bin-define binName ?defName?
+#
# Uses [proj-find-executable-path $binName] to (verbosely) search for
# a binary, sets a define (see below) to the result, and returns the
# result (an empty string if not found).
}
########################################################################
-# Usage: proj-first-bin-of bin...
+# @proj-first-bin-of bin...
#
# Looks for the first binary found of the names passed to this
# function. If a match is found, the full path to that binary is
}
########################################################################
+# @proj-opt-was-provided key
+#
# Returns 1 if the user specifically provided the given configure
# flag, else 0. This can be used to distinguish between options which
# have a default value and those which were explicitly provided by the
}
########################################################################
+# @proj-opt-set flag ?val?
+#
# Force-set autosetup option $flag to $val. The value can be fetched
# later with [opt-val], [opt-bool], and friends.
#
}
########################################################################
+# @proj-val-truthy val
+#
# Returns 1 if $val appears to be a truthy value, else returns
# 0. Truthy values are any of {1 on enabled yes}
proc proj-val-truthy {val} {
}
########################################################################
+# @proj-opt-truthy flag
+#
# Returns 1 if [opt-val $flag] appears to be a truthy value or
# [opt-bool $flag] is true. See proj-val-truthy.
proc proj-opt-truthy {flag} {
}
########################################################################
+# @proj-if-opt-truthy boolFlag thenScript ?elseScript?
+#
# If [proj-opt-truthy $flag] is true, eval $then, else eval $else.
proc proj-if-opt-truthy {boolFlag thenScript {elseScript {}}} {
if {[proj-opt-truthy $boolFlag]} {
}
########################################################################
+# @proj-define-if-opt-truthy flag def ?msg? ?iftrue? ?iffalse?
+#
# If [proj-opt-truthy $flag] then [define $def $iftrue] else [define
# $def $iffalse]. If $msg is not empty, output [msg-checking $msg] and
# a [msg-results ...] which corresponds to the result. Returns 1 if
}
########################################################################
-# Args: [-v] optName defName {descr {}}
+# @proj-opt-define-bool ?-v? optName defName ?descr?
#
# Checks [proj-opt-truthy $optName] and calls [define $defName X]
# where X is 0 for false and 1 for true. descr is an optional
}
########################################################################
+# @proj-check-module-loader
+#
# Check for module-loading APIs (libdl/libltdl)...
#
# Looks for libltdl or dlopen(), the latter either in -ldl or built in
}
########################################################################
+# @proj-no-check-module-loader
+#
# Sets all flags which would be set by proj-check-module-loader to
# empty/falsy values, as if those checks had failed to find a module
# loader. Intended to be called in place of that function when
}
########################################################################
+# @proj-file-conent ?-trim? filename
+#
# Opens the given file, reads all of its content, and returns it. If
# the first arg is -trim, the contents of the file named by the second
# argument are trimmed before returning them.
}
########################################################################
+# @proj-file-conent filename
+#
# Returns the contents of the given file as an array of lines, with
# the EOL stripped from each input line.
proc proj-file-content-list {fname} {
}
########################################################################
+# @proj-check-compile-commands ?configFlag?
+#
# Checks the compiler for compile_commands.json support. If passed an
# argument it is assumed to be the name of an autosetup boolean config
# which controls whether to run/skip this check.
#
# This test has a long history of false positive results because of
# compilers reacting differently to the -MJ flag.
-proc proj-check-compile-commands {{configOpt {}}} {
+proc proj-check-compile-commands {{configFlag {}}} {
msg-checking "compile_commands.json support... "
- if {"" ne $configOpt && ![proj-opt-truthy $configOpt]} {
+ if {"" ne $configFlag && ![proj-opt-truthy $configFlag]} {
msg-result "explicitly disabled"
define MAKE_COMPILATION_DB no
return 0
}
########################################################################
+# @proj-touch filename
+#
# Runs the 'touch' command on one or more files, ignoring any errors.
proc proj-touch {filename} {
catch { exec touch {*}$filename }
}
########################################################################
-# Usage:
-#
-# proj-make-from-dot-in ?-touch? filename(s)...
+# @proj-make-from-dot-in ?-touch? filename...
#
# Uses [make-template] to create makefile(-like) file(s) $filename
# from $filename.in but explicitly makes the output read-only, to
}
########################################################################
+# @proj-check-profile-flag ?flagname?
+#
# Checks for the boolean configure option named by $flagname. If set,
# it checks if $CC seems to refer to gcc. If it does (or appears to)
# then it defines CC_PROFILE_FLAG to "-pg" and returns 1, else it
}
########################################################################
+# @proj-looks-like-windows ?key?
+#
# Returns 1 if this appears to be a Windows environment (MinGw,
# Cygwin, MSys), else returns 0. The optional argument is the name of
# an autosetup define which contains platform name info, defaulting to
proc proj-looks-like-windows {{key host}} {
global autosetup
switch -glob -- [get-define $key] {
- *-*-ming* - *-*-cygwin - *-*-msys {
+ *-*-ming* - *-*-cygwin - *-*-msys - *windows* {
return 1
}
}
}
########################################################################
+# @proj-looks-like-mac ?key?
+#
# Looks at either the 'host' (==compilation target platform) or
# 'build' (==the being-built-on platform) define value and returns if
# if that value seems to indicate that it represents a Mac platform,
}
########################################################################
+# @proj-exe-extension
+#
# Checks autosetup's "host" and "build" defines to see if the build
# host and target are Windows-esque (Cygwin, MinGW, MSys). If the
# build environment is then BUILD_EXEEXT is [define]'d to ".exe", else
}
########################################################################
+# @proj-dll-extension
+#
# Works like proj-exe-extension except that it defines BUILD_DLLEXT
# and TARGET_DLLEXT to one of (.so, ,dll, .dylib).
#
}
########################################################################
+# @proj-lib-extension
+#
# Static-library counterpart of proj-dll-extension. Defines
# BUILD_LIBEXT and TARGET_LIBEXT to the conventional static library
# extension for the being-built-on resp. the target platform.
}
########################################################################
+# @proj-file-extensions
+#
# Calls all of the proj-*-extension functions.
proc proj-file-extensions {} {
proj-exe-extension
}
########################################################################
+# @proj-affirm-files-exist ?-v? filename...
+#
# Expects a list of file names. If any one of them does not exist in
# the filesystem, it fails fatally with an informative message.
# Returns the last file name it checks. If the first argument is -v
}
########################################################################
+# @proj-check-emsdk
+#
# Emscripten is used for doing in-tree builds of web-based WASM stuff,
# as opposed to WASI-based WASM or WASM binaries we import from other
# places. This is only set up for Unix-style OSes and is untested
}
########################################################################
+# @proj-check-rpath
+#
# Tries various approaches to handling the -rpath link-time
# flag. Defines LDFLAGS_RPATH to that/those flag(s) or an empty
# string. Returns 1 if it finds an option, else 0.
}
########################################################################
+# @proj-check-soname ?libname?
+#
# Checks whether CC supports the -Wl,soname,lib... flag. If so, it
# returns 1 and defines LDFLAGS_SONAME_PREFIX to the flag's prefix, to
# which the client would need to append "libwhatever.N". If not, it
}
########################################################################
+# @proj-xfer-option-aliases map
+#
# Expects a list of pairs of configure flags which have been
# registered with autosetup, in this form:
#
}
########################################################################
+# @proj-which-linenoise headerFile
+#
# Attempts to determine whether the given linenoise header file is of
# the "antirez" or "msteveb" flavor. It returns 2 for msteveb, else 1
# (it does not validate that the header otherwise contains the
}
########################################################################
+# @proj-remap-autoconf-dir-vars
#
-# "Re-export" the autoconf-conventional --XYZdir flags into something
+# "Re-map" the autoconf-conventional --XYZdir flags into something
# which is more easily overridable from a make invocation.
#
# Based off of notes in <https://sqlite.org/forum/forumpost/00d12a41f7>.
}
########################################################################
+# @proj-env-file flag ?default?
+#
# If a file named .env-$flag exists, this function returns a
# trimmed copy of its contents, else it returns $dflt. The intended
# usage is that things like developer-specific CFLAGS preferences can
}
########################################################################
+# @proj-get-env var ?default?
+#
# Extracts the value of "environment" variable $var from the first of
# the following places where it's defined:
#
-C Enhance\sthe\s--with-emsdk\sflag\sto\suse\sa\sdefault\svalue\sof\s'auto',\smeaning\sto\ssearch\sthe\senvironment\sfor\sit,\sand\sto\sfail\sfatally\sif\s--with-emsdk\sis\sexplicitly\sprovided\sbut\sthe\sSDK\sis\snot\sfound.
-D 2024-11-06T02:59:59.807
+C Add\sautosetup/README.md\s-\smaintenance-related\sdocs\sfor\sSQLite\sdevelopers\s(e.g.\show\sto\supdate\sautosetup).\sStart\smarking\sup\sthe\sproj.tcl\sAPIs\swith\sautosetup's\sdoc\smarkup\sso\sthat\sthey\sappear\sin\sthe\s./configure\s--reference\soutput.
+D 2024-11-06T04:38:05.379
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
F LICENSE.md c5b4009dca54d127d2d6033c22fd9cc34f53bedb6ef12c7cbaa468381c74ab28
F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2
F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90
F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2
-F auto.def 4a5115da298b51f0332fda72933976bded86700c94e30d75066e665795d638d7
+F auto.def 062b05538bc09779962a5265125aa289152f6abbb1ebaded9b22e8969b151d75
F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903
F autoconf/Makefile.am adedc1324b6a87fdd1265ddd336d2fb7d4f36a0e77b86ea553ae7cc4ea239347
F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac
F autoconf/tea/win/targets.vc 96a25a1fa6e9e9cfb348fd3760a5395b4ce8acafc8ed10f0412937ec200d5dbd
F autosetup/LICENSE 41a26aebdd2cd185d1e2b210f71b7ce234496979f6b35aef2cbf6b80cbed4ce4
F autosetup/README.autosetup a78ff8c4a3d2636a4268736672a74bf14a82f42687fcf0631a70c516075c031e
+F autosetup/README.md 94a117db60b2a8efbfed58e548809631f1941a8df9c3c6a356080771b772e31c
F autosetup/autosetup 9416ffdcdd6e2dbf7f6d1e5c890078518930f8af7722a950eacc28c7f151d2d6 x
F autosetup/autosetup-config.guess dfa101c5e8220e864d5e9c72a85e87110df60260d36cb951ad0a85d6d9eaa463 x
F autosetup/autosetup-config.sub a38fb074d0dece01cf919e9fb534a26011608aa8fa606490864295328526cd73 x
F autosetup/default.auto 5cdf016de2140e50f1db190a02039dc42fb390af1dda4cc4853e3042a9ef0e82
F autosetup/jimsh0.c d40e381ea4526a067590e7b91bd4b2efa6d4980d286f908054c647b3df4aee14
F autosetup/pkg-config.tcl 4e635bf39022ff65e0d5434339dd41503ea48fc53822c9c5bde88b02d3d952ba
-F autosetup/proj.tcl 57b9c794d01124c91af840b3ba0ef1e991e815c9a872fa451baff0dc03e9f84a
+F autosetup/proj.tcl b3a0621b6e98b9e87813ba7a15a64f92708527dd8efc99a764846c16336aadf0
F autosetup/system.tcl 51d4be76cd9a9074704b584e5c9cbba616202c8468cf9ba8a4f8294a7ab1dba9
F autosetup/tmake.auto eaebc74ad538dfdd3c817c27eefc31930c20510c4f3a3704071f6cb0629ed71f
F autosetup/tmake.tcl a275793ec1b6f8708179af0acef1f6f10d46c2920739743f7a8720c6d700c7a9
F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7
F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139
F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
-P 8b58cf9bbd3090c60f1ee7468cdeeb0b0fa4560d1e51a5fd0bef43692d10fe04
-R caf12b590890f202527bfa9f99549a98
+P 9724b747caa926bca09653ea6ac3c0f7869824c9a476eb81f03e1a6763552da1
+R 22b44d94fb3a53e904cadda0982c176f
U stephan
-Z 9566a0d488cad676e06a60ec48a87114
+Z e3f63aefb44fb343dd26a948d9892eb7
# Remove this line to create a well-formed Fossil manifest.