module Sqlite3::ExtConf

Constants

ENV_ALLOWLIST

Public Class Methods

abort_could_not_find(missing) click to toggle source
# File ext/sqlite3/extconf.rb, line 159
def abort_could_not_find(missing)
  abort("\nCould not find #{missing}.\nPlease visit https://github.com/sparklemotion/sqlite3-ruby for installation instructions.\n\n")
end
abort_pkg_config(id) click to toggle source
# File ext/sqlite3/extconf.rb, line 163
def abort_pkg_config(id)
  abort("\nCould not configure the build properly (#{id}). Please install either the `pkg-config` utility or the `pkg-config` rubygem.\n\n")
end
configure() click to toggle source
# File ext/sqlite3/extconf.rb, line 9
def configure
  configure_cross_compiler

  if system_libraries?
    message "Building sqlite3-ruby using system #{libname}.\n"
    configure_system_libraries
  else
    message "Building sqlite3-ruby using packaged sqlite3.\n"
    configure_packaged_libraries
  end

  configure_extension

  create_makefile('sqlite3/sqlite3_native')
end
configure_cross_compiler() click to toggle source
# File ext/sqlite3/extconf.rb, line 25
def configure_cross_compiler
  RbConfig::CONFIG["CC"] = RbConfig::MAKEFILE_CONFIG["CC"] = ENV["CC"] if ENV["CC"]
  ENV["CC"] = RbConfig::CONFIG["CC"]
end
configure_extension() click to toggle source
# File ext/sqlite3/extconf.rb, line 93
def configure_extension
  if Gem::Requirement.new("< 2.7").satisfied_by?(Gem::Version.new(RUBY_VERSION))
    append_cppflags("-DTAINTING_SUPPORT")
  end

  append_cflags("-fvisibility=hidden") # see https://github.com/rake-compiler/rake-compiler-dock/issues/87

  if find_header("sqlite3.h")
    # noop
  elsif sqlcipher? && find_header("sqlcipher/sqlite3.h")
    append_cppflags("-DUSING_SQLCIPHER_INC_SUBDIR")
  else
    abort_could_not_find("sqlite3.h")
  end

  abort_could_not_find(libname) unless find_library(libname, "sqlite3_libversion_number", "sqlite3.h")

  # Functions defined in 1.9 but not 1.8
  have_func('rb_proc_arity')

  # Functions defined in 2.1 but not 2.0
  have_func('rb_integer_pack')

  # These functions may not be defined
  have_func('sqlite3_initialize')
  have_func('sqlite3_backup_init')
  have_func('sqlite3_column_database_name')
  have_func('sqlite3_enable_load_extension')
  have_func('sqlite3_load_extension')

  unless have_func('sqlite3_open_v2') # https://www.sqlite.org/releaselog/3_5_0.html
    abort("\nPlease use a version of SQLite3 >= 3.5.0\n\n")
  end

  have_func('sqlite3_prepare_v2')
  have_type('sqlite3_int64', 'sqlite3.h')
  have_type('sqlite3_uint64', 'sqlite3.h')
