sqlite3 1.4.2 → 1.5.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,100 +1,252 @@
1
- ENV['RC_ARCHS'] = '' if RUBY_PLATFORM =~ /darwin/
2
-
3
- require 'mkmf'
4
-
5
- # :stopdoc:
6
-
7
- RbConfig::MAKEFILE_CONFIG['CC'] = ENV['CC'] if ENV['CC']
8
-
9
- ldflags = cppflags = nil
10
- if RbConfig::CONFIG["host_os"] =~ /darwin/
11
- begin
12
- if with_config('sqlcipher')
13
- brew_prefix = `brew --prefix sqlcipher`.chomp
14
- ldflags = "#{brew_prefix}/lib"
15
- cppflags = "#{brew_prefix}/include/sqlcipher"
16
- pkg_conf = "#{brew_prefix}/lib/pkgconfig"
17
- else
18
- brew_prefix = `brew --prefix sqlite3`.chomp
19
- ldflags = "#{brew_prefix}/lib"
20
- cppflags = "#{brew_prefix}/include"
21
- pkg_conf = "#{brew_prefix}/lib/pkgconfig"
22
- end
1
+ require "mkmf"
2
+ require "mini_portile2"
3
+
4
+ module Sqlite3
5
+ module ExtConf
6
+ ENV_ALLOWLIST = ["CC", "CFLAGS", "LDFLAGS", "LIBS", "CPPFLAGS", "LT_SYS_LIBRARY_PATH", "CPP"]
7
+
8
+ class << self
9
+ def configure
10
+ configure_cross_compiler
11
+
12
+ if system_libraries?
13
+ message "Building sqlite3-ruby using system #{libname}.\n"
14
+ configure_system_libraries
15
+ else
16
+ message "Building sqlite3-ruby using packaged sqlite3.\n"
17
+ configure_packaged_libraries
18
+ end
19
+
20
+ configure_extension
21
+
22
+ create_makefile('sqlite3/sqlite3_native')
23
+ end
24
+
25
+ def configure_cross_compiler
26
+ RbConfig::CONFIG["CC"] = RbConfig::MAKEFILE_CONFIG["CC"] = ENV["CC"] if ENV["CC"]
27
+ ENV["CC"] = RbConfig::CONFIG["CC"]
28
+ end
29
+
30
+ def system_libraries?
31
+ sqlcipher? || enable_config("system-libraries")
32
+ end
33
+
34
+ def libname
35
+ sqlcipher? ? "sqlcipher" : "sqlite3"
36
+ end
37
+
38
+ def sqlcipher?
39
+ with_config("sqlcipher") ||
40
+ with_config("sqlcipher-dir") ||
41
+ with_config("sqlcipher-include") ||
42
+ with_config("sqlcipher-lib")
43
+ end
44
+
45
+ def configure_system_libraries
46
+ pkg_config(libname)
47
+ append_cppflags("-DUSING_SQLCIPHER") if sqlcipher?
48
+ end
49
+
50
+ def configure_packaged_libraries
51
+ minimal_recipe.tap do |recipe|
52
+ recipe.configure_options += ["--enable-shared=no", "--enable-static=yes"]
53
+ ENV.to_h.tap do |env|
54
+ additional_cflags = [
55
+ "-fPIC", # needed for linking the static library into a shared library
56
+ "-O2", # see https://github.com/sparklemotion/sqlite3-ruby/issues/335 for some benchmarks
57
+ ]
58
+ env["CFLAGS"] = [env["CFLAGS"], additional_cflags].flatten.join(" ")
59
+ recipe.configure_options += env.select { |k,v| ENV_ALLOWLIST.include?(k) }
60
+ .map { |key, value| "#{key}=#{value.strip}" }
61
+ end
62
+
63
+ unless File.exist?(File.join(recipe.target, recipe.host, recipe.name, recipe.version))
64
+ recipe.cook
65
+ end
66
+ recipe.activate
67
+
68
+ ENV["PKG_CONFIG_ALLOW_SYSTEM_CFLAGS"] = "t" # on macos, pkg-config will not return --cflags without this
69
+ pcfile = File.join(recipe.path, "lib", "pkgconfig", "sqlite3.pc")
70
+ if pkg_config(pcfile)
71
+ # see https://bugs.ruby-lang.org/issues/18490
72
+ libs = xpopen(["pkg-config", "--libs", "--static", pcfile], err: [:child, :out], &:read)
73
+ libs.split.each { |lib| append_ldflags(lib) } if $?.success?
74
+ else
75
+ abort("\nCould not configure the build properly. Please install either the `pkg-config` utility or the `pkg-config` rubygem.\n\n")
76
+ end
77
+ end
78
+ end
79
+
80
+ def configure_extension
81
+ if Gem::Requirement.new("< 2.7").satisfied_by?(Gem::Version.new(RUBY_VERSION))
82
+ append_cppflags("-DTAINTING_SUPPORT")
83
+ end
84
+
85
+ if find_header("sqlite3.h")
86
+ # noop
87
+ elsif sqlcipher? && find_header("sqlcipher/sqlite3.h")
88
+ append_cppflags("-DUSING_SQLCIPHER_INC_SUBDIR")
89
+ else
90
+ abort_could_not_find("sqlite3.h")
91
+ end
92
+
93
+ abort_could_not_find(libname) unless find_library(libname, "sqlite3_libversion_number", "sqlite3.h")
94
+
95
+ # Functions defined in 1.9 but not 1.8
96
+ have_func('rb_proc_arity')
97
+
98
+ # Functions defined in 2.1 but not 2.0
99
+ have_func('rb_integer_pack')
100
+
101
+ # These functions may not be defined
102
+ have_func('sqlite3_initialize')
103
+ have_func('sqlite3_backup_init')
104
+ have_func('sqlite3_column_database_name')
105
+ have_func('sqlite3_enable_load_extension')
106
+ have_func('sqlite3_load_extension')
107
+
108
+ unless have_func('sqlite3_open_v2') # https://www.sqlite.org/releaselog/3_5_0.html
109
+ abort("\nPlease use a version of SQLite3 >= 3.5.0\n\n")
110
+ end
111
+
112
+ have_func('sqlite3_prepare_v2')
113
+ have_type('sqlite3_int64', 'sqlite3.h')
114
+ have_type('sqlite3_uint64', 'sqlite3.h')
115
+ end
116
+
117
+ def minimal_recipe
118
+ MiniPortile.new(libname, sqlite3_config[:version]).tap do |recipe|
119
+ recipe.files = sqlite3_config[:files]
120
+ recipe.target = File.join(package_root_dir, "ports")
121
+ recipe.patch_files = Dir[File.join(package_root_dir, "patches", "*.patch")].sort
122
+ end
123
+ end
124
+
125
+ def package_root_dir
126
+ File.expand_path(File.join(File.dirname(__FILE__), "..", ".."))
127
+ end
128
+
129
+ def sqlite3_config
130
+ mini_portile_config[:sqlite3]
131
+ end
132
+
133
+ def mini_portile_config
134
+ {
135
+ sqlite3: {
136
+ # checksum verified by first checking the published sha3(256) checksum against https://sqlite.org/download.html:
137
+ #
138
+ # $ sha3sum -a 256 ports/archives/sqlite-autoconf-3390400.tar.gz
139
+ # 431328e30d12c551da9ba7ef2122b269076058512014afa799caaf62ca567090 ports/archives/sqlite-autoconf-3390400.tar.gz
140
+ #
141
+ # $ sha256sum ports/archives/sqlite-autoconf-3390400.tar.gz
142
+ # f31d445b48e67e284cf206717cc170ab63cbe4fd7f79a82793b772285e78fdbb ports/archives/sqlite-autoconf-3390400.tar.gz
143
+ #
144
+ version: "3.39.4",
145
+ files: [{
146
+ url: "https://sqlite.org/2022/sqlite-autoconf-3390400.tar.gz",
147
+ sha256: "f31d445b48e67e284cf206717cc170ab63cbe4fd7f79a82793b772285e78fdbb",
148
+ }],
149
+ }
150
+ }
151
+ end
152
+
153
+ def abort_could_not_find(missing)
154
+ abort("\nCould not find #{missing}.\nPlease visit https://github.com/sparklemotion/sqlite3-ruby for installation instructions.\n\n")
155
+ end
156
+
157
+ def cross_build?
158
+ enable_config("cross-build")
159
+ end
160
+
161
+ def download
162
+ minimal_recipe.download
163
+ end
164
+
165
+ def print_help
166
+ print(<<~TEXT)
167
+ USAGE: ruby #{$PROGRAM_NAME} [options]
168
+
169
+ Flags that are always valid:
170
+
171
+ --disable-system-libraries
172
+ Use the packaged libraries, and ignore the system libraries.
173
+ (This is the default behavior.)
23
174
 
