Skip to content

Commit 9aeeb9b

Browse files
committed
refactor: extconf.rb
This adds the ability to download a sqlite3 tarball with `--download-dependencies`
1 parent e53a2f1 commit 9aeeb9b

1 file changed

Lines changed: 147 additions & 84 deletions

File tree

ext/sqlite3/extconf.rb

Lines changed: 147 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -1,95 +1,158 @@
11
require "mkmf"
22
require "mini_portile2"
33

4-
package_root_dir = File.expand_path(File.join(File.dirname(__FILE__), "..", ".."))
5-
6-
RbConfig::CONFIG["CC"] = RbConfig::MAKEFILE_CONFIG["CC"] = ENV["CC"] if ENV["CC"]
7-
ENV["CC"] = RbConfig::CONFIG["CC"]
8-
9-
cross_build_p = enable_config("cross-build")
10-
sqlcipher_p = with_config("sqlcipher")
11-
system_libraries_p = sqlcipher_p || enable_config("system-libraries")
12-
libname = sqlcipher_p ? "sqlcipher" : "sqlite3"
13-
14-
def abort_could_not_find(missing)
15-
abort("Could not find #{missing}. Please visit https://github.com/sparklemotion/sqlite3-ruby for installation instructions.")
16-
end
17-
18-
if system_libraries_p
19-
message "Building sqlite3-ruby using system #{libname}.\n"
20-
pkg_config(libname)
21-
append_cflags("-DUSING_SQLCIPHER") if sqlcipher_p
22-
23-
else
24-
message "Building sqlite3-ruby using packaged sqlite3.\n"
25-
MiniPortile.new("sqlite3", "3.38.5").tap do |recipe|
26-
# checksum verified by first checking the published sha3(256) checksum:
27-
#
28-
# $ sha3sum -a 256 sqlite-autoconf-3380500.tar.gz
29-
# ab649fea76f49a6ec7f907f001d87b8bd76dec0679c783e3992284c5a882a98c sqlite-autoconf-3380500.tar.gz
30-
# $ sha256sum sqlite-autoconf-3380500.tar.gz
31-
# 5af07de982ba658fd91a03170c945f99c971f6955bc79df3266544373e39869c sqlite-autoconf-3380500.tar.gz
32-
#
33-
recipe.files = [{
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+
end
41+
42+
def configure_system_libraries
43+
pkg_config(libname)
44+
append_cflags("-DUSING_SQLCIPHER") if sqlcipher?
45+
end
46+
47+
def configure_packaged_libraries
48+
minimal_recipe.tap do |recipe|
49+
recipe.configure_options += ["--enable-shared=no", "--enable-static=yes"]
50+
ENV.to_h.tap do |env|
51+
env["CFLAGS"] = [env["CFLAGS"], "-fPIC"].join(" ") # needed for linking the static library into a shared library
52+
recipe.configure_options += env.select { |k,v| ENV_ALLOWLIST.include?(k) }
53+
.map { |key, value| "#{key}=#{value.strip}" }
54+
end
55+
56+
unless File.exist?(File.join(recipe.target, recipe.host, recipe.name, recipe.version))
57+
recipe.cook
58+
end
59+
recipe.activate
60+
61+
ENV["PKG_CONFIG_ALLOW_SYSTEM_CFLAGS"] = "t" # on macos, pkg-config will not return --cflags without this
62+
pcfile = File.join(recipe.path, "lib", "pkgconfig", "sqlite3.pc")
63+
if pkg_config(pcfile)
64+
# see https://bugs.ruby-lang.org/issues/18490
65+
libs = xpopen(["pkg-config", "--libs", "--static", pcfile], err: [:child, :out], &:read)
66+
libs.split.each { |lib| append_ldflags(lib) } if $?.success?
67+
else
68+
abort("\nCould not configure the build properly. Please install either the `pkg-config` utility or the `pkg-config` rubygem.\n\n")
69+
end
70+
end
71+
end
72+
73+
def configure_extension
74+
if Gem::Requirement.new("< 2.7").satisfied_by?(Gem::Version.new(RUBY_VERSION))
75+
append_cflags("-DTAINTING_SUPPORT")
76+
end
77+
78+
abort_could_not_find("sqlite3.h") unless find_header("sqlite3.h")
79+
abort_could_not_find(libname) unless find_library(libname, "sqlite3_libversion_number", "sqlite3.h")
80+
81+
# Functions defined in 1.9 but not 1.8
82+
have_func('rb_proc_arity')
83+
84+
# Functions defined in 2.1 but not 2.0
85+
have_func('rb_integer_pack')
86+
87+
# These functions may not be defined
88+
have_func('sqlite3_initialize')
89+
have_func('sqlite3_backup_init')
90+
have_func('sqlite3_column_database_name')
91+
have_func('sqlite3_enable_load_extension')
92+
have_func('sqlite3_load_extension')
93+
94+
unless have_func('sqlite3_open_v2') # https://www.sqlite.org/releaselog/3_5_0.html
95+
abort("\nPlease use a version of SQLite3 >= 3.5.0\n\n")
96+
end
97+
98+
have_func('sqlite3_prepare_v2')
99+
have_type('sqlite3_int64', 'sqlite3.h')
100+
have_type('sqlite3_uint64', 'sqlite3.h')
101+
end
102+
103+
def minimal_recipe
104+
MiniPortile.new(libname, sqlite3_config[:version]).tap do |recipe|
105+
recipe.files = sqlite3_config[:files]
106+
recipe.target = File.join(package_root_dir, "ports")
107+
recipe.patch_files = Dir[File.join(package_root_dir, "patches", "*.patch")].sort
108+
end
109+
end
110+
111+
def package_root_dir
112+
File.expand_path(File.join(File.dirname(__FILE__), "..", ".."))
113+
end
114+
115+
def sqlite3_config
116+
mini_portile_config[:sqlite3]
117+
end
118+
119+
def mini_portile_config
120+
{
121+
sqlite3: {
122+
# checksum verified by first checking the published sha3(256) checksum:
123+
#
124+
# $ sha3sum -a 256 sqlite-autoconf-3380500.tar.gz
125+
# ab649fea76f49a6ec7f907f001d87b8bd76dec0679c783e3992284c5a882a98c sqlite-autoconf-3380500.tar.gz
126+
# $ sha256sum sqlite-autoconf-3380500.tar.gz
127+
# 5af07de982ba658fd91a03170c945f99c971f6955bc79df3266544373e39869c sqlite-autoconf-3380500.tar.gz
128+
#
129+
version: "3.38.5",
130+
files: [{
34131
url: "https://www.sqlite.org/2022/sqlite-autoconf-3380500.tar.gz",
35132
sha256: "5af07de982ba658fd91a03170c945f99c971f6955bc79df3266544373e39869c",
36-
}]
37-
recipe.target = File.join(package_root_dir, "ports")
38-
recipe.patch_files = Dir[File.join(package_root_dir, "patches", "*.patch")].sort
39-
40-
recipe.configure_options += ["--enable-shared=no", "--enable-static=yes"]
41-
ENV.to_h.tap do |env|
42-
env["CFLAGS"] = [env["CFLAGS"], "-fPIC"].join(" ") # needed for linking the static library into a shared library
43-
recipe.configure_options += env
44-
.select { |k,v| ["CC", "CFLAGS", "LDFLAGS", "LIBS", "CPPFLAGS", "LT_SYS_LIBRARY_PATH", "CPP"].include?(k) }
45-
.map { |key, value| "#{key}=#{value.strip}" }
46-
end
47-
48-
unless File.exist?(File.join(recipe.target, recipe.host, recipe.name, recipe.version))
49-
recipe.cook
50-
end
51-
recipe.activate
52-
53-
ENV["PKG_CONFIG_ALLOW_SYSTEM_CFLAGS"] = "t" # on macos, pkg-config will not return --cflags without this
54-
pcfile = File.join(recipe.path, "lib", "pkgconfig", "sqlite3.pc")
55-
if pkg_config(pcfile)
56-
# see https://bugs.ruby-lang.org/issues/18490
57-
libs = xpopen(["pkg-config", "--libs", "--static", pcfile], err: [:child, :out], &:read)
58-
libs.split.each { |lib| append_ldflags(lib) } if $?.success?
59-
else
60-
message("Please install either the `pkg-config` utility or the `pkg-config` rubygem.\n")
133+
}],
134+
}
135+
}
136+
end
137+
138+
def abort_could_not_find(missing)
139+
abort("\nCould not find #{missing}.\nPlease visit https://github.com/sparklemotion/sqlite3-ruby for installation instructions.\n\n")
140+
end
141+
142+
def cross_build?
143+
enable_config("cross-build")
144+
end
145+
146+
def download
147+
minimal_recipe.download
148+
end
61149
end
62150
end
63151
end
64152

