SQLite

Check-in [2ddeb7a8]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Bring the automated readline detection up to parity with the legacy configure script.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: 2ddeb7a8f55735cc7f2cf95cbbb0b20c563ced87db1429816fcfb0ee89e751f0
User & Date: stephan 2024-10-27 04:27:47
Context
2024-10-27
05:28
configure: document why --enable-editline does not work and emit a warning with a potential alternative/workaround if it's used. Various cosmetic cleanups. (check-in: ccb8f16f user: stephan tags: trunk)
04:27
Bring the automated readline detection up to parity with the legacy configure script. (check-in: 2ddeb7a8 user: stephan tags: trunk)
02:27
Rename --with-readline-ldflags/cflags to --with-readline-lib/inc because it turns out that ldflags/cflags have (when passed an explicit value) the same semantics the legacy lib/inc flags. Still to-fix is that the no-flag-given readline search behavior differs, and is much more limited, from the legacy configure behavior. (check-in: 8f6897b9 user: stephan tags: trunk)
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to auto.def.

13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
# JimTCL: https://jim.tcl.tk
#


use cc cc-db cc-shared cc-lib hwaci-common pkg-config

# Are we cross-compiling?
set cross_compiling 0
if {[get-define host] ne [get-define build]} {
  set cross_compiling 1
} elseif {1
          && "nope" eq [get-env CC_FOR_BUILD "nope"]
          && [get-define CC] ne [get-define CC_FOR_BUILD]} {
  # Arguable/debatable...
  #
  # When _not_ cross-compiling and CC_FOR_BUILD is _not_ explcitely
  # specified, force CC_FOR_BUILD to be the same as CC, so that:
  #
  # ./configure CC=clang
  #







|
|
|
<
|
|







13
14
15
16
17
18
19
20
21
22

23
24
25
26
27
28
29
30
31
# JimTCL: https://jim.tcl.tk
#


use cc cc-db cc-shared cc-lib hwaci-common pkg-config

# Are we cross-compiling?
set cross_compiling [hwaci-is-cross-compiling]
if {0
    && !$cross_compiling

    && "nope" eq [get-env CC_FOR_BUILD "nope"]
    && [get-define CC] ne [get-define CC_FOR_BUILD]} {
  # Arguable/debatable...
  #
  # When _not_ cross-compiling and CC_FOR_BUILD is _not_ explcitely
  # specified, force CC_FOR_BUILD to be the same as CC, so that:
  #
  # ./configure CC=clang
  #
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
  largefile=1          => {Disable large file support}
  shared=1             => {Disable build of shared libary}
  with-readline-lib:LDFLAGS
                       => {Readline LDFLAGS, e.g. -lreadline -lncurses}
  with-readline-inc:CFLAGS
                       => {Readline CFLAGS, e.g. -I/path/to/includes}
  with-readline-header:PATH
                       => {Full path to readline.h, from which --with-readline-inc will be derived.}
  with-linenoise:DIR   => {Source directory for linenoise.c and linenoise.h}
  amalgamation=1       => {Disable the amalgamation and instead build all files separately}
  load-extension=1     => {Disable loading of external extensions}
  math=1               => {Disable math functions}
  json=1               => {Disable JSON functions}
  all                  => {Enable FTS4, FTS5, Geopoly, RTree, Sessions}
  memsys5              => {Enable MEMSYS5}







|







165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
  largefile=1          => {Disable large file support}
  shared=1             => {Disable build of shared libary}
  with-readline-lib:LDFLAGS
                       => {Readline LDFLAGS, e.g. -lreadline -lncurses}
  with-readline-inc:CFLAGS
                       => {Readline CFLAGS, e.g. -I/path/to/includes}
  with-readline-header:PATH
                       => {Full path to readline.h, from which --with-readline-inc will be derived}
  with-linenoise:DIR   => {Source directory for linenoise.c and linenoise.h}
  amalgamation=1       => {Disable the amalgamation and instead build all files separately}
  load-extension=1     => {Disable loading of external extensions}
  math=1               => {Disable math functions}
  json=1               => {Disable JSON functions}
  all                  => {Enable FTS4, FTS5, Geopoly, RTree, Sessions}
  memsys5              => {Enable MEMSYS5}
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805

806
807
808
809
810
811
812
813
814
815
816
817



818














819






























820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
  }
  msg-result $ts
  define TEMP_STORE $tsn
  unset ts tsn
}