24
- # pkg_config should be less error prone than parsing compiler
25
- # commandline options, but we need to set default ldflags and cpp flags
26
- # in case the user doesn't have pkg-config installed
27
- ENV['PKG_CONFIG_PATH'] ||= pkg_conf
28
- rescue
29
- end
30
- end
175
+ --enable-system-libraries
176
+ Use system libraries instead of building and using the packaged libraries.
31
177
 
32
- if with_config('sqlcipher')
33
- pkg_config("sqlcipher")
34
- else
35
- pkg_config("sqlite3")
36
- end
178
+ --with-sqlcipher
179
+ Use libsqlcipher instead of libsqlite3.
180
+ (Implies `--enable-system-libraries`.)
37
181
 
38
- # --with-sqlite3-{dir,include,lib}
39
- if with_config('sqlcipher')
40
- $CFLAGS << ' -DUSING_SQLCIPHER'
41
- dir_config("sqlcipher", cppflags, ldflags)
42
- else
43
- dir_config("sqlite3", cppflags, ldflags)
44
- end
182
+ --help
183
+ Display this message.
45
184
 
46
- if RbConfig::CONFIG["host_os"] =~ /mswin/
47
- $CFLAGS << ' -W3'
48
- end
49
185
 
50
- if RUBY_VERSION < '2.7'
51
- $CFLAGS << ' -DTAINTING_SUPPORT'
52
- end
186
+ Flags only used when using system libraries:
53
187
 