65-
# if RbConfig::CONFIG["host_os"] =~ /mswin/
66-
# $CFLAGS << ' -W3'
67-
# end
68-
69-
append_cflags("-DTAINTING_SUPPORT") if Gem::Requirement.new("< 2.7").satisfied_by?(Gem::Version.new(RUBY_VERSION))
70-
71-
abort_could_not_find("sqlite3.h") unless find_header("sqlite3.h")
72-
abort_could_not_find(libname) unless find_library(libname, "sqlite3_libversion_number", "sqlite3.h")
73-
74-
# Functions defined in 1.9 but not 1.8
75-
have_func('rb_proc_arity')
76-
77-
# Functions defined in 2.1 but not 2.0
78-
have_func('rb_integer_pack')
79-
80-
# These functions may not be defined
81-
have_func('sqlite3_initialize')
82-
have_func('sqlite3_backup_init')
83-
have_func('sqlite3_column_database_name')
84-
have_func('sqlite3_enable_load_extension')
85-
have_func('sqlite3_load_extension')
86-
87-
unless have_func('sqlite3_open_v2') # https://www.sqlite.org/releaselog/3_5_0.html
88-
abort "Please use a newer version of SQLite3"
153+
if arg_config("--download-dependencies")
154+
Sqlite3::ExtConf.download
155+
exit!(0)
89156
end
90157

91-
have_func('sqlite3_prepare_v2')
92-
have_type('sqlite3_int64', 'sqlite3.h')
93-
have_type('sqlite3_uint64', 'sqlite3.h')
94-
95-
create_makefile('sqlite3/sqlite3_native')
158+
Sqlite3::ExtConf.configure

0 commit comments

Comments
 (0)