Mercurial
comparison third_party/sqlite3/autosetup/README.md @ 173:827c6ac504cd hg-web
Merged in default here.
| author | MrJuneJune <me@mrjunejune.com> |
|---|---|
| date | Mon, 19 Jan 2026 18:59:10 -0800 |
| parents | 589bab390fb4 |
| children |
comparison
equal
deleted
inserted
replaced
| 151:c033667da5f9 | 173:827c6ac504cd |
|---|---|
| 1 Maintaining Autosetup in the SQLite Tree | |
| 2 ======================================================================== | |
| 3 | |
| 4 This document provides some tips and reminders for the SQLite | |
| 5 developers regarding using and maintaining the [Autosetup][]-based | |
| 6 build infrastructure. It is not an [Autosetup][] reference. | |
| 7 | |
| 8 **Table of Contents**: | |
| 9 | |
| 10 - [Autosetup API Reference](#apiref) | |
| 11 - [API Tips](#apitips) | |
| 12 - [Ensuring TCL Compatibility](#tclcompat) | |
| 13 - [Design Conventions](#conventions) | |
| 14 - Symbolic Names of Feature Flags | |
| 15 - Do Not Update Global Shared State | |
| 16 - [Updating Autosetup](#updating) | |
| 17 - ***[Patching Autosetup for Project-local changes](#patching)*** | |
| 18 - [Branch-specific Customization](#branch-customization) | |
| 19 | |
| 20 | |
| 21 ------------------------------------------------------------------------ | |
| 22 | |
| 23 <a name="apiref"></a> | |
| 24 Autosetup API Reference | |
| 25 ======================================================================== | |
| 26 | |
| 27 The Autosetup API is quite extensive and can be read either in | |
| 28 the [files in the `autosetup` dir](/dir/autosetup) or using: | |
| 29 | |
| 30 > | |
| 31 ``` | |
| 32 $ ./configure --reference | less | |
| 33 ``` | |
| 34 | |
| 35 That will include any docs from any TCL files in the `./autosetup` dir | |
| 36 which contain certain (simple) markup defined by autosetup. | |
| 37 | |
| 38 This project's own configuration-related TCL code is spread across the | |
| 39 following files: | |
| 40 | |
| 41 - [proj.tcl][]: project-agnostic utility code for autosetup-driven | |
| 42 projects. This file is designed to be shared between this project, | |
| 43 other projects managed under the SQLite/Hwaci umbrella | |
| 44 (e.g. Fossil), and personal projects of SQLite's developers. It is | |
| 45 essentially an amalgamation of a decade's worth of autosetup-related | |
| 46 utility code. | |
| 47 - [sqlite-config.tcl][]: utility code which is too project-specific | |
| 48 for `proj.tcl`. We split this out of `auto.def` so that it can be | |
| 49 used by both `auto.def` and... | |
| 50 - [auto.def][]: the primary driver for the `./configure` process. | |
| 51 When we talk about "the configure script," we're technically | |
| 52 referring to this file, though it actually contains very little | |
| 53 of the TCL code. | |
| 54 - [autoconf/auto.def][]: the main driver script for the "autoconf" | |
| 55 bundle's configure script. It is essentially a slightly trimmed-down | |
| 56 version of the main `auto.def` file. The `autoconf` dir was ported | |
| 57 from the Autotools to Autosetup in the 3.49.0 dev cycle but retains | |
| 58 the "autoconf" name to minimize downstream disruption. | |
| 59 | |
| 60 | |
| 61 <a name="apitips"></a> | |
| 62 Autosetup API Tips | |
| 63 ======================================================================== | |
| 64 | |
| 65 This section briefly covers only APIs which are frequently useful in | |
| 66 day-to-day maintenance and might not be immediately recognized as such | |
| 67 from a casual perusal of the relevant TCL files. The complete docs of | |
| 68 those with `proj-` prefix can be found in [proj.tcl][] and those with | |
| 69 an `sqlite-` prefix are in [sqlite-config.tcl][]. The others are part | |
| 70 of Autosetup's core packages and are scattered around [the TCL files | |
| 71 in ./autosetup](/dir/autosetup). | |
| 72 | |
| 73 In (mostly) alphabetical order: | |
| 74 | |
| 75 - **`file-isexec filename`**\ | |
| 76 Should be used in place of `[file executable]`, as it will also | |
| 77 check for `${filename}.exe` on Windows platforms. However, on such | |
| 78 platforms it also assumes that _any_ existing file is executable. | |
| 79 | |
| 80 - **`get-env VAR ?default?`**\ | |
| 81 Will fetch an "environment variable" from the first of either: (1) a | |
| 82 KEY=VALUE passed to the configure script or (2) the system's | |
| 83 environment variables. Not to be confused with `getenv`, which only | |
| 84 does the latter and is rarely, if ever, useful in this tree. | |
| 85 - **`proj-get-env VAR ?default?`**\ | |
| 86 Works like `get-env` but will, if that function finds no match, | |
| 87 look for a file named `./.env-$VAR` and, if found, return its | |
| 88 trimmed contents. This can be used, e.g., to set a developer's | |
| 89 local preferences for the default `CFLAGS`.\ | |
| 90 Tip: adding `-O0` to `.env-CFLAGS` reduces rebuild times | |
| 91 considerably at the cost of performance in `make devtest` and the | |
| 92 like. | |
| 93 | |
| 94 - **`proj-fatal msg`**\ | |
| 95 Emits `$msg` to stderr and exits with non-zero. Its differences from | |
| 96 autosetup's `user-error` are purely cosmetic. | |
| 97 | |
| 98 - **`proj-if-opt-truthy flag thenScript ?elseScript?`**\ | |
| 99 Evals `thenScript` if the given `--flag` is truthy, else it | |
| 100 evals the optional `elseScript`. | |
| 101 | |
| 102 - **`proj-indented-notice ?-error? ?-notice? msg`**\ | |
| 103 Breaks its `msg` argument into lines, trims them, and emits them | |
| 104 with consistent indentation. Exactly how it emits depends on the | |
| 105 flags passed to it (or not), as covered in its docs. This will stick | |
| 106 out starkly from normal output and is intended to be used only for | |
| 107 important notices. | |
| 108 | |
| 109 - **`proj-opt-truthy flag`**\ | |
| 110 Returns 1 if `--flag`'s value is "truthy," i.e. one of (1, on, | |
| 111 enabled, yes, true). | |
| 112 | |
| 113 - **`proj-opt-was-provided FLAG`**\ | |
| 114 Returns 1 if `--FLAG` was explicitly provided to configure, | |
| 115 else 0. This distinction can be used to determine, e.g., whether | |
| 116 `--with-readline` was provided or whether we're searching for | |
| 117 readline by default. In the former case, failure to find it should | |
| 118 be treated as fatal, where in the latter case it's not.\ | |
| 119 Unlike most functions which deal with `--flags`, this one does not | |
| 120 validate that `$FLAG` is a registered flag so will not fail fatally | |
| 121 if `$FLAG` is not registered as an Autosetup option. | |
| 122 | |
| 123 - **`proj-val-truthy value`**\ | |
| 124 Returns 1 if `$value` is "truthy," See `proj-opt-truthy` for the definition | |
| 125 of "truthy." | |
| 126 | |
| 127 - **`proj-warn msg`**\ | |
| 128 Emits `$msg` to stderr. Closely-related is autosetup's `user-notice` | |
| 129 (described below). | |
| 130 | |
| 131 - **`sqlite-add-feature-flag ?-shell? FLAG...`**\ | |
| 132 Adds the given feature flag to the CFLAGS which are specific to | |
| 133 building libsqlite3. It's intended to be passed one or more | |
| 134 `-DSQLITE_ENABLE_...`, or similar, flags. If the `-shell` flag is | |
| 135 used then it also passes its arguments to | |
| 136 `sqlite-add-shell-opt`. This is a no-op if `FLAG` is not provided or | |
| 137 is empty. | |
| 138 | |
| 139 - **`sqlite-add-shell-opt FLAG...`**\ | |
| 140 The shell-specific counterpart of `sqlite-add-feature-flag` which | |
| 141 only adds the given flag(s) to the CLI-shell-specific CFLAGS. | |
| 142 | |
| 143 - **`sqlite-configure BUILD-NAME {script}`**\ | |
| 144 This is where all configure `--flags` are defined for all known | |
| 145 build modes ("canonical" or "autoconf"). After processing all flags, | |
| 146 this function runs `$script`, which contains the build-mode-specific | |
| 147 configuration bits, and then runs any finalization bits which are | |
| 148 common to all build modes. The `auto.def` files are intended to contain | |
| 149 exactly two commands: | |
| 150 `use sqlite-config; sqlite-configure BUILD-NAME {script}` | |
| 151 | |
| 152 - **`user-notice msg`**\ | |
| 153 Queues `$msg` to be sent to stderr, but does not emit it until | |
| 154 either `show-notices` is called or the next time autosetup would | |
| 155 output something (it internally calls `show-notices`). This can be | |
| 156 used to generate warnings between a "checking for..." message and | |
| 157 its resulting "yes/no/whatever" message in such a way as to not | |
| 158 spoil the layout of such messages. | |
| 159 | |
| 160 | |
| 161 <a name="tclcompat"></a> | |
| 162 Ensuring TCL Compatibility | |
| 163 ======================================================================== | |
| 164 | |
| 165 One of the significant benefits of using Autosetup is that (A) this | |
| 166 project uses many TCL scripts in the build process and (B) Autosetup | |
| 167 comes with a TCL interpreter named [JimTCL][]. | |
| 168 | |
| 169 It is important that any TCL files used by the configure process and | |
| 170 makefiles remain compatible with both [JimTCL][] and the canonical | |
| 171 TCL. Though JimTCL has outstanding compatibility with canonical TCL, | |
| 172 it does have a few corners with incompatibilities, e.g. regular | |
| 173 expressions. If a script runs in JimTCL without using any | |
| 174 JimTCL-specific features, then it's a certainty that it will run in | |
| 175 canonical TCL as well. The opposite, however, is not _always_ the | |
| 176 case. | |
| 177 | |
| 178 When [`./configure`](/file/configure) is run, it goes through a | |
| 179 bootstrapping process to find a suitable TCL with which to run the | |
| 180 autosetup framework. The first step involves [finding or building a | |
| 181 TCL shell](/file/autosetup/autosetup-find-tclsh). That will first | |
| 182 search for an available `tclsh` (under several common names, | |
| 183 e.g. `tclsh8.6`) before falling back to compiling the copy of | |
| 184 `jimsh0.c` included in the source tree. i.e. it will prefer to use a | |
| 185 system-installed TCL for running the configure script. Once it finds | |
| 186 (or builds) a TCL shell, it then runs [a sanity test to ensure that | |
| 187 the shell is suitable](/file/autosetup/autosetup-test-tclsh) before | |
| 188 using it to run the main autosetup app. | |
| 189 | |
| 190 There are two simple ways to ensure that running of the configure | |
| 191 process uses JimTCL instead of the canonical `tclsh`, and either | |
| 192 approach provides equally high assurances about configure script | |
| 193 compatibility across TCL implementations: | |
| 194 | |
| 195 1. Build on a system with no `tclsh` installed in the `$PATH`. In that | |
| 196 case, the configure process will fall back to building the in-tree | |
| 197 copy of JimTCL. | |
| 198 | |
| 199 2. Manually build `./jimsh0` in the top of the checkout with:\ | |
| 200 `cc -o jimsh0 autosetup/jimsh0.c`\ | |
| 201 With that in place, the configure script will prefer to use that | |
| 202 before looking for a system-level `tclsh`. Be aware, though, that | |
| 203 `make distclean` will remove that file. | |
| 204 | |
| 205 **Note that `./jimsh0` is distinctly different from the `./jimsh`** | |
| 206 which gets built for code-generation purposes. The latter requires | |
| 207 non-default build flags to enable features which are | |
| 208 platform-dependent, most notably to make its `[file normalize]` work. | |
| 209 This means, for example, that the configure script and its utility | |
| 210 APIs must not use `[file normalize]`, but autosetup provides a | |
| 211 TCL-only implementation of `[file-normalize]` (note the dash) for | |
| 212 portable use in the configure script. Contrariwise, code-generation | |
| 213 scripts invoked via `make` may use `[file normalize]`, as they'll use | |
| 214 `./jimsh` or `tclsh` instead of `./jimsh0`. | |
| 215 | |
| 216 | |
| 217 Known TCL Incompatibilities | |
| 218 ------------------------------------------------------------------------ | |
| 219 | |
| 220 A summary of known incompatibilities in JimTCL | |
| 221 | |
| 222 - **CRNL line endings**: prior to 2025-02-05 `fconfigure -translation ...` | |
| 223 was a no-op in JimTCL, and it emits CRNL line endings by default on | |
| 224 Windows. Since then, it supports `-translation binary`, which is | |
| 225 close enough to `-translation lf` for our purposes. When working | |
| 226 with files using the `open` command, it is important to use mode | |
| 227 `"rb"` or `"wb"`, as appropriate, so that the output does not get | |
| 228 CRNL-mangled on Windows. | |
| 229 | |
| 230 - **`file copy`** does not support multiple source files. See | |
| 231 [](/info/61f18c96183867fe) for a workaround. | |
| 232 | |
| 233 - **Regular expressions**: | |
| 234 | |
| 235 - Patterns treat `\nnn` octal values as back-references (which it | |
| 236 does not support). Those can be reformulated as demonstrated in | |
| 237 [](/info/aeac23359bb681c0). | |
| 238 | |
| 239 - `regsub` does not support the `\y` flag. A workaround is demonstrated | |
| 240 in [](/info/c2e5dd791cce3ec4). | |
| 241 | |
| 242 | |
| 243 <a name="conventions"></a> | |
| 244 Design Conventions | |
| 245 ======================================================================== | |
| 246 | |
| 247 This section describes the motivations for the most glaring of the | |
| 248 build's design decisions, in particular how they deviate from | |
| 249 historical, or even widely-conventional, practices. | |
| 250 | |
| 251 Symbolic Names of Feature Flags | |
| 252 ------------------------------------------------------------------------ | |
| 253 | |
| 254 Historically, the project's makefile has exclusively used | |
| 255 `UPPER_UNDERSCORE` form for makefile variables. This build, however, | |
| 256 primarily uses `X.y` format, where `X` is often a category label, | |
| 257 e.g. `CFLAGS`, and `y` is the specific instance of that category, | |
| 258 e.g. `CFLAGS.readline`. | |
| 259 | |
| 260 When the configure script exports flags for consumption by filtered | |
| 261 files, e.g. [Makefile.in][] and the generated | |
| 262 `sqlite_cfg.h`, it does so in the more conventional `X_Y` form because | |
| 263 those flags get exported as as C `#define`s to `sqlite_cfg.h`, where | |
| 264 dots are not permitted. | |
| 265 | |
| 266 The `X.y` convention is used in the makefiles primarily because the | |
| 267 person who did the initial port finds that considerably easier on the | |
| 268 eyes and fingers. In practice, the `X_Y` form of such exports is used | |
| 269 exactly once in [Makefile.in][], where it's translated from `@X_Y@` | |
| 270 into into `X.y` form for consumption by [Makefile.in][] and | |
| 271 [main.mk][]. For example: | |
| 272 | |
| 273 > | |
| 274 ``` | |
| 275 LDFLAGS.shobj = @SHOBJ_LDFLAGS@ | |
| 276 LDFLAGS.zlib = @LDFLAGS_ZLIB@ | |
| 277 LDFLAGS.math = @LDFLAGS_MATH@ | |
| 278 ``` | |
| 279 | |
| 280 (That first one is defined by autosetup, and thus applies "LDFLAGS" as | |
| 281 the suffix rather than the prefix. Which is more legible is a matter | |
| 282 of taste, for which there is no accounting.) | |
| 283 | |
| 284 | |
| 285 Do Not Update Global Shared State | |
| 286 ------------------------------------------------------------------------ | |
| 287 | |
| 288 In both the legacy Autotools-driven build and common Autosetup usage, | |
| 289 feature tests performed by the configure script may amend global flags | |
| 290 such as `LIBS`, `LDFLAGS`, and `CFLAGS`[^as-cflags]. That's | |
| 291 appropriate for a makefile which builds a single deliverable, but less | |
| 292 so for makefiles which produce multiple deliverables. Drawbacks of | |
| 293 that approach include: | |
| 294 | |
| 295 - It's unlikely that every single deliverable will require the same | |
| 296 core set of those flags. | |
| 297 - It can be difficult to determine the origin of any given change to | |
| 298 that global state because those changes are hidden behind voodoo | |
| 299 performed outside the immediate visibility of the configure script's | |
| 300 maintainer. | |
| 301 - It can force the maintainers of the configure script to place tests | |
| 302 in a specific order so that the resulting flags get applied at | |
| 303 the correct time and/or in the correct order.\ | |
| 304 (A real-life example: before the approach described below was taken | |
| 305 to collecting build-time flags, the test for `-rpath` had to come | |
| 306 _after_ the test for zlib because the results of the `-rpath` test | |
| 307 implicitly modified global state which broke the zlib feature | |
| 308 test. Because the feature tests no longer (intentionally) modify | |
| 309 shared global state, that is not an issue.) | |
| 310 | |
| 311 In this build, cases where feature tests modify global state in such a | |
| 312 way that it may impact later feature tests are either (A) very | |
| 313 intentionally defined to do so (e.g. the `--with-wasi-sdk` flag has | |
| 314 invasive side-effects) or (B) are oversights (i.e. bugs). | |
| 315 | |
| 316 This tree's [configure script][auto.def], [utility APIs][proj.tcl], | |
| 317 [Makefile.in][], and [main.mk][] therefore strive to separate the | |
| 318 results of any given feature test into its own well-defined | |
| 319 variables. For example: | |
| 320 | |
| 321 - The linker flags for zlib are exported from the configure script as | |
| 322 `LDFLAGS_ZLIB`, which [Makefile.in][] and [main.mk][] then expose as | |
| 323 `LDFLAGS.zlib`. | |
| 324 - `CFLAGS_READLINE` (a.k.a. `CFLAGS.readline`) contains the `CFLAGS` | |
| 325 needed for including `libreadline`, `libedit`, or `linenoise`, and | |
| 326 `LDFLAGS_READLINE` (a.k.a. `LDFLAGS.readline`) is its link-time | |
| 327 counterpart. | |
| 328 | |
| 329 It is then up to the Makefile to apply and order the flags however is | |
| 330 appropriate. | |
| 331 | |
| 332 At the end of the configure script, the global `CFLAGS` _ideally_ | |
| 333 holds only flags which are either relevant to all targets or, failing | |
| 334 that, will have no unintended side-effects on any targets. That said: | |
| 335 clients frequently pass custom `CFLAGS` to `./configure` or `make` to | |
| 336 set library-level feature toggles, e.g. `-DSQLITE_OMIT_FOO`, in which | |
| 337 case there is no practical way to avoid "polluting" the builds of | |
| 338 arbitrary makefile targets with those. _C'est la vie._ | |
| 339 | |
| 340 | |
| 341 [^as-cflags]: But see this article for a detailed discussion of how | |
| 342 autosetup currently deals specifically with CFLAGS: | |
| 343 <https://msteveb.github.io/autosetup/articles/handling-cflags/> | |
| 344 | |
| 345 | |
| 346 <a name="updating"></a> | |
| 347 Updating Autosetup | |
| 348 ======================================================================== | |
| 349 | |
| 350 Updating autosetup is, more often than not, painless. It requires having | |
| 351 a checked-out copy of [the autosetup git repository][autosetup-git]: | |
| 352 | |
| 353 > | |
| 354 ``` | |
| 355 $ git clone https://github.com/msteveb/autosetup | |
| 356 $ cd autosetup | |
| 357 # Or, if it's already checked out: | |
| 358 $ git pull | |
| 359 ``` | |
| 360 | |
| 361 Then, from the top-most directory of an SQLite checkout: | |
| 362 | |
| 363 > | |
| 364 ``` | |
| 365 $ /path/to/autosetup-checkout/autosetup --install . | |
| 366 $ fossil status # show the modified files | |
| 367 ``` | |
| 368 | |
| 369 Unless the upgrade made any incompatible changes (which is exceedingly | |
| 370 rare), that's all there is to it. After that's done, **apply a patch | |
| 371 for the change described in the following section**, test the | |
| 372 configure process, and check it in. | |
| 373 | |
| 374 <a name="patching"></a> | |
| 375 Patching Autosetup for Project-local Changes | |
| 376 ------------------------------------------------------------------------ | |
| 377 | |
| 378 Autosetup reserves the flag name **`--debug`** for its own purposes, | |
| 379 and its own special handling of `--enable-...` flags makes `--debug` | |
| 380 an alias for `--enable-debug`. As this project has a long history of | |
| 381 using `--enable-debug`, we patch autosetup to use the name | |
| 382 `--autosetup-debug` in place of `--debug`. That requires (as of this | |
| 383 writing) four small edits in | |
| 384 [/autosetup/autosetup](/file/autosetup/autosetup), as demonstrated in | |
| 385 [check-in 3296c8d3](/info/3296c8d3). | |
| 386 | |
| 387 If autosetup is upgraded and this patch is _not_ applied the invoking | |
| 388 `./configure` will fail loudly because of the declaration of the | |
| 389 `debug` flag in `auto.def` - duplicated flags are not permitted. | |
| 390 | |
| 391 <a name="branch-customization"></a> | |
| 392 Branch-specific Customization | |
| 393 ======================================================================== | |
| 394 | |
| 395 Certain vendor-specific branches require slight configure script | |
| 396 customization. Rather than editing `sqlite-config.tcl` for this, | |
| 397 which frequently leads to merge conflicts, the following approach | |
| 398 is recommended: | |
| 399 | |
| 400 In the vendor-specific branch, create a file named | |
| 401 `autosetup/sqlite-custom.tcl`. | |
| 402 | |
| 403 That file should contain the following content... | |
| 404 | |
| 405 If flag customization is required, add: | |
| 406 | |
| 407 > | |
| 408 ``` | |
| 409 proc sqlite-custom-flags {} { | |
| 410 # If any existing --flags require different default values | |
| 411 # then call: | |
| 412 options-defaults { | |
| 413 flag-name new-default-value | |
| 414 ... | |
| 415 } | |
| 416 # ^^^ That will replace the default value but will not update | |
| 417 # the --help text, which may lead to some confusion: | |
| 418 # https://github.com/msteveb/autosetup/issues/77 | |
| 419 | |
| 420 return { | |
| 421 {*} { | |
| 422 new-flag-name => {Help text} | |
| 423 ... | |
| 424 } | |
| 425 }; #see below | |
| 426 } | |
| 427 ``` | |
| 428 | |
| 429 That function must return either an empty string or a list in the form | |
| 430 used internally by [sqlite-config.tcl][]'s `sqlite-configure`. | |
| 431 | |
| 432 Next, define: | |
| 433 | |
| 434 > | |
| 435 ``` | |
| 436 proc sqlite-custom-handle-flags {} { | |
| 437 ... do any custom flag handling here ... | |
| 438 } | |
| 439 ``` | |
| 440 | |
| 441 That function, if defined, will be called relatively late in the | |
| 442 configure process, before any filtered files are generated but after | |
| 443 all other significant processing. | |
| 444 | |
| 445 | |
| 446 [Autosetup]: https://msteveb.github.io/autosetup/ | |
| 447 [auto.def]: /file/auto.def | |
| 448 [autoconf/auto.def]: /file/autoconf/auto.def | |
| 449 [autosetup-git]: https://github.com/msteveb/autosetup | |
| 450 [proj.tcl]: /file/autosetup/proj.tcl | |
| 451 [sqlite-config.tcl]: /file/autosetup/sqlite-config.tcl | |
| 452 [Makefile.in]: /file/Makefile.in | |
| 453 [main.mk]: /file/main.mk | |
| 454 [JimTCL]: https://jim.tcl.tk |