54
- def asplode missing
55
- if RUBY_PLATFORM =~ /mingw|mswin/
56
- abort "#{missing} is missing. Install SQLite3 from " +
57
- "http://www.sqlite.org/ first."
58
- else
59
- abort <<-error
60
- #{missing} is missing. Try 'brew install sqlite3',
61
- 'yum install sqlite-devel' or 'apt-get install libsqlite3-dev'
62
- and check your shared library search path (the
63
- location where your sqlite3 shared library is located).
64
- error
65
- end
66
- end
188
+ General (applying to all system libraries):
67
189
 
68
- asplode('sqlite3.h') unless find_header 'sqlite3.h'
69
- find_library 'pthread', 'pthread_create' # 1.8 support. *shrug*
190
+ --with-opt-dir=DIRECTORY
191
+ Look for headers and libraries in DIRECTORY.
70
192
 
71
- have_library 'dl' # for static builds
193
+ --with-opt-lib=DIRECTORY
194
+ Look for libraries in DIRECTORY.
72
195
 
73
- if with_config('sqlcipher')
74
- asplode('sqlcipher') unless find_library 'sqlcipher', 'sqlite3_libversion_number'
75
- else
76
- asplode('sqlite3') unless find_library 'sqlite3', 'sqlite3_libversion_number'
77
- end
196
+ --with-opt-include=DIRECTORY
197
+ Look for headers in DIRECTORY.
198
+
199
+ Related to sqlcipher:
200
+
201
+ --with-sqlcipher-dir=DIRECTORY
202
+ Look for sqlcipher headers and library in DIRECTORY.
203
+ (Implies `--with-sqlcipher` and `--enable-system-libraries`.)
204
+
205
+ --with-sqlcipher-lib=DIRECTORY
206
+ Look for sqlcipher library in DIRECTORY.
207
+ (Implies `--with-sqlcipher` and `--enable-system-libraries`.)
78
208
 
79
- # Functions defined in 1.9 but not 1.8
80
- have_func('rb_proc_arity')
209
+ --with-sqlcipher-include=DIRECTORY
210
+ Look for sqlcipher headers in DIRECTORY.
211
+ (Implies `--with-sqlcipher` and `--enable-system-libraries`.)
81
212
 