end
configure_packaged_libraries() click to toggle source
# File ext/sqlite3/extconf.rb, line 50
def configure_packaged_libraries
  minimal_recipe.tap do |recipe|
    recipe.configure_options += ["--enable-shared=no", "--enable-static=yes"]
    ENV.to_h.tap do |env|
      additional_cflags = [
        "-fPIC", # needed for linking the static library into a shared library
        "-O2", # see https://github.com/sparklemotion/sqlite3-ruby/issues/335 for some benchmarks
        "-fvisibility=hidden", # see https://github.com/rake-compiler/rake-compiler-dock/issues/87
      ]
      env["CFLAGS"] = [env["CFLAGS"], additional_cflags].flatten.join(" ")
      recipe.configure_options += env.select { |k,v| ENV_ALLOWLIST.include?(k) }
                                     .map { |key, value| "#{key}=#{value.strip}" }
    end

    unless File.exist?(File.join(recipe.target, recipe.host, recipe.name, recipe.version))
      recipe.cook
    end
    recipe.activate

    # on macos, pkg-config will not return --cflags without this
    ENV["PKG_CONFIG_ALLOW_SYSTEM_CFLAGS"] = "t"

    # only needed for Ruby 3.1.3, see https://bugs.ruby-lang.org/issues/19233
    RbConfig::CONFIG["PKG_CONFIG"] = config_string("PKG_CONFIG") || "pkg-config"

    lib_path = File.join(recipe.path, "lib")
    pcfile = File.join(lib_path, "pkgconfig", "sqlite3.pc")
    abort_pkg_config("pkg_config") unless pkg_config(pcfile)

    # see https://bugs.ruby-lang.org/issues/18490
    ldflags = xpopen(["pkg-config", "--libs", "--static", pcfile], err: [:child, :out], &:read)
    abort_pkg_config("xpopen") unless $?.success?
    ldflags = ldflags.split

    # see https://github.com/flavorjones/mini_portile/issues/118
    "-L#{lib_path}".tap do |lib_path_flag|
      ldflags.prepend(lib_path_flag) unless ldflags.include?(lib_path_flag)
    end

    ldflags.each { |ldflag| append_ldflags(ldflag) }
  end
end
configure_system_libraries() click to toggle source
# File ext/sqlite3/extconf.rb, line 45
def configure_system_libraries
  pkg_config(libname)
  append_cppflags("-DUSING_SQLCIPHER") if sqlcipher?
end
cross_build?() click to toggle source
# File ext/sqlite3/extconf.rb, line 167
def cross_build?
  enable_config("cross-build")
end
darwin?() click to toggle source
# File ext/sqlite3/extconf.rb, line 179
def darwin?
  RbConfig::CONFIG["target_os"].include?("darwin")
end
download() click to toggle source
# File ext/sqlite3/extconf.rb, line 175
def download
  minimal_recipe.download
end
libname() click to toggle source
# File ext/sqlite3/extconf.rb, line 34
def libname
  sqlcipher? ? "sqlcipher" : "sqlite3"
end
mini_portile_config() click to toggle source
# File ext/sqlite3/extconf.rb, line 154
def mini_portile_config
  # TODO: once Ruby 2.7 is no longer supported, use symbolize_names: true
  YAML.load_file(File.join(package_root_dir, "dependencies.yml"))
end
minimal_recipe() click to toggle source
# File ext/sqlite3/extconf.rb, line 132
def minimal_recipe
  require "mini_portile2"

  MiniPortile.new(libname, sqlite3_config[:version]).tap do |recipe|
    if sqlite_source_dir
      recipe.source_directory = sqlite_source_dir
    else
      recipe.files = sqlite3_config[:files]
      recipe.target = File.join(package_root_dir, "ports")
      recipe.patch_files = Dir[File.join(package_root_dir, "patches", "*.patch")].sort
    end
  end
end
package_root_dir() click to toggle source
# File ext/sqlite3/extconf.rb, line 146
def package_root_dir
  File.expand_path(File.join(File.dirname(__FILE__), "..", ".."))
end
print_help() click to toggle source
sqlcipher?() click to toggle source
# File ext/sqlite3/extconf.rb, line 38
def sqlcipher?
  with_config("sqlcipher") ||
    with_config("sqlcipher-dir") ||
    with_config("sqlcipher-include") ||
    with_config("sqlcipher-lib")
end
sqlite3_config() click to toggle source
# File ext/sqlite3/extconf.rb, line 150
def sqlite3_config
  mini_portile_config[:sqlite3]
end
sqlite_source_dir() click to toggle source
# File ext/sqlite3/extconf.rb, line 171
def sqlite_source_dir
  arg_config("--with-sqlite-source-dir")
end
system_libraries?() click to toggle source
# File ext/sqlite3/extconf.rb, line 30
def system_libraries?
  sqlcipher? || enable_config("system-libraries")
end