1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 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 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322
|
#!/usr/bin/tclsh
#
set help \
{Run this TCL script to build and install the TCL interface library for
SQLite. Run the script with the specific "tclsh" for which the installation
should occur.
There must be a valid "tclsqlite3.c" file in the working directory prior
to running this script. Use "make tclsqlite3.c" to generate that file.
Options:
--build-only Only build the extension, don't install it
--cc COMPILER Build using this compiler
--info Show info on existing SQLite TCL extension installs
--install-only Install an extension previously build
--uninstall Uninstall the extension
--version-check Check extension version against this source tree
--destdir DIR Installation root (used by "make install DESTDIR=...")
Other options are retained and passed through into the compiler.}
set build 1
set install 1
set uninstall 0
set infoonly 0
set versioncheck 0
set CC {}
set OPTS {}
set DESTDIR ""; # --destdir "$(DESTDIR)"
for {set ii 0} {$ii<[llength $argv]} {incr ii} {
set a0 [lindex $argv $ii]
if {$a0=="--install-only"} {
set build 0
} elseif {$a0=="--build-only"} {
set install 0
} elseif {$a0=="--uninstall"} {
set build 0
set install 0
set versioncheck 0
set uninstall 1
} elseif {$a0=="--info"} {
set build 0
set install 0
set versioncheck 0
set infoonly 1
} elseif {$a0=="--version-check"} {
set build 0
set install 0
set infoonly 0
set versioncheck 1
} elseif {$a0=="--cc" && $ii+1<[llength $argv]} {
incr ii
set CC [lindex $argv $ii]
} elseif {$a0=="--destdir" && $ii+1<[llength $argv]} {
incr ii
set DESTDIR [lindex $argv $ii]
} elseif {[string match -* $a0]} {
append OPTS " $a0"
} else {
puts stderr "Unknown option: \"$a0\"\n"
puts stderr $help
exit 1
}
}
# Find the root of the SQLite source tree
#
set srcdir [file normalize [file dir $argv0]/..]
# Get the SQLite version number into $VERSION
#
set fd [open $srcdir/VERSION]
set VERSION [string trim [read $fd]]
close $fd
if {$tcl_platform(platform) eq "windows"} {
# We are only able to install, uninstall, and list on Windows.
# The build process is handled by the Makefile.msc, specifically
# using "nmake /f Makefile.msc pkgIndex.tcl tclsqlite3.dll"
#
if {$build} {
puts "Unable to build on Windows using the builttclext.tcl script."
puts "To build, run\n"
puts " \"nmake /f Makefile.msc pkgIndex.tcl tclsqlite3.dll"
exit 1
}
set OUT tclsqlite3.dll
} else {
# Figure out the location of the tclConfig.sh file used by the
# tclsh that is executing this script.
#
if {[catch {
set LIBDIR [tcl::pkgconfig get libdir,install]
}]} {
puts stderr "$argv0: tclsh does not support tcl::pkgconfig."
exit 1
}
if {![file exists $LIBDIR]} {
puts stderr "$argv0: cannot find the tclConfig.sh file."
puts stderr "$argv0: tclsh reported library directory \"$LIBDIR\"\
does not exist."
exit 1
}
if {![file exists $LIBDIR/tclConfig.sh]
|| [file size $LIBDIR/tclConfig.sh]<5000} {
set n1 $LIBDIR/tcl$::tcl_version
if {[file exists $n1/tclConfig.sh]
&& [file size $n1/tclConfig.sh]>5000} {
set LIBDIR $n1
} else {
puts stderr "$argv0: cannot find tclConfig.sh in either $LIBDIR or $n1"
exit 1
}
}
# Read the tclConfig.sh file into the $tclConfig variable
#
#puts "using $LIBDIR/tclConfig.sh"
set fd [open $LIBDIR/tclConfig.sh rb]
set tclConfig [read $fd]
close $fd
# Extract parameter we will need from the tclConfig.sh file
#
set TCLMAJOR 8
regexp {TCL_MAJOR_VERSION='(\d)'} $tclConfig all TCLMAJOR
set SUFFIX so
regexp {TCL_SHLIB_SUFFIX='\.([^']+)'} $tclConfig all SUFFIX
if {$CC==""} {
set cc {}
regexp {TCL_CC='([^']+)'} $tclConfig all cc
if {$cc!=""} {
set CC $cc
}
}
if {$CC==""} {
set CC gcc
}
set CFLAGS -fPIC
regexp {TCL_SHLIB_CFLAGS='([^']+)'} $tclConfig all CFLAGS
set LIBS {}
regexp {TCL_STUB_LIB_SPEC='([^']+)'} $tclConfig all LIBS
set INC "-I$srcdir/src"
set inc {}
regexp {TCL_INCLUDE_SPEC='([^']+)'} $tclConfig all inc
if {$inc!=""} {
append INC " $inc"
}
set cmd {${CC} ${CFLAGS} ${LDFLAGS} -shared}
regexp {TCL_SHLIB_LD='([^']+)(-Wl,--out-implib.*)?'} $tclConfig all cmd
set LDFLAGS "$INC -DUSE_TCL_STUBS"
if {[string length $OPTS]>1} {
append LDFLAGS $OPTS
}
if {$tcl_platform(os) eq "Windows NT"} {
set OUT cyg
} else {
set OUT lib
}
if {$TCLMAJOR>8} {
set OUT ${OUT}tcl9sqlite$VERSION.$SUFFIX
} else {
set OUT ${OUT}sqlite$VERSION.$SUFFIX
}
set @ $OUT; # Workaround for https://sqlite.org/forum/forumpost/0683a49cb02f31a1
# in which Gentoo edits their tclConfig.sh to include an soname
# linker flag which includes ${@} (the target file's name).
set CMD [subst $cmd]
}
# Check the SQLite TCL extension that is loaded by default by this running
# TCL interpreter to see if it has the same SQLITE_SOURCE_ID as the source
# code in the directory holding this script.
#
if {$versioncheck} {
if {[catch {package require sqlite3} msg]} {
puts stderr "No SQLite TCL extension available: $msg"
exit 1
}
sqlite3 db :memory:
set extvers [db one {SELECT sqlite_source_id()}]
db close
set fd [open sqlite3.h rb]
set sqlite3h [read $fd]
close $fd
regexp {#define SQLITE_SOURCE_ID +"([^"]+)"} $sqlite3h all srcvers
set srcvers [string range $srcvers 0 78]
set extvers [string range $extvers 0 78]
if {$srcvers==$extvers} {
puts "source code and extension versions aligned:\n$extvers"
exit 0
}
puts stderr "source code and extension versions differ"
puts stderr "source: $srcvers\nextension: $extvers"
exit 1
}
# Show information about prior installs
#
if {$infoonly} {
set cnt 0
foreach dir $auto_path {
foreach subdir [glob -nocomplain -types d $dir/sqlite3*] {
if {[file exists $subdir/pkgIndex.tcl]} {
puts $subdir
incr cnt
}
}
}
if {$cnt==0} {
puts "no current installations of the SQLite TCL extension"
}
exit
}
# Uninstall the extension
#
if {$uninstall} {
set cnt 0
foreach dir $auto_path {
if {[file isdirectory $dir/sqlite$VERSION]} {
incr cnt
if {![file writable $dir] || ![file writable $dir/sqlite$VERSION]} {
puts "cannot uninstall $dir/sqlite$VERSION - permission denied"
} else {
puts "uninstalling $dir/sqlite$VERSION..."
file delete -force $dir/sqlite$VERSION
}
}
}
if {$cnt==0} {
puts "nothing to uninstall"
}
exit
}
if {$install} {
# Figure out where the extension will be installed. Put the extension
# in the first writable directory on $auto_path.
#
set DEST {}
foreach dir $auto_path {
if {[string match //*:* $dir]} {
# We can't install to //zipfs: paths
continue
} elseif {"" ne $DESTDIR && ![file writable $DESTDIR]} {
# In the common case, ${DESTDIR}${dir} will not exist when we
# get to this point of the installation, and the "is writable?"
# check just below this will fail for that case.
#
# Assumption made for simplification's sake: if ${DESTDIR} is
# not writable, no part of the remaining path will
# be. ${DESTDIR} is typically used by OS package maintainers,
# not normal installations, and it "shouldn't" ever happen that
# the DESTDIR is read-only while the target ${DESTDIR}${prefix}
# is not, as it's typical for such installations to create
# ${prefix} on-demand under ${DESTDIR}.
break
}
set dir ${DESTDIR}$dir
if {[file writable $dir] || "" ne $DESTDIR} {
# the dir will be created later ^^^^^^^^
set DEST $dir
break
} elseif {[glob -nocomplain $dir/sqlite3*/pkgIndex.tcl]!=""} {
set conflict [lindex [glob $dir/sqlite3*/pkgIndex.tcl] 0]
puts "Unable to install. There is already a conflicting version"
puts "of the SQLite TCL Extension that cannot be overwritten at\n"
puts " [file dirname $conflict]\n"
puts "Consider running using sudo to work around this problem."
exit 1
}
}
if {$DEST==""} {
puts "None of the directories on \$auto_path are writable by this process,"
puts "so the installation cannot take place. Consider running using sudo"
puts "to work around this problem.\n"
puts "These are the (unwritable) \$auto_path directories:\n"
foreach dir $auto_path {
puts " * ${DESTDIR}$dir"
}
exit 1
}
}
if {$build} {
# Generate the pkgIndex.tcl file
#
puts "generating pkgIndex.tcl..."
set fd [open pkgIndex.tcl w]
puts $fd [subst -nocommands {# -*- tcl -*-
# Tcl package index file, version ???
#
package ifneeded sqlite3 $VERSION \\
[list load [file join \$dir $OUT] Sqlite3]
}]
close $fd
# Generate and execute the command with which to do the compilation.
#
set cmd "$CMD -DUSE_TCL_STUBS tclsqlite3.c -o $OUT $LIBS"
puts $cmd
file delete -force $OUT
catch {exec {*}$cmd} errmsg
if {$errmsg!="" && ![file exists $OUT]} {
puts $errmsg
exit 1
}
}
if {$install} {
# Install the extension
set DEST2 $DEST/sqlite$VERSION
file mkdir $DEST2
puts "installing $DEST2/pkgIndex.tcl"
file copy -force pkgIndex.tcl $DEST2
puts "installing $DEST2/$OUT"
file copy -force $OUT $DEST2
}
|