82
- # Functions defined in 2.1 but not 2.0
83
- have_func('rb_integer_pack')
84
213
 
85
- # These functions may not be defined
86
- have_func('sqlite3_initialize')
87
- have_func('sqlite3_backup_init')
88
- have_func('sqlite3_column_database_name')
89
- have_func('sqlite3_enable_load_extension')
90
- have_func('sqlite3_load_extension')
214
+ Flags only used when building and using the packaged libraries:
91
215
 
92
- unless have_func('sqlite3_open_v2')
93
- abort "Please use a newer version of SQLite3"
216
+ --enable-cross-build
217
+ Enable cross-build mode. (You probably do not want to set this manually.)
218
+
219
+
220
+ Environment variables used for compiling the C extension:
221
+
222
+ CC
223
+ Use this path to invoke the compiler instead of `RbConfig::CONFIG['CC']`
224
+
225
+
226
+ Environment variables passed through to the compilation of packaged libraries:
227
+
228
+ CC
229
+ CPPFLAGS
230
+ CFLAGS
231
+ LDFLAGS
232
+ LIBS
233
+ LT_SYS_LIBRARY_PATH
234
+ CPP
235
+
236
+ TEXT
237
+ end
238
+ end
239
+ end
94
240
  end
95
241
 
96
- have_func('sqlite3_prepare_v2')
97
- have_type('sqlite3_int64', 'sqlite3.h')
98
- have_type('sqlite3_uint64', 'sqlite3.h')
242
+ if arg_config("--help")
243
+ Sqlite3::ExtConf.print_help
244
+ exit!(0)
245
+ end
246
+
247
+ if arg_config("--download-dependencies")
248
+ Sqlite3::ExtConf.download
249
+ exit!(0)
250
+ end
99
251
 
100
- create_makefile('sqlite3/sqlite3_native')
252
+ Sqlite3::ExtConf.configure
@@ -158,4 +158,6 @@ void Init_sqlite3_native()
158
158
  rb_define_singleton_method(mSqlite3, "threadsafe", threadsafe_p, 0);
159
159
  rb_define_const(mSqlite3, "SQLITE_VERSION", rb_str_new2(SQLITE_VERSION));
160
160
  rb_define_const(mSqlite3, "SQLITE_VERSION_NUMBER", INT2FIX(SQLITE_VERSION_NUMBER));
161
+ rb_define_const(mSqlite3, "SQLITE_LOADED_VERSION", rb_str_new2(sqlite3_libversion()));
162
+
161
163
  }
@@ -21,8 +21,11 @@
21
21
  #define SQLITE3_UTF8_STR_NEW2(_obj) \
22
22
  (rb_enc_associate_index(rb_str_new2(_obj), rb_utf8_encindex()))
23
23
 
24
-
25
- #include <sqlite3.h>
24
+ #ifdef USING_SQLCIPHER_INC_SUBDIR
25
+ # include <sqlcipher/sqlite3.h>
26
+ #else
27
+ # include <sqlite3.h>
28
+ #endif
26
29
 
27
30
  #ifndef HAVE_TYPE_SQLITE3_INT64
28
31
  typedef sqlite_int64 sqlite3_int64;
@@ -290,7 +290,7 @@ static VALUE bind_param(VALUE self, VALUE key, VALUE value)
290
290
  /* call-seq: stmt.reset!
291
291
  *
292
292
  * Resets the statement. This is typically done internally, though it might
293
- * occassionally be necessary to manually reset the statement.
293
+ * occasionally be necessary to manually reset the statement.
294
294
  */
295
295
  static VALUE reset_bang(VALUE self)
296
296
  {
@@ -309,7 +309,7 @@ static VALUE reset_bang(VALUE self)
309
309
  /* call-seq: stmt.clear_bindings!
310
310
  *
311
311
  * Resets the statement. This is typically done internally, though it might
312
- * occassionally be necessary to manually reset the statement.
312
+ * occasionally be necessary to manually reset the statement.
313
313
  */
314
314
  static VALUE clear_bindings_bang(VALUE self)
315
315
  {