########################################################################
# hwaci-check-line-editing jumps through proverbial hoops to try to
# find a working line-editing library, setting:
#
#   - HAVE_READLINE to 0 or 1
#   - HAVE_LINENOISE to 0 or 1
#   - HAVE_EDITLINE to 0 or 1
#
#   - LDFLAGS_READLINE = linker flags or empty string
#
#   - CFLAGS_READLINE = compilation flags for clients or empty string
#
# Note that LDFLAGS_READLINE and CFLAGS_READLINE may refer to
# linenoise or editline, not necessarily libreadline.
#
# Returns a string describing which line-editing approach to use, or
# "none" if no option is available.
proc hwaci-check-line-editing {} {
  define HAVE_READLINE 0
  define HAVE_LINENOISE 0
  define HAVE_EDITLINE 0
  define LDFLAGS_READLINE ""
  define CFLAGS_READLINE ""
  set check [opt-val with-linenoise]
  if {"" ne $check} {
    # Use linenoise...
    set dirLn $check
    if {![file isdir $dirLn]} {
      hwaci-fatal "--with-linenoise value is not a directory"
    }
    if {![file exists $dirLn/linenoise.c] } {
      hwaci-fatal "Cannot find linenoise.c in $dirLn"
    }
    if {![file exists $dirLn/linenoise.h] } {
      hwaci-fatal "Cannot find linenoise.h in $dirLn"
    }
    user-notice "Using linenoise from $dirLn"
    define CFLAGS_READLINE "-I$dirLn $dirLn/linenoise.c"
    define HAVE_LINENOISE 1
    add-shell-opt -DHAVE_LINENOISE=1
    return "linenoise"
  } elseif {[opt-bool editline]} {
    # Use editline...
    user-notice "WARNING: the --enable-editline flag is not yet supported"
    return "none"
  } elseif {![opt-bool readline]} {
    user-notice "Readline support explicitly disabled with --disable-readline."
    return "none"
  }
  set check [opt-val with-readline-lib][opt-val with-readline-inc]
  if {"" ne $check} {
    # If any one of --with-readline-(lib|inc|header) are provided,
    # those trump any automated searching.
    set fL [join [opt-val with-readline-lib]]
    set v [opt-val with-readline-header]
    if {"" eq $v} {

      set fC [join [opt-val with-readline-inc]]
    } else {
      # Derive CFLAGS from header file name
      set v [file dirname $v]
      if {[string match */*line $v]} {
        # Special case: if the path includes .../*line/readline.h", set
        # the -I to one dir up from that because our sources include
        # <readline/readline.h> or <editline/readline.h>.  Reminder: if
        # auto.def is being run by jimsh0 then [file normalize] will not
        # work!
        set v [file dirname $v]
      }



      set fC "-I$v"














    }






























    define LDFLAGS_READLINE $fL
    define CFLAGS_READLINE $fC
    define HAVE_READLINE 1
    add-shell-opt -DHAVE_READLINE=1
    user-notice "Using client-provided readline flags: $fC $fL"
    return "readline"
  }

  # Try the project-agnostic readline detector:
  set v [hwaci-check-readline]
  add-shell-opt -DHAVE_READLINE=$v
  if {$v} { return "readline" }
  # TODO: reimplement:
  #  --enable-editline
  return "none"
}; # hwaci-check-line-editing
msg-checking "Line-editing support for the sqlite3 shell: "
msg-result [hwaci-check-line-editing]

hwaci-if-opt-truthy load-extension {
  if {[hwaci-check-function-in-lib dlopen dl]} {
    define LDFLAGS_DLOPEN [get-define lib_dlopen]
    undefine lib_dlopen
  } else {
    user-error "dlopen() not found. Use --disable-load-extension to bypass this check."







|















|











<
|

<
|








|



|


|
<
|
<
|
|
|
>
|

<









>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
|


|



<
<
<
<
<
<

|
|
<







743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777

778
779

780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796

797

798
799
800
801
802
803

804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869






870
871
872

873
874
875
876
877
878
879
  }
  msg-result $ts
  define TEMP_STORE $tsn
  unset ts tsn
}

########################################################################
# sqlite-check-line-editing jumps through proverbial hoops to try to
# find a working line-editing library, setting:
#
#   - HAVE_READLINE to 0 or 1
#   - HAVE_LINENOISE to 0 or 1
#   - HAVE_EDITLINE to 0 or 1
#
#   - LDFLAGS_READLINE = linker flags or empty string
#
#   - CFLAGS_READLINE = compilation flags for clients or empty string
#
# Note that LDFLAGS_READLINE and CFLAGS_READLINE may refer to
# linenoise or editline, not necessarily libreadline.
#
# Returns a string describing which line-editing approach to use, or
# "none" if no option is available.
proc sqlite-check-line-editing {} {
  define HAVE_READLINE 0
  define HAVE_LINENOISE 0
  define HAVE_EDITLINE 0
  define LDFLAGS_READLINE ""
  define CFLAGS_READLINE ""
  set check [opt-val with-linenoise]
  if {"" ne $check} {
    # Use linenoise...
    set dirLn $check
    if {![file isdir $dirLn]} {
      hwaci-fatal "--with-linenoise value is not a directory"

    } elseif {![file exists $dirLn/linenoise.c] } {
      hwaci-fatal "Cannot find linenoise.c in $dirLn"

    } elseif {![file exists $dirLn/linenoise.h] } {
      hwaci-fatal "Cannot find linenoise.h in $dirLn"
    }
    user-notice "Using linenoise from $dirLn"
    define CFLAGS_READLINE "-I$dirLn $dirLn/linenoise.c"
    define HAVE_LINENOISE 1
    add-shell-opt -DHAVE_LINENOISE=1
    return "linenoise"
  } elseif {[opt-bool editline]} {
    # TODO: reimplement --enable-editline
    user-notice "WARNING: the --enable-editline flag is not yet supported"
    return "none"
  } elseif {![opt-bool readline]} {
    user-notice "Readline support explicitly disabled with --disable-readline"
    return "none"
  }


  # Transform with-readline-header=X to with-readline-inc=-I...

  set v [opt-val with-readline-header]
  hwaci-opt-set with-readline-header ""
  if {"" ne $v} {
    if {"auto" eq $v} {
      hwaci-opt-set with-readline-inc auto
    } else {

      set v [file dirname $v]
      if {[string match */*line $v]} {
        # Special case: if the path includes .../*line/readline.h", set
        # the -I to one dir up from that because our sources include
        # <readline/readline.h> or <editline/readline.h>.  Reminder: if
        # auto.def is being run by jimsh0 then [file normalize] will not
        # work!
        set v [file dirname $v]
      }
      hwaci-opt-set with-readline-inc "-I$v"
    }
  }

  # Look for readline.h
  set rlInc [opt-val with-readline-inc auto]
  if {"auto" eq $rlInc} {
    set rlInc ""
    if {!$::cross_compiling} {
      # ^^^ this check is derived from the legacy configure script
      set rlInc [hwaci-search-for-header-dir readline.h \
                 -dirs {/usr /usr/local /usr/local/readline /usr/contrib /mingw} \
                 -subdirs {include/readline include}]
      # ^^^ The -dirs and -subdirs lists are from the legacy configure script
      if {"" ne $rlInc} {
        if {[string match */*line $rlInc]} {
          # See notes above for --with-readline-header
          set rlInc [file dirname $rlInc]
        }
        set rlInc "-I${rlInc}"
      }
    }
  }

  # If readline.h was found/specified, look for libreadline...
  set rlLib ""
  if {"" ne $rlInc} {
    set rlLib [opt-val with-readline-lib]
    if {"" eq $rlLib || "auto" eq $rlLib} {
      set rlLib ""
      set libTerm ""
      if {[hwaci-check-function-in-lib tgetent {readline ncurses curses termcap}]} {
        # ^^^ that libs list comes from the legacy configure script ^^^
        set libTerm [get-define lib_tgetent]
        undefine lib_tgetent
      }
      if {"readline" eq $libTerm} {
        set rlLib $libTerm
      } elseif {[hwaci-check-function-in-lib readline readline $libTerm]} {
        set rlLib [get-define lib_readline]
        lappend rlLib $libTerm
        undefine lib_readline
      }
    }
  }

  if {"" ne $rlLib} {
    set rlLib [join $rlLib]
    set rlInc [join $rlInc]
    define LDFLAGS_READLINE $rlLib
    define CFLAGS_READLINE $rlInc
    define HAVE_READLINE 1
    add-shell-opt -DHAVE_READLINE=1
    user-notice "Using readline flags: $rlInc $rlLib"
    return "readline"
  }







  return "none"
}; # sqlite-check-line-editing
msg-result "Line-editing support for the sqlite3 shell: [sqlite-check-line-editing]"


hwaci-if-opt-truthy load-extension {
  if {[hwaci-check-function-in-lib dlopen dl]} {
    define LDFLAGS_DLOPEN [get-define lib_dlopen]
    undefine lib_dlopen
  } else {
    user-error "dlopen() not found. Use --disable-load-extension to bypass this check."

Changes to autosetup/hwaci-common.tcl.

51
52
53
54
55
56
57






58
59
60
61
62
63
64
}
proc hwaci-notice {msg} {
  puts stderr "NOTICE: $msg"
}
proc hwaci-fatal {msg} {
  user-error "ERROR: $msg"
}







########################################################################
# hwaci-lshift_ shifts $count elements from the list named $listVar
# and returns them as a new list. On empty input, returns "".
#
# Modified slightly from: https://wiki.tcl-lang.org/page/lshift
proc hwaci-lshift_ {listVar {count 1}} {







>
>
>
>
>
>







51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
}
proc hwaci-notice {msg} {
  puts stderr "NOTICE: $msg"
}
proc hwaci-fatal {msg} {
  user-error "ERROR: $msg"
}

########################################################################
# Returns 1 if cross-compiling, else 0.
proc hwaci-is-cross-compiling {} {
  return [expr {[get-define host] ne [get-define build]}]
}

########################################################################
# hwaci-lshift_ shifts $count elements from the list named $listVar
# and returns them as a new list. On empty input, returns "".
#
# Modified slightly from: https://wiki.tcl-lang.org/page/lshift
proc hwaci-lshift_ {listVar {count 1}} {
83
84
85
86
87
88
89































90
91
92
93
94
95
96
proc hwaci-check-function-in-lib {function libs {otherlibs {}}} {
  set found 0
  define-push {LIBS} {
    set found [cc-check-function-in-lib $function $libs $otherlibs]
  }
  return $found
}
































########################################################################
# If $v is true, [puts $msg] is called, else puts is not called.
#proc hwaci-maybe-verbose {v msg} {
#  if {$v} {
#    puts $msg
#  }







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
proc hwaci-check-function-in-lib {function libs {otherlibs {}}} {
  set found 0
  define-push {LIBS} {
    set found [cc-check-function-in-lib $function $libs $otherlibs]
  }
  return $found
}

########################################################################
# Searches for $header in a combination of dirs and subdirs, specified
# by the -dirs {LIST} and -subdirs {LIST} flags (each of which have
# sane defaults). Returns either the first matching dir or an empty
# string.  The return value does not contain the filename part.
proc hwaci-search-for-header-dir {header args} {
  set subdirs {include}
  set dirs {/usr /usr/local /mingw}
# Debatable:
#  if {![hwaci-is-cross-compiling]} {
#    lappend dirs [get-define prefix]
#  }
  while {[llength $args]} {
    switch -exact -- [lindex $args 0] {
      -dirs     { set args [lassign $args - dirs] }
      -subdirs  { set args [lassign $args - subdirs] }
      default   {
        hwaci-fatal "Unhandled argument: $args"
      }
    }
  }
  foreach dir $dirs {
    foreach sub $subdirs {
      if {[file exists $dir/$sub/$header]} {
        return "$dir/$sub"
      }
    }
  }
  return ""
}

########################################################################
# If $v is true, [puts $msg] is called, else puts is not called.
#proc hwaci-maybe-verbose {v msg} {
#  if {$v} {
#    puts $msg
#  }
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724







725
726
727
728
729
730
731
      set rc 0
    }
  }
  return $rc
}

########################################################################
# Check for libreadline functionality.  Linking in readline varies
# wildly by platform and this check does not cover all known options.
# This detection is known to fail under the following conditions:
#
# - (pkg-config readline) info is either unavailable for libreadline or
#   simply misbehaves.
#
# - Compile-and-link-with-default-path tests fail. This will fail for
#   platforms which store readline under, e.g., /usr/local.
#
# Defines the following vars:
#
# - HAVE_READLINE: 0 or 1
# - LDFLAGS_READLINE: "" or linker flags
# - CFLAGS_READLINE: "" or c-flags
#







# Returns the value of HAVE_READLINE.
proc hwaci-check-readline {} {
  define HAVE_READLINE 0
  define LDFLAGS_READLINE ""
  define CFLAGS_READLINE ""
  if {![opt-bool readline]} {
    msg-result "libreadline disabled via --disable-readline."







|






<
|







>
>
>
>
>
>
>







739
740
741
742
743
744
745
746
747
748
749
750
751
752

753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
      set rc 0
    }
  }
  return $rc
}

########################################################################
# Check for availability of libreadline.  Linking in readline varies
# wildly by platform and this check does not cover all known options.
# This detection is known to fail under the following conditions:
#
# - (pkg-config readline) info is either unavailable for libreadline or
#   simply misbehaves.
#

# - Either of readline.h or libreadline are in an exotic place.
#
# Defines the following vars:
#
# - HAVE_READLINE: 0 or 1
# - LDFLAGS_READLINE: "" or linker flags
# - CFLAGS_READLINE: "" or c-flags
#
# Quirks:
#
# - If readline.h is found in a directory name matching *line then the
#   resulting -I... flag points one directory _up_ from that, under
#   the assumption that client-side code will #include
#   <readline/readline.h>.
#
# Returns the value of HAVE_READLINE.
proc hwaci-check-readline {} {
  define HAVE_READLINE 0
  define LDFLAGS_READLINE ""
  define CFLAGS_READLINE ""
  if {![opt-bool readline]} {
    msg-result "libreadline disabled via --disable-readline."
752
753
754
755
756
757
758










759







760




761

762
763




764

765
766
767
768
769
770
771
772
773


774
775




776
777
778
779
780
781
782
783
  # 1
  #
  # i.e. there's apparently no way to find out that readline requires
  # termcap beyond parsing the error message.  It turns out it doesn't
  # want termcap, it wants -lcurses, but we don't get that info from
  # pkg-config either.











  set h "readline/readline.h"







  if {[cc-check-includes $h]} {




    if {[hwaci-check-function-in-lib readline readline]} {

      msg-result "Enabling libreadline."
      define HAVE_READLINE 1




      define LDFLAGS_READLINE [get-define lib_readline]

      undefine lib_readline
      return 1
    }
    # else TODO: look in various places and [define CFLAGS_READLINE
    # -I...]
  }
  # Numerous TODOs:
  # - Requires linking with [n]curses or similar on some platforms.
  # - Headers are in a weird place on some BSD systems.


  # - Add --with-readline=DIR
  # - Add --with-readline-lib=lib ==> pass lib file via LDFLAGS_READLINE




  # - Add --with-readline-inc=dir ==> pass -Idir via CFLAGS_READLINE
  msg-result "libreadline not found."
  return 0
}


########################################################################
# Internal helper for hwaci-dump-defs-json. Expects to be passed a







>
>
>
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
|
>
>
>
>
|
>
|
|
>
>
>
>
|
>

<

<
<

|
<
<
>
>
|
|
>
>
>
>
|







795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835

836


837
838


839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
  # 1
  #
  # i.e. there's apparently no way to find out that readline requires
  # termcap beyond parsing the error message.  It turns out it doesn't
  # want termcap, it wants -lcurses, but we don't get that info from
  # pkg-config either.

  # Look for readline.h
  set rlInc ""
  if {![hwaci-is-cross-compiling]} {
    # ^^^ this check is derived from SQLite's legacy configure script
    set rlInc [hwaci-search-for-header-dir readline.h \
                 -subdirs {include/readline include}]
    if {"" ne $rlInc} {
      if {[string match */*line $rlInc]} {
        # Special case: if the path includes .../*line/readline.h", set
        # the -I to one dir up from that because our sources include
        # <readline/readline.h> or <editline/readline.h>. Reminder: if
        # auto.def is being run by jimsh0 then [file normalize] will not
        # work!
        set rlInc [file dirname $v]
      }
      set rlInc "-I${rlInc}"
    }
  }

  # If readline.h was found/specified, look for libreadline...
  set rlLib ""
  if {"" ne $rlInc} {
    set libTerm ""
    if {[hwaci-check-function-in-lib tgetent {readline ncurses curses termcap}]} {
      # ^^^ check extracted from an ancient autotools configure script.
      set libTerm [get-define lib_tgetent]
      undefine lib_tgetent
    }
    if {"readline" eq $libTerm} {
      set rlLib $libTerm
    } elseif {[hwaci-check-function-in-lib readline readline $libTerm]} {
      set rlLib [get-define lib_readline]
      lappend rlLib $libTerm
      undefine lib_readline

    }


  }



  if {"" ne $rlLib} {
    set rlLib [join $rlLib]
    define LDFLAGS_READLINE $rlLib
    define CFLAGS_READLINE $rlInc
    define HAVE_READLINE 1
    msg-result "Using readline with flags: $rlInc $rlLib"
    return 1
  }

  msg-result "libreadline not found."
  return 0
}


########################################################################
# Internal helper for hwaci-dump-defs-json. Expects to be passed a