|
1 | 1 | require "mkmf" |
2 | 2 | require "mini_portile2" |
3 | 3 |
|
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: [{ |
34 | 131 | url: "https://www.sqlite.org/2022/sqlite-autoconf-3380500.tar.gz", |
35 | 132 | 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 |
61 | 149 | end |
62 | 150 | end |
63 | 151 | end |
64 | 152 |
|
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) |
89 | 156 | end |
90 | 157 |
|
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