comparison third_party/sqlite3/autosetup/sqlite-config.tcl @ 167:589bab390fb4

[ThirdParty] Added sqlite3 to the third_party.
author MrJuneJune <me@mrjunejune.com>
date Mon, 19 Jan 2026 16:28:45 -0800
parents
children
comparison
equal deleted inserted replaced
166:78ea8d5ccc87 167:589bab390fb4
1 # This file holds functions for autosetup which are specific to the
2 # sqlite build tree. They are in this file, instead of auto.def, so
3 # that they can be reused in the autoconf sub-tree. This file requires
4 # functions from the project-agnostic proj.tcl.
5
6 if {[string first " " $autosetup(srcdir)] != -1} {
7 user-error "The pathname of the source tree\
8 may not contain space characters"
9 }
10 if {[string first " " $autosetup(builddir)] != -1} {
11 user-error "The pathname of the build directory\
12 may not contain space characters"
13 }
14
15 use proj
16 #
17 # We want the package version info to be emitted early on, but doing
18 # so requires a bit of juggling. We have to [use system] for
19 # --prefix=... to work and to emit the Host/Build system info, but we
20 # don't want those to interfere with --help output.
21 define PACKAGE_VERSION [proj-file-content -trim $::autosetup(srcdir)/VERSION]
22 if {"--help" ni $::argv} {
23 msg-result "Configuring SQLite version [get-define PACKAGE_VERSION]"
24 }
25 use system ; # Will output "Host System" and "Build System" lines
26 if {"--help" ni $::argv} {
27 proj-tweak-default-env-dirs
28 msg-result "Source dir = $::autosetup(srcdir)"
29 msg-result "Build dir = $::autosetup(builddir)"
30 use cc cc-db cc-shared cc-lib pkg-config
31 }
32
33 #
34 # Object for communicating certain config-time state across various
35 # auto.def-related pieces.
36 array set sqliteConfig [subst [proj-strip-hash-comments {
37 #
38 # Gets set by [sqlite-configure] (the main configure script driver).
39 build-mode unknown
40 #
41 # Gets set to 1 when using jimsh for code generation. May affect
42 # later decisions.
43 use-jim-for-codegen 0
44 #
45 # Set to 1 when cross-compiling This value may be changed by certain
46 # build options, so it's important that config code which checks for
47 # cross-compilation uses this var instead of
48 # [proj-is-cross-compiling].
49 is-cross-compiling [proj-is-cross-compiling]
50 #
51 # Pass msg-debug=1 to configure to enable obnoxiously loud output
52 # from [msg-debug].
53 msg-debug-enabled 0
54 #
55 # Output file for --dump-defines. Intended only for build debugging
56 # and not part of the public build interface.
57 dump-defines-txt ./config.defines.txt
58 #
59 # If not empty then --dump-defines will dump not only
60 # (dump-defines-txt) but also a JSON file named after this option's
61 # value.
62 dump-defines-json ""
63
64 #
65 # The list of feature --flags which the --all flag implies. This
66 # requires special handling in a few places.
67 #
68 all-flag-enables {fts4 fts5 rtree geopoly session dbpage dbstat carray}
69
70 #
71 # Default value for the --all flag. Can hypothetically be modified
72 # by non-canonical builds (it was added for a Tcl extension build
73 # mode which was eventually removed).
74 #
75 all-flag-default 0
76 }]]
77
78 ########################################################################
79 # Processes all configure --flags for this build, run build-specific
80 # config checks, then finalize the configure process. $buildMode must
81 # be one of (canonical, autoconf), and others may be added in the
82 # future. After bootstrapping, $configScript is eval'd in the caller's
83 # scope, then post-configuration finalization is run. $configScript is
84 # intended to hold configure code which is specific to the given
85 # $buildMode, with the caveat that _some_ build-specific code is
86 # encapsulated in the configuration finalization step.
87 #
88 # The intent is that all (or almost all) build-mode-specific
89 # configuration goes inside the $configScript argument to this
90 # function, and that an auto.def file contains only two commands:
91 #
92 # use sqlite-config
93 # sqlite-configure BUILD_NAME { build-specific configure script }
94 #
95 # There are snippets of build-mode-specific decision-making in
96 # [sqlite-configure-finalize], which gets run after $configScript.
97 proc sqlite-configure {buildMode configScript} {
98 proj-assert {$::sqliteConfig(build-mode) eq "unknown"} \
99 "sqlite-configure must not be called more than once"
100 set allBuildModes {canonical autoconf}
101 if {$buildMode ni $allBuildModes} {
102 user-error "Invalid build mode: $buildMode. Expecting one of: $allBuildModes"
103 }
104 if {$::sqliteConfig(all-flag-default)} {
105 set allFlagHelp "Disable these extensions: $::sqliteConfig(all-flag-enables)"
106 } else {
107 set allFlagHelp "Enable these extensions: $::sqliteConfig(all-flag-enables)"
108 }
109
110 set ::sqliteConfig(build-mode) $buildMode
111 ########################################################################
112 # A gentle introduction to flags handling in autosetup
113 #
114 # Reference: https://msteveb.github.io/autosetup/developer/
115 #
116 # All configure flags must be described in one or more calls to
117 # autosetup's [options] and [options-add] functions. The general
118 # syntax of the single argument to those functions is a list contain
119 # a mapping of flags to help text:
120 #
121 # FLAG => {Help text}
122 #
123 # Where FLAG can have any of the following formats:
124 #
125 # boolopt => "a boolean option which defaults to disabled"
126 # boolopt2=1 => "a boolean option which defaults to enabled"
127 # stringopt: => "an option which takes an argument, e.g. --stringopt=value"
128 # stringopt:DESCR => As for stringopt: with a description for the value
129 # stringopt2:=value => "an option where the argument is optional and defaults to 'value'"
130 # optalias booltopt3 => "a boolean with a hidden alias. --optalias is not shown in --help"
131 #
132 # Autosetup does no small amount of specialized handling for flags,
133 # especially booleans. Each bool-type --FLAG implicitly gets
134 # --enable-FLAG and --disable-FLAG forms. That can lead lead to some
135 # confusion when writing help text. For example:
136 #
137 # options { json=1 {Disable JSON functions} }
138 #
139 # The reason the help text says "disable" is because a boolean option
140 # which defaults to true is, in the --help text, rendered as:
141 #
142 # --disable-json Disable JSON functions
143 #
144 # Whereas a bool flag which defaults to false will instead render as:
145 #
146 # --enable-FLAG
147 #
148 # Non-boolean flags, in contrast, use the names specifically given to
149 # them in the [options] invocation. e.g. "with-tcl" is the --with-tcl
150 # flag.
151 #
152 # Fetching values for flags:
153 #
154 # booleans: use one of:
155 # - [opt-bool FLAG] is autosetup's built-in command for this, but we
156 # have some convenience variants:
157 # - [proj-opt-truthy FLAG]
158 # - [proj-opt-if-truthy FLAG {THEN} {ELSE}]
159 #
160 # Non-boolean (i.e. string) flags:
161 # - [opt-val FLAG ?default?]
162 # - [opt-str ...] - see the docs in ./autosetup/autosetup
163 #
164 # [proj-opt-was-provided] can be used to determine whether a flag was
165 # explicitly provided, which is often useful for distinguishing from
166 # the case of a default value.
167 ########################################################################
168 set allFlags {
169 # Structure: a list of M {Z} pairs, where M is a descriptive
170 # option group name and Z is a list of X Y pairs. X is a list of
171 # $buildMode name(s) to which the Y flags apply, or {*} to apply
172 # to all builds. Y is a {block} in the form expected by
173 # autosetup's [options] and [options-add] command. Each block
174 # which is applicable to $buildMode is passed on to
175 # [options-add]. The order of each Y and sub-Y is retained, which
176 # is significant for rendering of --help.
177 #
178 # Maintenance note: [options] does not support comments in
179 # options, but we filter this object through
180 # [proj-strip-hash-comments] to remove them before passing them on
181 # to [options].
182
183 # When writing {help text blocks}, be aware that:
184 #
185 # A) autosetup formats them differently if the {block} starts with
186 # a newline: it starts left-aligned, directly under the --flag, and
187 # the rest of the block is pasted verbatim rather than
188 # pretty-printed.
189 #
190 # B) Vars and commands are NOT expanded, but we use a [subst] call
191 # below which will replace (only) $var refs.
192
193 # Options for how to build the library
194 build-modes {
195 {canonical autoconf} {
196 shared=1 => {Disable build of shared library}
197 static=1 => {Disable build of static library}
198 }
199 {canonical} {
200 amalgamation=1 => {Disable the amalgamation and instead build all files separately}
201 }
202 }
203
204 # Library-level features and defaults
205 lib-features {
206 {*} {
207 threadsafe=1 => {Disable mutexing}
208 with-tempstore:=no => {Use an in-RAM database for temporary tables: never,no,yes,always}
209 load-extension=1 => {Disable loading of external extensions}
210 # ^^^ one of the downstream custom builds overrides the load-extension default to 0, which
211 # confuses the --help text generator. https://github.com/msteveb/autosetup/issues/77
212 math=1 => {Disable math functions}
213 json=1 => {Disable JSON functions}
214 memsys5 => {Enable MEMSYS5}
215 memsys3 => {Enable MEMSYS3}
216 fts3 => {Enable the FTS3 extension}
217 fts4 => {Enable the FTS4 extension}
218 fts5 => {Enable the FTS5 extension}
219 update-limit => {Enable the UPDATE/DELETE LIMIT clause}
220 geopoly => {Enable the GEOPOLY extension}
221 rtree => {Enable the RTREE extension}
222 session => {Enable the SESSION extension}
223 dbpage => {Enable the sqlite3_dbpage extension}
224 dbstat => {Enable the sqlite3_dbstat extension}
225 carray=1 => {Disable the CARRAY extension}
226 all=$::sqliteConfig(all-flag-default) => {$allFlagHelp}
227 largefile=1
228 => {This legacy flag has no effect on the library but may influence
229 the generated sqlite_cfg.h by adding #define HAVE_LFS}
230 }
231 {canonical} {
232 column-metadata => {Enable the column metadata APIs}
233 # ^^^ Affects how sqlite3.c is generated, so is not available in
234 # the autoconf build.
235 }
236 }
237
238 # Options for TCL support
239 tcl {
240 {canonical} {
241 tcl=1
242 => {Disable components which require TCL, including all tests.
243 This tree requires TCL for code generation but can use the in-tree
244 copy of autosetup/jimsh0.c for that. The SQLite TCL extension and the
245 test code require a canonical tclsh.}
246 with-tcl:DIR
247 => {Directory containing tclConfig.sh or a directory one level up from
248 that, from which we can derive a directory containing tclConfig.sh.
249 A dir name of "prefix" is equivalent to the directory specified by
250 the --prefix flag.}
251 with-tclsh:PATH
252 => {Full pathname of tclsh to use. It is used for (A) trying to find
253 tclConfig.sh and (B) all TCL-based code generation. Use --with-tcl
254 unless you have a specific need for this flag. Warning: if its
255 containing dir has multiple tclsh versions, it may select the
256 wrong tclConfig.sh!}
257 static-tclsqlite3=0
258 => {Statically-link tclsqlite3. This only works if TCL support is
259 enabled and all requisite libraries are available in
260 static form. Note that glibc is unable to fully statically
261 link certain libraries required by tclsqlite3, so this won't
262 work on most Linux environments.}
263 }
264 }
265
266 # Options for line-editing modes for the CLI shell
267 line-editing {
268 {canonical autoconf} {
269 readline=1
270 => {Disable readline support}
271 # --with-readline-lib is a backwards-compatible alias for
272 # --with-readline-ldflags
273 with-readline-lib:
274 with-readline-ldflags:=auto
275 => {Readline LDFLAGS, e.g. -lreadline -lncurses}
276 # --with-readline-inc is a backwards-compatible alias for
277 # --with-readline-cflags.
278 with-readline-inc:
279 with-readline-cflags:=auto
280 => {Readline CFLAGS, e.g. -I/path/to/includes}
281 with-readline-header:PATH
282 => {Full path to readline.h, from which --with-readline-cflags will be derived}
283 with-linenoise:DIR
284 => {Source directory for linenoise.c and linenoise.h}
285 editline=0
286 => {Enable BSD editline support}
287 }
288 }
289
290 # Options for ICU: International Components for Unicode
291 icu {
292 {*} {
293 with-icu-ldflags:LDFLAGS
294 => {Enable SQLITE_ENABLE_ICU and add the given linker flags for the
295 ICU libraries. e.g. on Ubuntu systems, try '-licui18n -licuuc -licudata'.}
296 with-icu-cflags:CFLAGS
297 => {Apply extra CFLAGS/CPPFLAGS necessary for building with ICU.
298 e.g. -I/usr/local/include}
299 with-icu-config:=auto
300 => {Enable SQLITE_ENABLE_ICU. Value must be one of: auto, pkg-config,
301 /path/to/icu-config}
302 icu-collations=0
303 => {Enable SQLITE_ENABLE_ICU_COLLATIONS. Requires --with-icu-ldflags=...
304 or --with-icu-config}
305 }
306 }
307
308 # Options for exotic/alternative build modes
309 alternative-builds {
310 {canonical autoconf} {
311 with-wasi-sdk:=/opt/wasi-sdk
312 => {Top-most dir of the wasi-sdk for a WASI build}
313 }
314
315 {*} {
316 # Note that --static-cli-shell has a completely different
317 # meaning from --static-shell in the autoconf build!
318 # --[disable-]static-shell is a legacy flag which we can't
319 # remove without breaking downstream builds.
320 static-cli-shell=0
321 => {Statically-link the sqlite3 CLI shell.
322 This only works if the requisite libraries are all available in
323 static form.}
324 }
325
326 {canonical} {
327 static-shells=0
328 => {Shorthand for --static-cli-shell --static-tclsqlite3}
329
330 with-emsdk:=auto
331 => {Top-most dir of the Emscripten SDK installation.
332 Needed only by ext/wasm. Default=EMSDK env var.}
333
334 amalgamation-extra-src:FILES
335 => {Space-separated list of source files to append as-is to the resulting
336 sqlite3.c amalgamation file. May be provided multiple times.}
337 }
338 }
339
340 # Options primarily for downstream packagers/package maintainers
341 packaging {
342 {autoconf} {
343 # --disable-static-shell: https://sqlite.org/forum/forumpost/cc219ee704
344 # Note that this has a different meaning from --static-cli-shell in the
345 # canonical build!
346 static-shell=1
347 => {Link the sqlite3 shell app against the DLL instead of embedding sqlite3.c}
348 }
349 {canonical autoconf} {
350 rpath=1 => {Disable use of the rpath linker flag}
351 # soname: https://sqlite.org/src/forumpost/5a3b44f510df8ded
352 soname:=legacy
353 => {SONAME for libsqlite3.so. "none", or not using this flag, sets no
354 soname. "legacy" sets it to its historical value of
355 libsqlite3.so.0. A value matching the glob "libsqlite3.*" sets
356 it to that literal value. Any other value is assumed to be a
357 suffix which gets applied to "libsqlite3.so.",
358 e.g. --soname=9.10 equates to "libsqlite3.so.9.10".}
359 # dll-basename: https://sqlite.org/forum/forumpost/828fdfe904
360 dll-basename:=auto
361 => {Specifies the base name of the resulting DLL file.
362 If not provided, "libsqlite3" is usually assumed but on some platforms
363 a platform-dependent default is used. On some platforms this flag
364 gets automatically enabled if it is not provided. Use "default" to
365 explicitly disable platform-dependent activation on such systems.}
366 # out-implib: https://sqlite.org/forum/forumpost/0c7fc097b2
367 out-implib:=auto
368 => {Enable use of --out-implib linker flag to generate an
369 "import library" for the DLL. The output's base name is
370 specified by this flag's value, with "auto" meaning to figure
371 out a name automatically. On some platforms this flag gets
372 automatically enabled if it is not provided. Use "none" to
373 explicitly disable this feature on such platforms.}
374 }
375 }
376
377 # Options mostly for sqlite's own development
378 developer {
379 {*} {
380 # Note that using the --debug/--enable-debug flag here
381 # requires patching autosetup/autosetup to rename its builtin
382 # --debug to --autosetup-debug. See details in
383 # autosetup/README.md#patching.
384 with-debug=0
385 debug=0
386 => {Enable debug build flags. This option will impact performance by
387 as much as 4x, as it includes large numbers of assert()s in
388 performance-critical loops. Never use --debug for production
389 builds.}
390 scanstatus
391 => {Enable the SQLITE_ENABLE_STMT_SCANSTATUS feature flag}
392 }
393 {canonical} {
394 dev
395 => {Enable dev-mode build: automatically enables certain other flags}
396 test-status
397 => {Enable status of tests}
398 gcov=0
399 => {Enable coverage testing using gcov}
400 linemacros
401 => {Enable #line macros in the amalgamation}
402 dynlink-tools
403 => {Dynamically link libsqlite3 to certain tools which normally statically embed it}
404 asan-fsanitize:=auto
405 => {Comma- or space-separated list of -fsanitize flags for use with the
406 fuzzcheck-asan tool. Only those which the compiler claims to support
407 will actually be used. May be provided multiple times.}
408 }
409 {*} {
410 dump-defines=0
411 => {Dump autosetup defines to $::sqliteConfig(dump-defines-txt)
412 (for build debugging)}
413 }
414 }
415 }; # $allFlags
416
417 set allFlags [proj-strip-hash-comments $allFlags]
418 # ^^^ lappend of [sqlite-custom-flags] introduces weirdness if
419 # we delay [proj-strip-hash-comments] until after that.
420
421 ########################################################################
422 # sqlite-custom.tcl is intended only for vendor-branch-specific
423 # customization. See autosetup/README.md#branch-customization for
424 # details.
425 if {[file exists $::autosetup(libdir)/sqlite-custom.tcl]} {
426 uplevel 1 {source $::autosetup(libdir)/sqlite-custom.tcl}
427 }
428
429 if {[llength [info proc sqlite-custom-flags]] > 0} {
430 # sqlite-custom-flags is assumed to be imported via
431 # autosetup/sqlite-custom.tcl.
432 set scf [sqlite-custom-flags]
433 if {"" ne $scf} {
434 lappend allFlags sqlite-custom-flags $scf
435 }
436 }
437
438 #lappend allFlags just-testing {{*} {soname:=duplicateEntry => {x}}}
439
440 # Filter allFlags to create the set of [options] legal for this build
441 foreach {group XY} [subst -nobackslashes -nocommands $allFlags] {
442 foreach {X Y} $XY {
443 if { $buildMode in $X || "*" in $X } {
444 options-add $Y
445 }
446 }
447 }
448
449 if {[catch {options {}} msg xopts]} {
450 # Workaround for <https://github.com/msteveb/autosetup/issues/73>
451 # where [options] behaves oddly on _some_ TCL builds when it's
452 # called from deeper than the global scope.
453 dict incr xopts -level
454 return {*}$xopts $msg
455 }
456 sqlite-configure-phase1 $buildMode
457 uplevel 1 $configScript
458 sqlite-configure-finalize
459 }; # sqlite-configure
460
461 ########################################################################
462 # Runs "phase 1" of the configure process: after initial --flags
463 # handling but before sqlite-configure's $configScript argument is
464 # run. $buildMode must be the mode which was passed to
465 # [sqlite-configure].
466 proc sqlite-configure-phase1 {buildMode} {
467 define PACKAGE_NAME sqlite
468 define PACKAGE_URL {https://sqlite.org}
469 define PACKAGE_BUGREPORT [get-define PACKAGE_URL]/forum
470 define PACKAGE_STRING "[get-define PACKAGE_NAME] [get-define PACKAGE_VERSION]"
471 proj-xfer-options-aliases {
472 # Carry values from hidden --flag aliases over to their canonical
473 # flag forms. This list must include only options which are common
474 # to all build modes supported by [sqlite-configure].
475 with-readline-inc => with-readline-cflags
476 with-readline-lib => with-readline-ldflags
477 with-debug => debug
478 }
479 set ::sqliteConfig(msg-debug-enabled) [proj-val-truthy [get-env msg-debug 0]]
480 proc-debug "msg-debug is enabled"
481 proj-setup-autoreconfig SQLITE_AUTORECONFIG
482 proj-file-extensions
483 if {".exe" eq [get-define TARGET_EXEEXT]} {
484 define SQLITE_OS_UNIX 0
485 define SQLITE_OS_WIN 1
486 } else {
487 define SQLITE_OS_UNIX 1
488 define SQLITE_OS_WIN 0
489 }
490 sqlite-setup-default-cflags
491 define HAVE_LFS 0
492 if {[opt-bool largefile]} {
493 #
494 # Insofar as we can determine HAVE_LFS has no effect on the
495 # library. Perhaps it did back in the early 2000's. The
496 # --enable/disable-largefile flag is retained because it's
497 # harmless, but it doesn't do anything useful. It does have
498 # visible side-effects, though: the generated sqlite_cfg.h may (or
499 # may not) define HAVE_LFS.
500 cc-check-lfs
501 }
502 set srcdir $::autosetup(srcdir)
503 proj-dot-ins-append $srcdir/Makefile.in
504 if {[file exists $srcdir/sqlite3.pc.in]} {
505 proj-dot-ins-append $srcdir/sqlite3.pc.in
506 }
507 sqlite-handle-hpux; # must be relatively early so that other config tests can work
508 }; # sqlite-configure-phase1
509
510 ########################################################################
511 # Performs late-stage config steps common to all supported
512 # $::sqliteConfig(build-mode) values.
513 proc sqlite-configure-finalize {} {
514 sqlite-handle-rpath
515 sqlite-handle-soname
516 sqlite-handle-threadsafe
517 sqlite-handle-tempstore
518 sqlite-handle-load-extension
519 sqlite-handle-math
520 sqlite-handle-icu
521 if {[proj-opt-exists readline]} {
522 sqlite-handle-line-editing
523 }
524 if {[proj-opt-exists shared]} {
525 proj-define-for-opt shared ENABLE_LIB_SHARED "Build shared library?"
526 }
527 if {[proj-opt-exists static]} {
528 if {![proj-define-for-opt static ENABLE_LIB_STATIC "Build static library?"]} {
529 # This notice really only applies to the canonical build...
530 proj-indented-notice {
531 NOTICE: static lib build may be implicitly re-activated by
532 other components, e.g. some test apps.
533 }
534 }
535 }
536 sqlite-handle-env-quirks
537 sqlite-handle-common-feature-flags
538 sqlite-finalize-feature-flags
539 sqlite-process-dot-in-files; # do not [define] anything after this
540 sqlite-dump-defines
541 }
542
543 ########################################################################
544 # Internal config-time debugging output routine. It generates no
545 # output unless msg-debug=1 is passed to the configure script.
546 proc msg-debug {msg} {
547 if {$::sqliteConfig(msg-debug-enabled)} {
548 puts stderr [proj-bold "** DEBUG: $msg"]
549 }
550 }
551 ########################################################################
552 # A [msg-debug] proxy which prepends the name of the current proc to
553 # the debug message. It is not legal to call this from the global
554 # scope.
555 proc proc-debug {msg} {
556 msg-debug "\[[proj-scope 1]\]: $msg"
557 }
558
559 define OPT_FEATURE_FLAGS {} ; # -DSQLITE_OMIT/ENABLE flags.
560 define OPT_SHELL {} ; # Feature-related CFLAGS for the sqlite3 CLI app
561 ########################################################################
562 # Adds $args, if not empty, to OPT_FEATURE_FLAGS. If the first arg is
563 # -shell then it strips that arg and passes the remaining args the
564 # sqlite-add-shell-opt in addition to adding them to
565 # OPT_FEATURE_FLAGS. This is intended only for holding
566 # -DSQLITE_ENABLE/OMIT/... flags, but that is not enforced here.
567 proc sqlite-add-feature-flag {args} {
568 set shell ""
569 if {"-shell" eq [lindex $args 0]} {
570 set args [lassign $args shell]
571 }
572 if {"" ne $args} {
573 if {"" ne $shell} {
574 sqlite-add-shell-opt {*}$args
575 }
576 define-append OPT_FEATURE_FLAGS {*}$args
577 }
578 }
579
580 ########################################################################
581 # Appends $args, if not empty, to OPT_SHELL.
582 proc sqlite-add-shell-opt {args} {
583 if {"" ne $args} {
584 define-append OPT_SHELL {*}$args
585 }
586 }
587
588 ########################################################################
589 # Check for log(3) in libm and die with an error if it is not
590 # found. $featureName should be the feature name which requires that
591 # function (it's used only in error messages). defines LDFLAGS_MATH to
592 # the required linker flags (which may be empty even if the math APIs
593 # are found, depending on the OS).
594 proc sqlite-affirm-have-math {featureName} {
595 if {"" eq [get-define LDFLAGS_MATH ""]} {
596 if {![msg-quiet proj-check-function-in-lib log m]} {
597 user-error "Missing math APIs for $featureName"
598 }
599 set lfl [get-define lib_log ""]
600 undefine lib_log
601 if {"" ne $lfl} {
602 user-notice "Forcing requirement of $lfl for $featureName"
603 }
604 define LDFLAGS_MATH $lfl
605 }
606 }
607
608 ########################################################################
609 # Run checks for required binaries, like ld and ar. In the canonical
610 # build this must come before [sqlite-handle-wasi-sdk].
611 proc sqlite-check-common-bins {} {
612 cc-check-tools ld ar ; # must come before [sqlite-handle-wasi-sdk]
613 if {"" eq [proj-bin-define install]} {
614 proj-warn "Cannot find install binary, so 'make install' will not work."
615 define BIN_INSTALL false
616 }
617 }
618
619 ########################################################################
620 # Run checks for system-level includes and libs which are common to
621 # both the canonical build and the "autoconf" bundle.
622 #
623 # For the canonical build this must come after
624 # [sqlite-handle-wasi-sdk], as that function may change the
625 # environment in ways which affect this.
626 proc sqlite-check-common-system-deps {} {
627 # Check for needed/wanted data types
628 cc-with {-includes stdint.h} \
629 {cc-check-types int8_t int16_t int32_t int64_t intptr_t \
630 uint8_t uint16_t uint32_t uint64_t uintptr_t}
631
632 # Check for needed/wanted functions
633 cc-check-functions gmtime_r isnan localtime_r localtime_s \
634 usleep utime pread pread64 pwrite pwrite64
635
636 apply {{} {
637 set ldrt ""
638 # Collapse funcs from librt into LDFLAGS_RT.
639 # Some systems (ex: SunOS) require -lrt in order to use nanosleep
640 foreach func {fdatasync nanosleep} {
641 if {[proj-check-function-in-lib $func rt]} {
642 set ldrt [get-define lib_${func} ""]
643 undefine lib_${func}
644 if {"" ne $ldrt} {
645 break
646 }
647 }
648 }
649 define LDFLAGS_RT $ldrt
650 }}
651
652 # Check for needed/wanted headers
653 cc-check-includes \
654 sys/types.h sys/stat.h dlfcn.h unistd.h \
655 stdlib.h malloc.h memory.h \
656 string.h strings.h \
657 inttypes.h
658
659 if {[cc-check-includes zlib.h] && [proj-check-function-in-lib deflate z]} {
660 # TODO? port over the more sophisticated zlib search from the fossil auto.def
661 define HAVE_ZLIB 1
662 define LDFLAGS_ZLIB -lz
663 sqlite-add-shell-opt -DSQLITE_HAVE_ZLIB=1
664 } else {
665 define HAVE_ZLIB 0
666 define LDFLAGS_ZLIB ""
667 }
668 }
669
670 ########################################################################
671 # Move -DSQLITE_OMIT... and -DSQLITE_ENABLE... flags from CFLAGS and
672 # CPPFLAGS to OPT_FEATURE_FLAGS and remove them from BUILD_CFLAGS.
673 proc sqlite-munge-cflags {} {
674 # Move CFLAGS and CPPFLAGS entries matching -DSQLITE_OMIT* and
675 # -DSQLITE_ENABLE* to OPT_FEATURE_FLAGS. This behavior is derived
676 # from the legacy build and was missing the 3.48.0 release (the
677 # initial Autosetup port).
678 # https://sqlite.org/forum/forumpost/9801e54665afd728
679 #
680 # Handling of CPPFLAGS, as well as removing ENABLE/OMIT from
681 # CFLAGS/CPPFLAGS, was missing in the 3.49.0 release as well.
682 #
683 # If any configure flags for features are in conflict with
684 # CFLAGS/CPPFLAGS-specified feature flags, all bets are off. There
685 # are no guarantees about which one will take precedence.
686 foreach flagDef {CFLAGS CPPFLAGS} {
687 set tmp ""
688 foreach cf [get-define $flagDef ""] {
689 switch -glob -- $cf {
690 -DSQLITE_OMIT* -
691 -DSQLITE_ENABLE* {
692 sqlite-add-feature-flag $cf
693 }
694 default {
695 lappend tmp $cf
696 }
697 }
698 }
699 define $flagDef $tmp
700 }
701
702 # Strip all SQLITE_ENABLE/OMIT flags from BUILD_CFLAGS,
703 # for compatibility with the legacy build.
704 set tmp ""
705 foreach cf [get-define BUILD_CFLAGS ""] {
706 switch -glob -- $cf {
707 -DSQLITE_OMIT* -
708 -DSQLITE_ENABLE* {}
709 default {
710 lappend tmp $cf
711 }
712 }
713 }
714 define BUILD_CFLAGS $tmp
715 }
716
717 #########################################################################
718 # Set up the default CFLAGS and BUILD_CFLAGS values.
719 proc sqlite-setup-default-cflags {} {
720 ########################################################################
721 # We differentiate between two C compilers: the one used for binaries
722 # which are to run on the build system (in autosetup it's called
723 # CC_FOR_BUILD and in Makefile.in it's $(B.cc)) and the one used for
724 # compiling binaries for the target system (CC a.k.a. $(T.cc)).
725 # Normally they're the same, but they will differ when
726 # cross-compiling.
727 #
728 # When cross-compiling we default to not using the -g flag, based on a
729 # /chat discussion prompted by
730 # https://sqlite.org/forum/forumpost/9a67df63eda9925c
731 set defaultCFlags {-O2}
732 if {!$::sqliteConfig(is-cross-compiling)} {
733 lappend defaultCFlags -g
734 }
735 define CFLAGS [proj-get-env CFLAGS $defaultCFlags]
736 # BUILD_CFLAGS is the CFLAGS for CC_FOR_BUILD.
737 define BUILD_CFLAGS [proj-get-env BUILD_CFLAGS {-g}]
738 sqlite-munge-cflags
739 }
740
741 ########################################################################
742 # Handle various SQLITE_ENABLE/OMIT_... feature flags.
743 proc sqlite-handle-common-feature-flags {} {
744 msg-result "Feature flags..."
745 if {![opt-bool all]} {
746 # Special handling for --disable-all
747 foreach flag $::sqliteConfig(all-flag-enables) {
748 if {![proj-opt-was-provided $flag]} {
749 proj-opt-set $flag 0
750 }
751 }
752 }
753 foreach {boolFlag featureFlag ifSetEvalThis} [proj-strip-hash-comments {
754 all {} {
755 # The 'all' option must be first in this list. This impl makes
756 # an effort to only apply flags which the user did not already
757 # apply, so that combinations like (--all --disable-geopoly)
758 # will indeed disable geopoly. There are corner cases where
759 # flags which depend on each other will behave in non-intuitive
760 # ways:
761 #
762 # --all --disable-rtree
763 #
764 # Will NOT disable geopoly, though geopoly depends on rtree.
765 # The --geopoly flag, though, will automatically re-enable
766 # --rtree, so --disable-rtree won't actually disable anything in
767 # that case.
768 foreach k $::sqliteConfig(all-flag-enables) {
769 if {![proj-opt-was-provided $k]} {
770 proj-opt-set $k 1
771 }
772 }
773 }
774 fts3 -DSQLITE_ENABLE_FTS3 {sqlite-affirm-have-math fts3}
775 fts4 -DSQLITE_ENABLE_FTS4 {sqlite-affirm-have-math fts4}
776 fts5 -DSQLITE_ENABLE_FTS5 {sqlite-affirm-have-math fts5}
777 geopoly -DSQLITE_ENABLE_GEOPOLY {proj-opt-set rtree}
778 rtree -DSQLITE_ENABLE_RTREE {}
779 session {-DSQLITE_ENABLE_SESSION -DSQLITE_ENABLE_PREUPDATE_HOOK} {}
780 update-limit -DSQLITE_ENABLE_UPDATE_DELETE_LIMIT {}
781 memsys5 -DSQLITE_ENABLE_MEMSYS5 {}
782 memsys3 {} {
783 if {[opt-bool memsys5]} {
784 proj-warn "not enabling memsys3 because memsys5 is enabled."
785 expr 0
786 } else {
787 sqlite-add-feature-flag -DSQLITE_ENABLE_MEMSYS3
788 }
789 }
790 scanstatus -DSQLITE_ENABLE_STMT_SCANSTATUS {}
791 column-metadata -DSQLITE_ENABLE_COLUMN_METADATA {}
792 dbpage -DSQLITE_ENABLE_DBPAGE_VTAB {}
793 dbstat -DSQLITE_ENABLE_DBSTAT_VTAB {}
794 carray -DSQLITE_ENABLE_CARRAY {}
795 }] {
796 if {$boolFlag ni $::autosetup(options)} {
797 # Skip flags which are in the canonical build but not
798 # the autoconf bundle.
799 continue
800 }
801 proj-if-opt-truthy $boolFlag {
802 sqlite-add-feature-flag $featureFlag
803 if {0 != [eval $ifSetEvalThis] && "all" ne $boolFlag} {
804 msg-result " + $boolFlag"
805 }
806 } {
807 if {"all" ne $boolFlag} {
808 msg-result " - $boolFlag"
809 }
810 }
811 }
812 ########################################################################
813 # Invert the above loop's logic for some SQLITE_OMIT_... cases. If
814 # config option $boolFlag is false, [sqlite-add-feature-flag
815 # $featureFlag], where $featureFlag is intended to be
816 # -DSQLITE_OMIT_...
817 foreach {boolFlag featureFlag} {
818 json -DSQLITE_OMIT_JSON
819 } {
820 if {[proj-opt-truthy $boolFlag]} {
821 msg-result " + $boolFlag"
822 } else {
823 sqlite-add-feature-flag $featureFlag
824 msg-result " - $boolFlag"
825 }
826 }
827 }
828
829 #########################################################################
830 # Remove duplicates from the final feature flag sets and show them to
831 # the user.
832 proc sqlite-finalize-feature-flags {} {
833 set oFF [get-define OPT_FEATURE_FLAGS]
834 if {"" ne $oFF} {
835 define OPT_FEATURE_FLAGS [lsort -unique $oFF]
836 msg-result "Library feature flags: [get-define OPT_FEATURE_FLAGS]"
837 }
838 set oFF [get-define OPT_SHELL]
839 if {"" ne $oFF} {
840 define OPT_SHELL [lsort -unique $oFF]
841 msg-result "Shell options: [get-define OPT_SHELL]"
842 }
843 if {"" ne [set extraSrc [get-define AMALGAMATION_EXTRA_SRC ""]]} {
844 proj-assert {"canonical" eq $::sqliteConfig(build-mode)}
845 msg-result "Appending source files to amalgamation: $extraSrc"
846 }
847 if {[lsearch [get-define TARGET_DEBUG ""] -DSQLITE_DEBUG=1] > -1} {
848 msg-result "Note: this is a debug build, so performance will suffer."
849 }
850 }
851
852 ########################################################################
853 # Checks for the --debug flag and [define]s TARGET_DEBUG based on
854 # that. TARGET_DEBUG is unused in the autoconf build but that is
855 # arguably a bug.
856 proc sqlite-handle-debug {} {
857 msg-checking "SQLITE_DEBUG build? "
858 proj-if-opt-truthy debug {
859 define TARGET_DEBUG {-g -DSQLITE_DEBUG=1 -O0 -Wall}
860 sqlite-add-feature-flag -DSQLITE_ENABLE_SELECTTRACE -DSQLITE_ENABLE_WHERETRACE
861 proj-opt-set memsys5
862 msg-result yes
863 } {
864 define TARGET_DEBUG {-DNDEBUG}
865 msg-result no
866 }
867 }
868
869 ########################################################################
870 # "soname" for libsqlite3.so. See discussion at:
871 # https://sqlite.org/src/forumpost/5a3b44f510df8ded
872 proc sqlite-handle-soname {} {
873 define LDFLAGS_LIBSQLITE3_SONAME ""
874 if {[proj-opt-was-provided soname]} {
875 set soname [join [opt-val soname] ""]
876 } else {
877 # Enabling soname breaks linking for the --dynlink-tools feature,
878 # and this project has no direct use for soname, so default to
879 # none. Package maintainers, on the other hand, like to have an
880 # soname.
881 set soname none
882 }
883 switch -exact -- $soname {
884 none - "" { return 0 }
885 legacy { set soname libsqlite3.so.0 }
886 default {
887 if {[string match libsqlite3.* $soname]} {
888 # use it as-is
889 } else {
890 # Assume it's a suffix
891 set soname "libsqlite3.so.${soname}"
892 }
893 }
894 }
895 proc-debug "soname=$soname"
896 if {[proj-check-soname $soname]} {
897 define LDFLAGS_LIBSQLITE3_SONAME [get-define LDFLAGS_SONAME_PREFIX]$soname
898 msg-result "Setting SONAME using: [get-define LDFLAGS_LIBSQLITE3_SONAME]"
899 } elseif {[proj-opt-was-provided soname]} {
900 # --soname was explicitly requested but not available, so fail fatally
901 proj-fatal "This environment does not support SONAME."
902 } else {
903 # --soname was not explicitly requested but not available, so just warn
904 msg-result "This environment does not support SONAME."
905 }
906 }
907
908 ########################################################################
909 # If --enable-threadsafe is set, this adds -DSQLITE_THREADSAFE=1 to
910 # OPT_FEATURE_FLAGS and sets LDFLAGS_PTHREAD to the linker flags
911 # needed for linking pthread (possibly an empty string). If
912 # --enable-threadsafe is not set, adds -DSQLITE_THREADSAFE=0 to
913 # OPT_FEATURE_FLAGS and sets LDFLAGS_PTHREAD to an empty string.
914 proc sqlite-handle-threadsafe {} {
915 msg-checking "Support threadsafe operation? "
916 define LDFLAGS_PTHREAD ""
917 set enable 0
918 proj-if-opt-truthy threadsafe {
919 msg-result "Checking for libs..."
920 if {[proj-check-function-in-lib pthread_create pthread]
921 && [proj-check-function-in-lib pthread_mutexattr_init pthread]} {
922 set enable 1
923 define LDFLAGS_PTHREAD [get-define lib_pthread_create]
924 undefine lib_pthread_create
925 undefine lib_pthread_mutexattr_init
926 } elseif {[proj-opt-was-provided threadsafe]} {
927 user-error "Missing required pthread libraries. Use --disable-threadsafe to disable this check."
928 } else {
929 msg-result "pthread support not detected"
930 }
931 # Recall that LDFLAGS_PTHREAD might be empty even if pthreads if
932 # found because it's in -lc on some platforms.
933 } {
934 msg-result "Disabled using --disable-threadsafe"
935 }
936 sqlite-add-feature-flag -DSQLITE_THREADSAFE=${enable}
937 return $enable
938 }
939
940 ########################################################################
941 # Handles the --with-tempstore flag.
942 #
943 # The test fixture likes to set SQLITE_TEMP_STORE on its own, so do
944 # not set that feature flag unless it was explicitly provided to the
945 # configure script.
946 proc sqlite-handle-tempstore {} {
947 if {[proj-opt-was-provided with-tempstore]} {
948 set ts [opt-val with-tempstore no]
949 set tsn 1
950 msg-checking "Use an in-RAM database for temporary tables? "
951 switch -exact -- $ts {
952 never { set tsn 0 }
953 no { set tsn 1 }
954 yes { set tsn 2 }
955 always { set tsn 3 }
956 default {
957 user-error "Invalid --with-tempstore value '$ts'. Use one of: never, no, yes, always"
958 }
959 }
960 msg-result $ts
961 sqlite-add-feature-flag -DSQLITE_TEMP_STORE=$tsn
962 }
963 }
964
965 ########################################################################
966 # Check for the Emscripten SDK for building the web-based wasm
967 # components. The core lib and tools do not require this but ext/wasm
968 # does. Most of the work is done via [proj-check-emsdk], then this
969 # function adds the following defines:
970 #
971 # - EMCC_WRAPPER = "" or top-srcdir/tool/emcc.sh
972 # - BIN_WASM_OPT = "" or path to wasm-opt
973 # - BIN_WASM_STRIP = "" or path to wasm-strip
974 #
975 # Noting that:
976 #
977 # 1) Not finding the SDK is not fatal at this level, nor is failure to
978 # find one of the related binaries.
979 #
980 # 2) wasm-strip is part of the wabt package:
981 #
982 # https://github.com/WebAssembly/wabt
983 #
984 # and this project requires it for production-mode builds but not dev
985 # builds.
986 #
987 proc sqlite-handle-emsdk {} {
988 define EMCC_WRAPPER ""
989 define BIN_WASM_STRIP ""
990 define BIN_WASM_OPT ""
991 set srcdir $::autosetup(srcdir)
992 if {$srcdir ne $::autosetup(builddir)} {
993 # The EMSDK pieces require writing to the original source tree
994 # even when doing an out-of-tree build. The ext/wasm pieces do not
995 # support an out-of-tree build so we treat that case as if EMSDK
996 # were not found.
997 msg-result "Out-of tree build: not checking for EMSDK."
998 return
999 }
1000 set emccSh $srcdir/tool/emcc.sh
1001 set extWasmConfig $srcdir/ext/wasm/config.make
1002 if {![get-define HAVE_WASI_SDK] && [proj-check-emsdk]} {
1003 define EMCC_WRAPPER $emccSh
1004 set emsdkHome [get-define EMSDK_HOME ""]
1005 proj-assert {"" ne $emsdkHome}
1006 #define EMCC_WRAPPER ""; # just for testing
1007 proj-bin-define wasm-strip
1008 proj-bin-define bash; # ext/wasm/GNUmakefile requires bash
1009 if {[file-isexec $emsdkHome/upstream/bin/wasm-opt]} {
1010 define BIN_WASM_OPT $emsdkHome/upstream/bin/wasm-opt
1011 } else {
1012 # Maybe there's a copy in the path?
1013 proj-bin-define wasm-opt BIN_WASM_OPT
1014 }
1015 proj-dot-ins-append $emccSh.in $emccSh {
1016 catch {exec chmod u+x $dotInsOut}
1017 }
1018 proj-dot-ins-append $extWasmConfig.in $extWasmConfig
1019 } else {
1020 define EMCC_WRAPPER ""
1021 file delete -force -- $emccSh $extWasmConfig
1022 }
1023 }
1024
1025 ########################################################################
1026 # Internal helper for [sqlite-check-line-editing]. Returns a list of
1027 # potential locations under which readline.h might be found.
1028 #
1029 # On some environments this function may perform extra work to help
1030 # sqlite-check-line-editing figure out how to find libreadline and
1031 # friends. It will communicate those results via means other than the
1032 # result value, e.g. by modifying configure --flags.
1033 proc sqlite-get-readline-dir-list {} {
1034 # Historical note: the dirs list, except for the inclusion of
1035 # $prefix and some platform-specific dirs, originates from the
1036 # legacy configure script.
1037 set dirs [list [get-define prefix]]
1038 switch -glob -- [get-define host] {
1039 *-linux-android {
1040 # Possibly termux
1041 lappend dirs /data/data/com.termux/files/usr
1042 }
1043 *-mingw32 {
1044 lappend dirs /mingw32 /mingw
1045 }
1046 *-mingw64 {
1047 lappend dirs /mingw64 /mingw
1048 }
1049 *-haiku {
1050 lappend dirs /boot/system/develop/headers
1051 if {[opt-val with-readline-ldflags] in {auto ""}} {
1052 # If the user did not supply their own --with-readline-ldflags
1053 # value, hijack that flag to inject options which are known to
1054 # work on Haiku OS installations.
1055 if {"" ne [glob -nocomplain /boot/system/lib/libreadline*]} {
1056 proj-opt-set with-readline-ldflags {-L/boot/system/lib -lreadline}
1057 }
1058 }
1059 }
1060 }
1061 lappend dirs /usr /usr/local /usr/local/readline /usr/contrib
1062 set rv {}
1063 foreach d $dirs {
1064 if {[file isdir $d]} {lappend rv $d}
1065 }
1066 #proc-debug "dirs=$rv"
1067 return $rv
1068 }
1069
1070 ########################################################################
1071 # sqlite-check-line-editing jumps through proverbial hoops to try to
1072 # find a working line-editing library, setting:
1073 #
1074 # - HAVE_READLINE to 0 or 1
1075 # - HAVE_LINENOISE to 0, 1, or 2
1076 # - HAVE_EDITLINE to 0 or 1
1077 #
1078 # Only one of ^^^ those will be set to non-0.
1079 #
1080 # - LDFLAGS_READLINE = linker flags or empty string
1081 #
1082 # - CFLAGS_READLINE = compilation flags for clients or empty string.
1083 #
1084 # Note that LDFLAGS_READLINE and CFLAGS_READLINE may refer to
1085 # linenoise or editline, not necessarily libreadline. In some cases
1086 # it will set HAVE_READLINE=1 when it's really using editline, for
1087 # reasons described in this function's comments.
1088 #
1089 # Returns a string describing which line-editing approach to use, or
1090 # "none" if no option is available.
1091 #
1092 # Order of checks:
1093 #
1094 # 1) --with-linenoise trumps all others and skips all of the
1095 # complexities involved with the remaining options.
1096 #
1097 # 2) --editline trumps --readline
1098 #
1099 # 3) --disable-readline trumps --readline
1100 #
1101 # 4) Default to automatic search for optional readline
1102 #
1103 # 5) Try to find readline or editline. If it's not found AND the
1104 # corresponding --FEATURE flag was explicitly given then fail
1105 # fatally, else fail non-fatally.
1106 proc sqlite-check-line-editing {} {
1107 msg-result "Checking for line-editing capability..."
1108 define HAVE_READLINE 0
1109 define HAVE_LINENOISE 0
1110 define HAVE_EDITLINE 0
1111 define LDFLAGS_READLINE ""
1112 define CFLAGS_READLINE ""
1113 set failIfNotFound 0 ; # Gets set to 1 for explicit --FEATURE requests
1114 # so that we know whether to fail fatally or not
1115 # if the library is not found.
1116 set libsForReadline {readline edit} ; # -l<LIB> names to check for readline().
1117 # The libedit check changes this.
1118 set editLibName "readline" ; # "readline" or "editline"
1119 set editLibDef "HAVE_READLINE" ; # "HAVE_READLINE" or "HAVE_EDITLINE"
1120 set dirLn [opt-val with-linenoise]
1121 if {"" ne $dirLn} {
1122 # Use linenoise from a copy of its sources (not a library)...
1123 if {![file isdir $dirLn]} {
1124 proj-fatal "--with-linenoise value is not a directory"
1125 }
1126 set lnH $dirLn/linenoise.h
1127 if {![file exists $lnH] } {
1128 proj-fatal "Cannot find linenoise.h in $dirLn"
1129 }
1130 set lnC ""
1131 set lnCOpts {linenoise-ship.c linenoise.c}
1132 foreach f $lnCOpts {
1133 if {[file exists $dirLn/$f]} {
1134 set lnC $dirLn/$f
1135 break
1136 }
1137 }
1138 if {"" eq $lnC} {
1139 proj-fatal "Cannot find any of $lnCOpts in $dirLn"
1140 }
1141 set flavor ""
1142 set lnVal [proj-which-linenoise $lnH]
1143 switch -- $lnVal {
1144 1 { set flavor "antirez" }
1145 2 { set flavor "msteveb" }
1146 default {
1147 proj-fatal "Cannot determine the flavor of linenoise from $lnH"
1148 }
1149 }
1150 define CFLAGS_READLINE "-I$dirLn $lnC"
1151 define HAVE_LINENOISE $lnVal
1152 sqlite-add-shell-opt -DHAVE_LINENOISE=$lnVal
1153 if {$::sqliteConfig(use-jim-for-codegen) && 2 == $lnVal} {
1154 define-append CFLAGS_JIMSH -DUSE_LINENOISE [get-define CFLAGS_READLINE]
1155 user-notice "Adding linenoise support to jimsh."
1156 }
1157 return "linenoise ($flavor)"
1158 } elseif {[opt-bool editline]} {
1159 # libedit mimics libreadline and on some systems does not have its
1160 # own header installed (instead, that of libreadline is used).
1161 #
1162 # shell.c historically expects HAVE_EDITLINE to be set for
1163 # libedit, but it then expects to see <editline/readline.h>, which
1164 # some system's don't actually have despite having libedit. If we
1165 # end up finding <editline/readline.h> below, we will use
1166 # -DHAVE_EDITLINE=1, else we will use -DHAVE_READLINE=1. In either
1167 # case, we will link against libedit.
1168 set failIfNotFound 1
1169 set libsForReadline {edit}
1170 set editLibName editline
1171 } elseif {![opt-bool readline]} {
1172 msg-result "Readline support explicitly disabled with --disable-readline"
1173 return "none"
1174 } elseif {[proj-opt-was-provided readline]} {
1175 # If an explicit --[enable-]readline was used, fail if it's not
1176 # found, else treat the feature as optional.
1177 set failIfNotFound 1
1178 }
1179
1180 # Transform with-readline-header=X to with-readline-cflags=-I...
1181 set v [opt-val with-readline-header]
1182 proj-opt-set with-readline-header ""
1183 if {"" ne $v} {
1184 if {"auto" eq $v} {
1185 proj-opt-set with-readline-cflags auto
1186 } else {
1187 set v [file dirname $v]
1188 if {[string match */readline $v]} {
1189 # Special case: if the path includes .../readline/readline.h,
1190 # set the -I to one dir up from that because our sources
1191 # #include <readline/readline.h> or <editline/readline.h>.
1192 set v [file dirname $v]
1193 }
1194 proj-opt-set with-readline-cflags "-I$v"
1195 }
1196 }
1197
1198 # Look for readline.h
1199 set rlInc [opt-val with-readline-cflags auto]
1200 if {"auto" eq $rlInc} {
1201 set rlInc ""
1202 if {$::sqliteConfig(is-cross-compiling)} {
1203 # ^^^ this check is derived from the legacy configure script.
1204 proj-warn "Skipping check for readline.h because we're cross-compiling."
1205 } else {
1206 set dirs [sqlite-get-readline-dir-list]
1207 set subdirs [list \
1208 include/$editLibName \
1209 readline]
1210 if {"editline" eq $editLibName} {
1211 lappend subdirs include/readline
1212 # ^^^ editline, on some systems, does not have its own header,
1213 # and uses libreadline's header.
1214 }
1215 lappend subdirs include
1216 set rlInc [proj-search-for-header-dir readline.h \
1217 -dirs $dirs -subdirs $subdirs]
1218 #proc-debug "rlInc=$rlInc"
1219 if {"" ne $rlInc} {
1220 if {[string match */readline $rlInc]} {
1221 set rlInc [file dirname $rlInc]; # CLI shell: #include <readline/readline.h>
1222 } elseif {[string match */editline $rlInc]} {
1223 set editLibDef HAVE_EDITLINE
1224 set rlInc [file dirname $rlInc]; # CLI shell: #include <editline/readline.h>
1225 }
1226 set rlInc "-I${rlInc}"
1227 }
1228 }
1229 } elseif {"" ne $rlInc && ![string match *-I* $rlInc]} {
1230 proj-fatal "Argument to --with-readline-cflags is intended to be CFLAGS and contain -I..."
1231 }
1232
1233 # If readline.h was found/specified, look for lib(readline|edit)...
1234 #
1235 # This is not quite straightforward because both libreadline and
1236 # libedit typically require some other library which (according to
1237 # legacy autotools-generated tests) provides tgetent(3). On some
1238 # systems that's built into libreadline/edit, on some (most?) its in
1239 # lib[n]curses, and on some it's in libtermcap.
1240 set rlLib ""
1241 if {"" ne $rlInc} {
1242 set rlLib [opt-val with-readline-ldflags]
1243 #proc-debug "rlLib=$rlLib"
1244 if {$rlLib in {auto ""}} {
1245 set rlLib "" ; # make sure it's not "auto", as we may append to it below
1246 set libTerm ""; # lib with tgetent(3)
1247 if {[proj-check-function-in-lib tgetent [list $editLibName ncurses curses termcap]]} {
1248 # ^^^ that libs list comes from the legacy configure script ^^^
1249 set libTerm [get-define lib_tgetent]
1250 undefine lib_tgetent
1251 }
1252 if {$editLibName eq $libTerm} {
1253 # tgetent(3) was found in the editing library
1254 set rlLib $libTerm
1255 } elseif {[proj-check-function-in-lib readline $libsForReadline $libTerm]} {
1256 # tgetent(3) was found in an external lib
1257 set rlLib [get-define lib_readline]
1258 lappend rlLib $libTerm
1259 undefine lib_readline
1260 }
1261 }
1262 }
1263
1264 # If we found a library, configure the build to use it...
1265 if {"" ne $rlLib} {
1266 if {"editline" eq $editLibName && "HAVE_READLINE" eq $editLibDef} {
1267 # Alert the user that, despite outward appearances, we won't be
1268 # linking to the GPL'd libreadline. Presumably that distinction is
1269 # significant for those using --editline.
1270 proj-indented-notice {
1271 NOTE: the local libedit uses <readline/readline.h> so we
1272 will compile with -DHAVE_READLINE=1 but will link with
1273 libedit.
1274 }
1275 }
1276 set rlLib [join $rlLib]
1277 set rlInc [join $rlInc]
1278 define LDFLAGS_READLINE $rlLib
1279 define CFLAGS_READLINE $rlInc
1280 proj-assert {$editLibDef in {HAVE_READLINE HAVE_EDITLINE}}
1281 proj-assert {$editLibName in {readline editline}}
1282 sqlite-add-shell-opt -D${editLibDef}=1
1283 msg-result "Using $editLibName flags: $rlInc $rlLib"
1284 # Check whether rl_completion_matches() has a signature we can use
1285 # and disable that sub-feature if it doesn't.
1286 if {![cctest -cflags "$rlInc -D${editLibDef}" -libs $rlLib -nooutput 1 \
1287 -source {
1288 #include <stdio.h>
1289 #ifdef HAVE_EDITLINE
1290 #include <editline/readline.h>
1291 #else
1292 #include <readline/readline.h>
1293 #endif
1294 static char * rcg(const char *z, int i){(void)z; (void)i; return 0;}
1295 int main(void) {
1296 char ** x = rl_completion_matches("one", rcg);
1297 (void)x;
1298 return 0;
1299 }
1300 }]} {
1301 proj-warn "readline-style completion disabled due to rl_completion_matches() signature mismatch"
1302 sqlite-add-shell-opt -DSQLITE_OMIT_READLINE_COMPLETION
1303 }
1304 return $editLibName
1305 }
1306
1307 if {$failIfNotFound} {
1308 proj-fatal "Explicit --$editLibName failed to find a matching library."
1309 }
1310 return "none"
1311 }; # sqlite-check-line-editing
1312
1313 ########################################################################
1314 # Runs sqlite-check-line-editing and adds a message around it. In the
1315 # canonical build this must not be called before
1316 # sqlite-determine-codegen-tcl for reasons now lost to history (and
1317 # might not still be applicable).
1318 proc sqlite-handle-line-editing {} {
1319 msg-result "Line-editing support for the sqlite3 shell: [sqlite-check-line-editing]"
1320 }
1321
1322
1323 ########################################################################
1324 # ICU - International Components for Unicode
1325 #
1326 # Handles these flags:
1327 #
1328 # --with-icu-ldflags=LDFLAGS
1329 # --with-icu-cflags=CFLAGS
1330 # --with-icu-config[=auto | pkg-config | /path/to/icu-config]
1331 # --enable-icu-collations
1332 #
1333 # --with-icu-config values:
1334 #
1335 # - auto: use the first one of (pkg-config, icu-config) found on the
1336 # system.
1337 # - pkg-config: use only pkg-config to determine flags
1338 # - /path/to/icu-config: use that to determine flags
1339 #
1340 # If --with-icu-config is used and neither pkg-config nor icu-config
1341 # are found, fail fatally.
1342 #
1343 # If both --with-icu-ldflags and --with-icu-config are provided, they
1344 # are cumulative. If neither are provided, icu-collations is not
1345 # honored and a warning is emitted if it is provided.
1346 #
1347 # Design note: though we could automatically enable ICU if the
1348 # icu-config binary or (pkg-config icu-io) are found, we specifically
1349 # do not. ICU is always an opt-in feature.
1350 proc sqlite-handle-icu {} {
1351 define LDFLAGS_ICU [join [opt-val with-icu-ldflags ""]]
1352 define CFLAGS_ICU [join [opt-val with-icu-cflags ""]]
1353 if {[proj-opt-was-provided with-icu-config]} {
1354 msg-result "Checking for ICU support..."
1355 set icuConfigBin [opt-val with-icu-config]
1356 set tryIcuConfigBin 1; # set to 0 if we end up using pkg-config
1357 if {$icuConfigBin in {auto pkg-config}} {
1358 if {[pkg-config-init 0] && [pkg-config icu-io]} {
1359 # Maintenance reminder: historical docs say to use both of
1360 # (icu-io, icu-uc). icu-uc lacks a required lib and icu-io has
1361 # all of them on tested OSes.
1362 set tryIcuConfigBin 0
1363 define LDFLAGS_ICU [get-define PKG_ICU_IO_LDFLAGS]
1364 define-append LDFLAGS_ICU [get-define PKG_ICU_IO_LIBS]
1365 define CFLAGS_ICU [get-define PKG_ICU_IO_CFLAGS]
1366 } elseif {"pkg-config" eq $icuConfigBin} {
1367 proj-fatal "pkg-config cannot find package icu-io"
1368 } else {
1369 proj-assert {"auto" eq $icuConfigBin}
1370 }
1371 }
1372 if {$tryIcuConfigBin} {
1373 if {"auto" eq $icuConfigBin} {
1374 set icuConfigBin [proj-first-bin-of \
1375 /usr/local/bin/icu-config \
1376 /usr/bin/icu-config]
1377 if {"" eq $icuConfigBin} {
1378 proj-indented-notice -error {
1379 --with-icu-config=auto cannot find (pkg-config icu-io) or icu-config binary.
1380 On Ubuntu-like systems try:
1381 --with-icu-ldflags='-licui18n -licuuc -licudata'
1382 }
1383 }
1384 }
1385 if {[file-isexec $icuConfigBin]} {
1386 set x [exec $icuConfigBin --ldflags]
1387 if {"" eq $x} {
1388 proj-indented-notice -error \
1389 [subst {
1390 $icuConfigBin --ldflags returned no data.
1391 On Ubuntu-like systems try:
1392 --with-icu-ldflags='-licui18n -licuuc -licudata'
1393 }]
1394 }
1395 define-append LDFLAGS_ICU $x
1396 set x [exec $icuConfigBin --cppflags]
1397 define-append CFLAGS_ICU $x
1398 } else {
1399 proj-fatal "--with-icu-config=$icuConfigBin does not refer to an executable"
1400 }
1401 }
1402 }
1403 set ldflags [define LDFLAGS_ICU [string trim [get-define LDFLAGS_ICU]]]
1404 set cflags [define CFLAGS_ICU [string trim [get-define CFLAGS_ICU]]]
1405 if {"" ne $ldflags} {
1406 sqlite-add-feature-flag -shell -DSQLITE_ENABLE_ICU
1407 msg-result "Enabling ICU support with flags: $ldflags $cflags"
1408 if {[opt-bool icu-collations]} {
1409 msg-result "Enabling ICU collations."
1410 sqlite-add-feature-flag -shell -DSQLITE_ENABLE_ICU_COLLATIONS
1411 # Recall that shell.c builds with sqlite3.c except in the case
1412 # of --disable-static-shell, a combination we do not
1413 # specifically attempt to account for.
1414 }
1415 } elseif {[opt-bool icu-collations]} {
1416 proj-warn "ignoring --enable-icu-collations because neither --with-icu-ldflags nor --with-icu-config provided any linker flags"
1417 } else {
1418 msg-result "ICU support is disabled."
1419 }
1420 }; # sqlite-handle-icu
1421
1422
1423 ########################################################################
1424 # Handles the --enable-load-extension flag. Returns 1 if the support
1425 # is enabled, else 0. If support for that feature is not found, a
1426 # fatal error is triggered if --enable-load-extension is explicitly
1427 # provided, else a loud warning is instead emitted. If
1428 # --disable-load-extension is used, no check is performed.
1429 #
1430 # Makes the following environment changes:
1431 #
1432 # - defines LDFLAGS_DLOPEN to any linker flags needed for this
1433 # feature. It may legally be empty on (A) some systems where
1434 # dlopen() is in libc and (B) certain Unix-esque Windows
1435 # environments which identify as Windows for SQLite's purposes so
1436 # use LoadLibrary().
1437 #
1438 # - If the feature is not available, adds
1439 # -DSQLITE_OMIT_LOAD_EXTENSION=1 to the feature flags list.
1440 proc sqlite-handle-load-extension {} {
1441 define LDFLAGS_DLOPEN ""
1442 set found 0
1443 set suffix ""
1444 proj-if-opt-truthy load-extension {
1445 switch -glob -- [get-define host] {
1446 *-*-mingw* - *windows* {
1447 incr found
1448 set suffix "Using LoadLibrary()"
1449 }
1450 default {
1451 set found [proj-check-function-in-lib dlopen dl]
1452 if {$found} {
1453 set suffix [define LDFLAGS_DLOPEN [get-define lib_dlopen]]
1454 undefine lib_dlopen
1455 } else {
1456 if {[proj-opt-was-provided load-extension]} {
1457 # Explicit --enable-load-extension: fail if not found
1458 proj-indented-notice -error {
1459 --enable-load-extension was provided but dlopen()
1460 not found. Use --disable-load-extension to bypass this
1461 check.
1462 }
1463 } else {
1464 # It was implicitly enabled: warn if not found
1465 proj-indented-notice {
1466 WARNING: dlopen() not found, so loadable module support will
1467 be disabled. Use --disable-load-extension to bypass this
1468 check.
1469 }
1470 }
1471 }
1472 }
1473 }
1474 }
1475 if {$found} {
1476 msg-result "Loadable extension support enabled. $suffix"
1477 } else {
1478 msg-result "Disabling loadable extension support. Use --enable-load-extension to enable them."
1479 sqlite-add-feature-flag -DSQLITE_OMIT_LOAD_EXTENSION=1
1480 }
1481 return $found
1482 }
1483
1484 ########################################################################
1485 # Handles the --enable-math flag.
1486 proc sqlite-handle-math {} {
1487 proj-if-opt-truthy math {
1488 if {![proj-check-function-in-lib ceil m]} {
1489 user-error "Cannot find libm functions. Use --disable-math to bypass this."
1490 }
1491 define LDFLAGS_MATH [get-define lib_ceil]
1492 undefine lib_ceil
1493 sqlite-add-feature-flag -DSQLITE_ENABLE_MATH_FUNCTIONS -DSQLITE_ENABLE_PERCENTILE
1494 msg-result "Enabling math SQL functions"
1495 } {
1496 define LDFLAGS_MATH ""
1497 msg-result "Disabling math SQL functions"
1498 }
1499 }
1500
1501 ########################################################################
1502 # If this OS looks like a Mac, checks for the Mac-specific
1503 # -current_version and -compatibility_version linker flags. Defines
1504 # LDFLAGS_MAC_CVERSION to an empty string and returns 0 if they're not
1505 # supported, else defines that to the linker flags and returns 1.
1506 #
1507 # We don't check this on non-Macs because this whole thing is a
1508 # libtool compatibility kludge to account for a version stamp which
1509 # libtool applied only on Mac platforms.
1510 #
1511 # Based on https://sqlite.org/forum/forumpost/9dfd5b8fd525a5d7.
1512 proc sqlite-handle-mac-cversion {} {
1513 define LDFLAGS_MAC_CVERSION ""
1514 set rc 0
1515 if {[proj-looks-like-mac]} {
1516 cc-with {-link 1} {
1517 # These version numbers are historical libtool-defined values, not
1518 # library-defined ones
1519 if {[cc-check-flags "-Wl,-current_version,9.6.0"]
1520 && [cc-check-flags "-Wl,-compatibility_version,9.0.0"]} {
1521 define LDFLAGS_MAC_CVERSION "-Wl,-compatibility_version,9.0.0 -Wl,-current_version,9.6.0"
1522 set rc 1
1523 } elseif {[cc-check-flags "-compatibility_version 9.0.0"]
1524 && [cc-check-flags "-current_version 9.6.0"]} {
1525 define LDFLAGS_MAC_CVERSION "-compatibility_version 9.0.0 -current_version 9.6.0"
1526 set rc 1
1527 }
1528 }
1529 }
1530 return $rc
1531 }
1532
1533 ########################################################################
1534 # If this is a Mac platform, check for support for
1535 # -Wl,-install_name,... and, if it's available, define
1536 # LDFLAGS_MAC_INSTALL_NAME to a variant of that string which is
1537 # intended to expand at make-time, else set LDFLAGS_MAC_INSTALL_NAME
1538 # to an empty string.
1539 #
1540 # https://sqlite.org/forum/forumpost/5651662b8875ec0a
1541 proc sqlite-handle-mac-install-name {} {
1542 define LDFLAGS_MAC_INSTALL_NAME ""; # {-Wl,-install_name,"$(install-dir.lib)/$(libsqlite3.DLL)"}
1543 set rc 0
1544 if {[proj-looks-like-mac]} {
1545 cc-with {-link 1} {
1546 if {[cc-check-flags "-Wl,-install_name,/usr/local/lib/libsqlite3.dylib"]} {
1547 define LDFLAGS_MAC_INSTALL_NAME {-Wl,-install_name,"$(install-dir.lib)/$(libsqlite3.DLL)"}
1548 set rc 1
1549 }
1550 }
1551 }
1552 return $rc
1553 }
1554
1555 #
1556 # Checks specific to HP-UX.
1557 #
1558 proc sqlite-handle-hpux {} {
1559 switch -glob -- [get-define host] {
1560 *hpux* {
1561 if {[cc-check-flags "-Ae"]} {
1562 define-append CFLAGS -Ae
1563 }
1564 }
1565 }
1566 }
1567
1568 ########################################################################
1569 # Handles the --dll-basename configure flag. [define]'s
1570 # SQLITE_DLL_BASENAME to the DLL's preferred base name (minus
1571 # extension). If --dll-basename is not provided (or programmatically
1572 # set - see [sqlite-handle-env-quirks]) then this is always
1573 # "libsqlite3", otherwise it may use a different value based on the
1574 # value of [get-define host].
1575 proc sqlite-handle-dll-basename {} {
1576 if {[proj-opt-was-provided dll-basename]} {
1577 set dn [join [opt-val dll-basename] ""]
1578 if {$dn in {none default}} { set dn libsqlite3 }
1579 } else {
1580 set dn libsqlite3
1581 }
1582 if {$dn in {auto ""}} {
1583 switch -glob -- [get-define host] {
1584 *-*-cygwin { set dn cygsqlite3-0 }
1585 *-*-ming* { set dn libsqlite3-0 }
1586 *-*-msys { set dn msys-sqlite3-0 }
1587 default { set dn libsqlite3 }
1588 }
1589 }
1590 define SQLITE_DLL_BASENAME $dn
1591 }
1592
1593 ########################################################################
1594 # [define]s LDFLAGS_OUT_IMPLIB to either an empty string or to a
1595 # -Wl,... flag for the platform-specific --out-implib flag, which is
1596 # used for building an "import library .dll.a" file on some platforms
1597 # (e.g. msys2, mingw). SQLITE_OUT_IMPLIB is defined to the name of the
1598 # import lib or an empty string. Returns 1 if supported, else 0.
1599 #
1600 # The name of the import library is [define]d in SQLITE_OUT_IMPLIB.
1601 #
1602 # If the configure flag --out-implib is not used (or programmatically
1603 # set) then this simply sets the above-listed defines to empty strings
1604 # (but see [sqlite-handle-env-quirks]). If that flag is used but the
1605 # capability is not available, a fatal error is triggered.
1606 #
1607 # This feature is specifically opt-in because it's supported on far
1608 # more platforms than actually need it and enabling it causes creation
1609 # of libsqlite3.so.a files which are unnecessary in most environments.
1610 #
1611 # Added in response to: https://sqlite.org/forum/forumpost/0c7fc097b2
1612 #
1613 # Platform notes:
1614 #
1615 # - cygwin sqlite packages historically install no .dll.a file.
1616 #
1617 # - msys2 and mingw sqlite packages historically install
1618 # /usr/lib/libsqlite3.dll.a despite the DLL being in
1619 # /usr/bin.
1620 proc sqlite-handle-out-implib {} {
1621 define LDFLAGS_OUT_IMPLIB ""
1622 define SQLITE_OUT_IMPLIB ""
1623 set rc 0
1624 if {[proj-opt-was-provided out-implib]} {
1625 set olBaseName [join [opt-val out-implib] ""]
1626 if {$olBaseName in {auto ""}} {
1627 set olBaseName "libsqlite3" ;# [get-define SQLITE_DLL_BASENAME]
1628 # Based on discussions with mingw/msys users, the import lib
1629 # should always be called libsqlite3.dll.a even on platforms
1630 # which rename libsqlite3.dll to something else.
1631 }
1632 if {$olBaseName ne "none"} {
1633 cc-with {-link 1} {
1634 set dll "${olBaseName}[get-define TARGET_DLLEXT]"
1635 set flags [proj-cc-check-Wl-flag --out-implib ${dll}.a]
1636 if {"" ne $flags} {
1637 define LDFLAGS_OUT_IMPLIB $flags
1638 define SQLITE_OUT_IMPLIB ${dll}.a
1639 set rc 1
1640 }
1641 }
1642 if {!$rc} {
1643 user-error "--out-implib is not supported on this platform"
1644 }
1645 }
1646 }
1647 return $rc
1648 }
1649
1650 ########################################################################
1651 # If the given platform identifier (defaulting to [get-define host])
1652 # appears to be one of the Unix-on-Windows environments, returns a
1653 # brief symbolic name for that environment, else returns an empty
1654 # string.
1655 #
1656 # It does not distinguish between msys and msys2, returning msys for
1657 # both. The build does not, as of this writing, specifically support
1658 # msys v1. Similarly, this function returns "mingw" for both "mingw32"
1659 # and "mingw64".
1660 proc sqlite-env-is-unix-on-windows {{envTuple ""}} {
1661 if {"" eq $envTuple} {
1662 set envTuple [get-define host]
1663 }
1664 set name ""
1665 switch -glob -- $envTuple {
1666 *-*-cygwin { set name cygwin }
1667 *-*-ming* { set name mingw }
1668 *-*-msys { set name msys }
1669 }
1670 return $name
1671 }
1672
1673 ########################################################################
1674 # Performs various tweaks to the build which are only relevant on
1675 # certain platforms, e.g. Mac and "Unix on Windows" platforms (msys2,
1676 # cygwin, ...).
1677 #
1678 # 1) DLL installation:
1679 #
1680 # [define]s SQLITE_DLL_INSTALL_RULES to a symbolic name suffix for a
1681 # set of "make install" rules to use for installation of the DLL
1682 # deliverable. The makefile is tasked with providing rules named
1683 # install-dll-NAME which runs the installation for that set, as well
1684 # as providing a rule named install-dll which resolves to
1685 # install-dll-NAME (perhaps indirectly, depending on whether the DLL
1686 # is (de)activated).
1687 #
1688 # The default value is "unix-generic".
1689 #
1690 # 2) --out-implib:
1691 #
1692 # On platforms where an "import library" is conventionally used but
1693 # --out-implib was not explicitly used, automatically add that flag.
1694 # This conventionally applies only to the "Unix on Windows"
1695 # environments like msys and cygwin.
1696 #
1697 # 3) --dll-basename:
1698 #
1699 # On the same platforms addressed by --out-implib, if --dll-basename
1700 # is not explicitly specified, --dll-basename=auto is implied.
1701 proc sqlite-handle-env-quirks {} {
1702 set instName unix-generic; # name of installation rules set
1703 set autoDll 0; # true if --out-implib/--dll-basename should be implied
1704 set host [get-define host]
1705 switch -glob -- $host {
1706 *apple* -
1707 *darwin* { set instName darwin }
1708 default {
1709 set x [sqlite-env-is-unix-on-windows $host]
1710 if {"" ne $x} {
1711 set instName $x
1712 set autoDll 1
1713 }
1714 }
1715 }
1716 define SQLITE_DLL_INSTALL_RULES $instName
1717 if {$autoDll} {
1718 if {![proj-opt-was-provided out-implib]} {
1719 # Imply --out-implib=auto
1720 proj-indented-notice [subst -nocommands -nobackslashes {
1721 NOTICE: auto-enabling --out-implib for environment [$host].
1722 Use --out-implib=none to disable this special case
1723 or --out-implib=auto to squelch this notice.
1724 }]
1725 proj-opt-set out-implib auto
1726 }
1727 if {![proj-opt-was-provided dll-basename]} {
1728 # Imply --dll-basename=auto
1729 proj-indented-notice [subst -nocommands -nobackslashes {
1730 NOTICE: auto-enabling --dll-basename for environment [$host].
1731 Use --dll-basename=default to disable this special case
1732 or --dll-basename=auto to squelch this notice.
1733 }]
1734 proj-opt-set dll-basename auto
1735 }
1736 }
1737 sqlite-handle-dll-basename
1738 sqlite-handle-out-implib
1739 sqlite-handle-mac-cversion
1740 sqlite-handle-mac-install-name
1741 if {[llength [info proc sqlite-custom-handle-flags]] > 0} {
1742 # sqlite-custom-handle-flags is assumed to be imported via a
1743 # client-specific import: autosetup/sqlite-custom.tcl.
1744 sqlite-custom-handle-flags
1745 }
1746 }
1747
1748 ########################################################################
1749 # Perform some late-stage work and generate the configure-process
1750 # output file(s).
1751 proc sqlite-process-dot-in-files {} {
1752 ########################################################################
1753 # "Re-export" the autoconf-conventional --XYZdir flags into something
1754 # which is more easily overridable from a make invocation. See the docs
1755 # for [proj-remap-autoconf-dir-vars] for the explanation of why.
1756 #
1757 # We do this late in the config process, immediately before we export
1758 # the Makefile and other generated files, so that configure tests
1759 # which make make use of the autotools-conventional flags
1760 # (e.g. [proj-check-rpath]) may do so before we "mangle" them here.
1761 proj-remap-autoconf-dir-vars
1762
1763 proj-dot-ins-process -validate
1764 make-config-header sqlite_cfg.h \
1765 -bare {SIZEOF_* HAVE_DECL_*} \
1766 -none {HAVE_CFLAG_* LDFLAGS_* SH_* SQLITE_AUTORECONFIG
1767 TARGET_* USE_GCOV TCL_*} \
1768 -auto {HAVE_* PACKAGE_*} \
1769 -none *
1770 proj-touch sqlite_cfg.h ; # help avoid frequent unnecessary @SQLITE_AUTORECONFIG@
1771 }
1772
1773 ########################################################################
1774 # Handle --with-wasi-sdk[=DIR]
1775 #
1776 # This must be run relatively early on because it may change the
1777 # toolchain and disable a number of config options. However, in the
1778 # canonical build this must come after [sqlite-check-common-bins].
1779 proc sqlite-handle-wasi-sdk {} {
1780 set wasiSdkDir [opt-val with-wasi-sdk] ; # ??? [lindex [opt-val with-wasi-sdk] end]
1781 define HAVE_WASI_SDK 0
1782 if {$wasiSdkDir eq ""} {
1783 return 0
1784 } elseif {$::sqliteConfig(is-cross-compiling)} {
1785 proj-fatal "Cannot combine --with-wasi-sdk with cross-compilation"
1786 }
1787 msg-result "Checking WASI SDK directory \[$wasiSdkDir]... "
1788 proj-affirm-files-exist -v {*}[prefix "$wasiSdkDir/bin/" {clang wasm-ld ar}]
1789 define HAVE_WASI_SDK 1
1790 define WASI_SDK_DIR $wasiSdkDir
1791 # Disable numerous options which we know either can't work or are
1792 # not useful in this build...
1793 msg-result "Using wasi-sdk clang. Disabling CLI shell and modifying config flags:"
1794 # Boolean (--enable-/--disable-) flags which must be switched off:
1795 foreach opt {
1796 dynlink-tools
1797 editline
1798 gcov
1799 icu-collations
1800 load-extension
1801 readline
1802 shared
1803 tcl
1804 threadsafe
1805 } {
1806 if {[proj-opt-exists $opt] && [opt-bool $opt]} {
1807 # -^^^^ not all builds define all of these flags
1808 msg-result " --disable-$opt"
1809 proj-opt-set $opt 0
1810 }
1811 }
1812 # Non-boolean flags which need to be cleared:
1813 foreach opt {
1814 with-emsdk
1815 with-icu-config
1816 with-icu-ldflags
1817 with-icu-cflags
1818 with-linenoise
1819 with-tcl
1820 } {
1821 if {[proj-opt-was-provided $opt]} {
1822 msg-result " removing --$opt"
1823 proj-opt-set $opt ""
1824 }
1825 }
1826 # Remember that we now have a discrepancy between
1827 # $::sqliteConfig(is-cross-compiling) and [proj-is-cross-compiling].
1828 set ::sqliteConfig(is-cross-compiling) 1
1829
1830 #
1831 # Changing --host and --target have no effect here except to
1832 # possibly cause confusion. Autosetup has finished processing them
1833 # by this point.
1834 #
1835 # host_alias=wasm32-wasi
1836 # target=wasm32-wasi
1837 #
1838 # Merely changing CC, LD, and AR to the wasi-sdk's is enough to get
1839 # sqlite3.o building in WASM format.
1840 #
1841 define CC "${wasiSdkDir}/bin/clang"
1842 define LD "${wasiSdkDir}/bin/wasm-ld"
1843 define AR "${wasiSdkDir}/bin/ar"
1844 #define STRIP "${wasiSdkDir}/bin/strip"
1845 return 1
1846 }; # sqlite-handle-wasi-sdk
1847
1848 ########################################################################
1849 # TCL...
1850 #
1851 # sqlite-check-tcl performs most of the --with-tcl and --with-tclsh
1852 # handling. Some related bits and pieces are performed before and
1853 # after that function is called.
1854 #
1855 # Important [define]'d vars:
1856 #
1857 # - HAVE_TCL indicates whether we have a tclsh suitable for building
1858 # the TCL SQLite extension and, by extension, the testing
1859 # infrastructure. This must only be 1 for environments where
1860 # tclConfig.sh can be found.
1861 #
1862 # - TCLSH_CMD is the path to the canonical tclsh or "". It never
1863 # refers to jimtcl.
1864 #
1865 # - TCL_CONFIG_SH is the path to tclConfig.sh or "".
1866 #
1867 # - TCLLIBDIR is the dir to which libtclsqlite3 gets installed.
1868 #
1869 # - BTCLSH = the path to the tcl interpreter used for in-tree code
1870 # generation. It may be jimtcl or the canonical tclsh but may not
1871 # be empty - this tree requires TCL to generated numerous
1872 # components.
1873 #
1874 # If --tcl or --with-tcl are provided but no TCL is found, this
1875 # function fails fatally. If they are not explicitly provided then
1876 # failure to find TCL is not fatal but a loud warning will be emitted.
1877 #
1878 proc sqlite-check-tcl {} {
1879 define TCLSH_CMD false ; # Significant is that it exits with non-0
1880 define HAVE_TCL 0 ; # Will be enabled via --tcl or a successful search
1881 define TCLLIBDIR "" ; # Installation dir for TCL extension lib
1882 define TCL_CONFIG_SH ""; # full path to tclConfig.sh
1883
1884 # Clear out all vars which would harvest from tclConfig.sh so that
1885 # the late-config validation of @VARS@ works even if --disable-tcl
1886 # is used.
1887 proj-tclConfig-sh-to-autosetup ""
1888
1889 file delete -force ".tclenv.sh"; # ensure no stale state from previous configures.
1890 if {![opt-bool tcl]} {
1891 proj-indented-notice {
1892 NOTE: TCL is disabled via --disable-tcl. This means that none
1893 of the TCL-based components will be built, including tests
1894 and sqlite3_analyzer.
1895 }
1896 return
1897 }
1898 # TODO: document the steps this is taking.
1899 set srcdir $::autosetup(srcdir)
1900 msg-result "Checking for a suitable tcl... "
1901 proj-assert [proj-opt-truthy tcl]
1902 set use_tcl 1
1903 set with_tclsh [opt-val with-tclsh]
1904 set with_tcl [opt-val with-tcl]
1905 if {"prefix" eq $with_tcl} {
1906 set with_tcl [get-define prefix]
1907 }
1908 proc-debug "use_tcl ${use_tcl}"
1909 proc-debug "with_tclsh=${with_tclsh}"
1910 proc-debug "with_tcl=$with_tcl"
1911 if {"" eq $with_tclsh && "" eq $with_tcl} {
1912 # If neither --with-tclsh nor --with-tcl are provided, try to find
1913 # a workable tclsh.
1914 set with_tclsh [proj-first-bin-of tclsh9.1 tclsh9.0 tclsh8.6 tclsh]
1915 proc-debug "with_tclsh=${with_tclsh}"
1916 }
1917
1918 set doConfigLookup 1 ; # set to 0 to test the tclConfig.sh-not-found cases
1919 if {"" ne $with_tclsh} {
1920 # --with-tclsh was provided or found above. Validate it and use it
1921 # to trump any value passed via --with-tcl=DIR.
1922 if {![file-isexec $with_tclsh]} {
1923 proj-fatal "TCL shell $with_tclsh is not executable"
1924 } else {
1925 define TCLSH_CMD $with_tclsh
1926 #msg-result "Using tclsh: $with_tclsh"
1927 }
1928 if {$doConfigLookup &&
1929 [catch {exec $with_tclsh $::autosetup(libdir)/find_tclconfig.tcl} result] == 0} {
1930 set with_tcl $result
1931 }
1932 if {"" ne $with_tcl && [file isdir $with_tcl]} {
1933 msg-result "$with_tclsh recommends the tclConfig.sh from $with_tcl"
1934 } else {
1935 proj-warn "$with_tclsh is unable to recommend a tclConfig.sh"
1936 set use_tcl 0
1937 }
1938 }
1939 set cfg ""
1940 set tclSubdirs {tcl9.1 tcl9.0 tcl8.6 lib}
1941 while {$use_tcl} {
1942 if {"" ne $with_tcl} {
1943 # Ensure that we can find tclConfig.sh under ${with_tcl}/...
1944 if {$doConfigLookup} {
1945 if {[file readable "${with_tcl}/tclConfig.sh"]} {
1946 set cfg "${with_tcl}/tclConfig.sh"
1947 } else {
1948 foreach i $tclSubdirs {
1949 if {[file readable "${with_tcl}/$i/tclConfig.sh"]} {
1950 set cfg "${with_tcl}/$i/tclConfig.sh"
1951 break
1952 }
1953 }
1954 }
1955 }
1956 if {"" eq $cfg} {
1957 proj-fatal "No tclConfig.sh found under ${with_tcl}"
1958 }
1959 } else {
1960 # If we have not yet found a tclConfig.sh file, look in $libdir
1961 # which is set automatically by autosetup or via the --prefix
1962 # command-line option. See
1963 # https://sqlite.org/forum/forumpost/e04e693439a22457
1964 set libdir [get-define libdir]
1965 if {[file readable "${libdir}/tclConfig.sh"]} {
1966 set cfg "${libdir}/tclConfig.sh"
1967 } else {
1968 foreach i $tclSubdirs {
1969 if {[file readable "${libdir}/$i/tclConfig.sh"]} {
1970 set cfg "${libdir}/$i/tclConfig.sh"
1971 break
1972 }
1973 }
1974 }
1975 if {![file readable $cfg]} {
1976 break
1977 }
1978 }
1979 msg-result "Using tclConfig.sh: $cfg"
1980 break
1981 }
1982 define TCL_CONFIG_SH $cfg
1983 # Export a subset of tclConfig.sh to the current TCL-space. If $cfg
1984 # is an empty string, this emits empty-string entries for the
1985 # various options we're interested in.
1986 proj-tclConfig-sh-to-autosetup $cfg
1987
1988 if {"" eq $with_tclsh && $cfg ne ""} {
1989 # We have tclConfig.sh but no tclsh. Attempt to locate a tclsh
1990 # based on info from tclConfig.sh.
1991 set tclExecPrefix [get-define TCL_EXEC_PREFIX]
1992 proj-assert {"" ne $tclExecPrefix}
1993 set tryThese [list \
1994 $tclExecPrefix/bin/tclsh[get-define TCL_VERSION] \
1995 $tclExecPrefix/bin/tclsh ]
1996 foreach trySh $tryThese {
1997 if {[file-isexec $trySh]} {
1998 set with_tclsh $trySh
1999 break
2000 }
2001 }
2002 if {![file-isexec $with_tclsh]} {
2003 proj-warn "Cannot find a usable tclsh (tried: $tryThese)
2004 }
2005 }
2006 define TCLSH_CMD $with_tclsh
2007 if {$use_tcl} {
2008 # Set up the TCLLIBDIR
2009 #
2010 # 2024-10-28: calculation of TCLLIBDIR is now done via the shell
2011 # in main.mk (search it for T.tcl.env.sh) so that
2012 # static/hand-written makefiles which import main.mk do not have
2013 # to define that before importing main.mk. Even so, we export
2014 # TCLLIBDIR from here, which will cause the canonical makefile to
2015 # use this one rather than to re-calculate it at make-time.
2016 set tcllibdir [get-env TCLLIBDIR ""]
2017 set sq3Ver [get-define PACKAGE_VERSION]
2018 if {"" eq $tcllibdir} {
2019 # Attempt to extract TCLLIBDIR from TCL's $auto_path
2020 if {"" ne $with_tclsh &&
2021 [catch {exec echo "puts stdout \$auto_path" | "$with_tclsh"} result] == 0} {
2022 foreach i $result {
2023 if {[file isdir $i]} {
2024 set tcllibdir $i/sqlite${sq3Ver}
2025 break
2026 }
2027 }
2028 } else {
2029 proj-warn "Cannot determine TCLLIBDIR."
2030 # The makefile will fail fatally in this case if a target is
2031 # invoked which requires TCLLIBDIR.
2032 }
2033 }
2034 #if {"" ne $tcllibdir} { msg-result "TCLLIBDIR = ${tcllibdir}"; }
2035 define TCLLIBDIR $tcllibdir
2036 }; # find TCLLIBDIR
2037
2038 if {[file-isexec $with_tclsh]} {
2039 msg-result "Using tclsh: $with_tclsh"
2040 if {$cfg ne ""} {
2041 define HAVE_TCL 1
2042 } else {
2043 proj-warn "Found tclsh but no tclConfig.sh."
2044 }
2045 }
2046 show-notices
2047 # If TCL is not found: if it was explicitly requested then fail
2048 # fatally, else just emit a warning. If we can find the APIs needed
2049 # to generate a working JimTCL then that will suffice for build-time
2050 # TCL purposes (see: proc sqlite-determine-codegen-tcl).
2051 if {![get-define HAVE_TCL] &&
2052 ([proj-opt-was-provided tcl] || [proj-opt-was-provided with-tcl])} {
2053 proj-fatal "TCL support was requested but no tclConfig.sh could be found."
2054 }
2055 if {"" eq $cfg} {
2056 proj-assert {0 == [get-define HAVE_TCL]}
2057 proj-indented-notice {
2058 WARNING: Cannot find a usable tclConfig.sh file. Use
2059 --with-tcl=DIR to specify a directory where tclConfig.sh can be
2060 found. SQLite does not use TCL internally, but some optional
2061 components require TCL, including tests and sqlite3_analyzer.
2062 }
2063 }
2064 }; # sqlite-check-tcl
2065
2066 ########################################################################
2067 # sqlite-determine-codegen-tcl checks which TCL to use as a code
2068 # generator. By default, prefer jimsh simply because we have it
2069 # in-tree (it's part of autosetup) unless --with-tclsh=X is used, in
2070 # which case prefer X.
2071 #
2072 # Returns the human-readable name of the TCL it selects. Fails fatally
2073 # if it cannot detect a TCL appropriate for code generation.
2074 #
2075 # Defines:
2076 #
2077 # - BTCLSH = the TCL shell used for code generation. It may set this
2078 # to an unexpanded makefile var name.
2079 #
2080 # - CFLAGS_JIMSH = any flags needed for buildng a BTCLSH-compatible
2081 # jimsh. The defaults may be passed on to configure as
2082 # CFLAGS_JIMSH=...
2083 proc sqlite-determine-codegen-tcl {} {
2084 msg-result "Checking for TCL to use for code generation... "
2085 define CFLAGS_JIMSH [proj-get-env CFLAGS_JIMSH {-O1}]
2086 set cgtcl [opt-val with-tclsh jimsh]
2087 if {"jimsh" ne $cgtcl} {
2088 # When --with-tclsh=X is used, use that for all TCL purposes,
2089 # including in-tree code generation, per developer request.
2090 define BTCLSH "\$(TCLSH_CMD)"
2091 return $cgtcl
2092 }
2093 set flagsToRestore {CC CFLAGS AS_CFLAGS CPPFLAGS AS_CPPFLAGS LDFLAGS LINKFLAGS LIBS CROSS}
2094 define-push $flagsToRestore {
2095 # We have to swap CC to CC_FOR_BUILD for purposes of the various
2096 # [cc-...] tests below. Recall that --with-wasi-sdk may have
2097 # swapped out CC with one which is not appropriate for this block.
2098 # Per consulation with autosetup's creator, doing this properly
2099 # requires us to [define-push] the whole $flagsToRestore list
2100 # (plus a few others which are not relevant in this tree).
2101 #
2102 # These will get set to their previous values at the end of this
2103 # block.
2104 foreach flag $flagsToRestore {define $flag ""}
2105 define CC [get-define CC_FOR_BUILD]
2106 # These headers are technically optional for JimTCL but necessary if
2107 # we want to use it for code generation:
2108 set sysh [cc-check-includes dirent.h sys/time.h]
2109 # jimsh0.c hard-codes #define's for HAVE_DIRENT_H and
2110 # HAVE_SYS_TIME_H on the platforms it supports, so we do not
2111 # need to add -D... flags for those. We check for them here only
2112 # so that we can avoid the situation that we later, at
2113 # make-time, try to compile jimsh but it then fails due to
2114 # missing headers (i.e. fail earlier rather than later).
2115 if {$sysh && [cc-check-functions realpath]} {
2116 define-append CFLAGS_JIMSH -DHAVE_REALPATH
2117 define BTCLSH "\$(JIMSH)"
2118 set ::sqliteConfig(use-jim-for-codegen) 1
2119 } elseif {$sysh && [cc-check-functions _fullpath]} {
2120 # _fullpath() is a Windows API. It's not entirely clear
2121 # whether we need to add {-DHAVE_SYS_TIME_H -DHAVE_DIRENT_H}
2122 # to CFLAGS_JIMSH in this case. On MinGW32 we definitely do
2123 # not want to because it already hard-codes them. On _MSC_VER
2124 # builds it does not.
2125 define-append CFLAGS_JIMSH -DHAVE__FULLPATH
2126 define BTCLSH "\$(JIMSH)"
2127 set ::sqliteConfig(use-jim-for-codegen) 1
2128 } elseif {[file-isexec [get-define TCLSH_CMD]]} {
2129 set cgtcl [get-define TCLSH_CMD]
2130 define BTCLSH "\$(TCLSH_CMD)"
2131 } else {
2132 # One last-ditch effort to find TCLSH_CMD: use info from
2133 # tclConfig.sh to try to find a tclsh
2134 if {"" eq [get-define TCLSH_CMD]} {
2135 set tpre [get-define TCL_EXEC_PREFIX]
2136 if {"" ne $tpre} {
2137 set tv [get-define TCL_VERSION]
2138 if {[file-isexec "${tpre}/bin/tclsh${tv}"]} {
2139 define TCLSH_CMD "${tpre}/bin/tclsh${tv}"
2140 } elseif {[file-isexec "${tpre}/bin/tclsh"]} {
2141 define TCLSH_CMD "${tpre}/bin/tclsh"
2142 }
2143 }
2144 }
2145 set cgtcl [get-define TCLSH_CMD]
2146 if {![file-isexec $cgtcl]} {
2147 proj-fatal "Cannot find a tclsh to use for code generation."
2148 }
2149 define BTCLSH "\$(TCLSH_CMD)"
2150 }
2151 }; # /define-push $flagsToRestore
2152 return $cgtcl
2153 }; # sqlite-determine-codegen-tcl
2154
2155 ########################################################################
2156 # Runs sqlite-check-tcl and, if this is the canonical build,
2157 # sqlite-determine-codegen-tcl.
2158 proc sqlite-handle-tcl {} {
2159 sqlite-check-tcl
2160 if {"canonical" ne $::sqliteConfig(build-mode)} return
2161 msg-result "TCL for code generation: [sqlite-determine-codegen-tcl]"
2162
2163 # Determine the base name of the Tcl extension's DLL
2164 #
2165 if {[get-define HAVE_TCL]} {
2166 if {[string match *-cygwin [get-define host]]} {
2167 set libname cyg
2168 } else {
2169 set libname lib
2170 }
2171 if {[get-define TCL_MAJOR_VERSION] > 8} {
2172 append libname tcl9
2173 }
2174 append libname sqlite
2175 } else {
2176 set libname ""
2177 }
2178 define TCL_EXT_DLL_BASENAME $libname
2179 # The extension is added in the makefile
2180 }
2181
2182 ########################################################################
2183 # Handle the --enable/disable-rpath flag.
2184 proc sqlite-handle-rpath {} {
2185 # autosetup/cc-shared.tcl sets the rpath flag definition in
2186 # [get-define SH_LINKRPATH], but it does so on a per-platform basis
2187 # rather than as a compiler check. Though we should do a proper
2188 # compiler check (as proj-check-rpath does), we may want to consider
2189 # adopting its approach of clearing the rpath flags for environments
2190 # for which sqlite-env-is-unix-on-windows returns a non-empty
2191 # string.
2192
2193 # https://sqlite.org/forum/forumpost/13cac3b56516f849
2194 if {[proj-opt-truthy rpath]} {
2195 proj-check-rpath
2196 } else {
2197 msg-result "Disabling use of rpath."
2198 define LDFLAGS_RPATH ""
2199 }
2200 }
2201
2202 ########################################################################
2203 # If the --dump-defines configure flag is provided then emit a list of
2204 # all [define] values to config.defines.txt, else do nothing.
2205 proc sqlite-dump-defines {} {
2206 proj-if-opt-truthy dump-defines {
2207 make-config-header $::sqliteConfig(dump-defines-txt) \
2208 -bare {SQLITE_OS* SQLITE_DEBUG USE_*} \
2209 -str {BIN_* CC LD AR LDFLAG* OPT_*} \
2210 -auto {*}
2211 # achtung: ^^^^ whichever SQLITE_OS_foo flag which is set to 0 will
2212 # get _undefined_ here unless it's part of the -bare set.
2213 if {"" ne $::sqliteConfig(dump-defines-json)} {
2214 msg-result "--dump-defines is creating $::sqliteConfig(dump-defines-json)"
2215 ########################################################################
2216 # Dump config-defines.json...
2217 # Demonstrate (mis?)handling of spaces in JSON-export array values:
2218 # define-append OPT_FOO.list {"-DFOO=bar baz" -DBAR="baz barre"}
2219 define OPT_FEATURE_FLAGS.list [get-define OPT_FEATURE_FLAGS]
2220 define OPT_SHELL.list [get-define OPT_SHELL]
2221 set dumpDefsOpt {
2222 -bare {SIZEOF_* HAVE_DECL_*}
2223 -none {HAVE_CFLAG_* LDFLAGS_* SH_* SQLITE_AUTORECONFIG TARGET_* USE_GCOV TCL_*}
2224 -array {*.list}
2225 -auto {OPT_* PACKAGE_* HAVE_*}
2226 }
2227 # if {$::sqliteConfig(dump-defines-json-include-lowercase)} {
2228 # lappend dumpDefsOpt -none {lib_*} ; # remnants from proj-check-function-in-lib and friends
2229 # lappend dumpDefsOpt -auto {[a-z]*}
2230 # }
2231 lappend dumpDefsOpt -none *
2232 proj-dump-defs-json $::sqliteConfig(dump-defines-json) {*}$dumpDefsOpt
2233 undefine OPT_FEATURE_FLAGS.list
2234 undefine OPT_SHELL.list
2235 }
2236 }
2237 }