Skip to content

Commit

Permalink
Backport gem cross-compilation changes
Browse files Browse the repository at this point in the history
  • Loading branch information
luislavena committed Aug 17, 2013
1 parent 42e5cd8 commit 5a1b6d8
Show file tree
Hide file tree
Showing 5 changed files with 100 additions and 36 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,4 @@ ports
.config
InstalledFiles
Makefile
Gemfile.lock
15 changes: 15 additions & 0 deletions Gemfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# -*- ruby -*-

# DO NOT EDIT THIS FILE. Instead, edit Rakefile, and run `rake bundler:gemfile`.

source "https://rubygems.org/"


gem "minitest", "~>5.0", :group => [:development, :test]
gem "rdoc", "~>4.0", :group => [:development, :test]
gem "rake-compiler", "~>0.9.1", :group => [:development, :test]
gem "mini_portile", "~>0.5.1", :group => [:development, :test]
gem "hoe-bundler", "~>1.0", :group => [:development, :test]
gem "hoe", "~>3.7", :group => [:development, :test]

# vim: syntax=ruby
18 changes: 11 additions & 7 deletions tasks/gem.rake
Original file line number Diff line number Diff line change
Expand Up @@ -6,24 +6,28 @@ rescue LoadError
require 'hoe'
end

Hoe.plugin :debugging, :doofus, :git
Hoe.plugin :debugging, :doofus, :git, :minitest, :bundler

HOE = Hoe.spec 'sqlite3' do
developer 'Jamis Buck', 'jamis@37signals.com'
developer 'Luis Lavena', 'luislavena@gmail.com'
developer 'Aaron Patterson', 'aaron@tenderlovemaking.com'

license "MIT"

self.readme_file = 'README.rdoc'
self.history_file = 'CHANGELOG.rdoc'
self.extra_rdoc_files = FileList['*.rdoc', 'ext/**/*.c']

spec_extras[:required_ruby_version] = Gem::Requirement.new('>= 1.8.7')
spec_extras[:required_rubygems_version] = '>= 1.3.5'
spec_extras[:extensions] = ["ext/sqlite3/extconf.rb"]
spec_extras[:license] = "MIT"
require_ruby_version ">= 1.8.7"
require_rubygems_version ">= 1.3.5"

spec_extras[:extensions] = ["ext/sqlite3/extconf.rb"]

extra_dev_deps << ['rake-compiler', "~> 0.8.2"]
extra_dev_deps << ["mini_portile", "~> 0.2.2"]
extra_dev_deps << ['rake-compiler', "~> 0.9.1"]
extra_dev_deps << ["mini_portile", "~> 0.5.1"]
extra_dev_deps << ["minitest", "~> 5.0"]
extra_dev_deps << ["hoe-bundler", "~> 1.0"]

clean_globs.push('**/test.db')
end
Expand Down
20 changes: 14 additions & 6 deletions tasks/native.rake
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
# use rake-compiler for building the extension
require 'rake/extensiontask'
require 'rake/extensioncompiler'

# NOTE: version used by cross compilation of Windows native extension
# It do not affect compilation under other operating systems
# The version indicated is the minimum DLL suggested for correct functionality
BINARY_VERSION = "3.7.11"
URL_VERSION = "3071100"
BINARY_VERSION = "3.7.17"
URL_VERSION = "3071700"
URL_PATH = "/2013"

# build sqlite3_native C extension
Rake::ExtensionTask.new('sqlite3_native', HOE.spec) do |ext|
RUBY_EXTENSION = Rake::ExtensionTask.new('sqlite3_native', HOE.spec) do |ext|
# where to locate the extension
ext.ext_dir = 'ext/sqlite3'

Expand All @@ -25,9 +27,15 @@ Rake::ExtensionTask.new('sqlite3_native', HOE.spec) do |ext|
ext.lib_dir = "lib/sqlite3/#{$1}"
ext.config_options << "--enable-local"
else
ext.cross_compile = true
ext.cross_platform = ['i386-mswin32-60', 'i386-mingw32']
ext.cross_config_options << "--enable-local"

# detect cross-compiler available
begin
Rake::ExtensionCompiler.mingw_host
ext.cross_compile = true
ext.cross_platform = ['i386-mswin32-60', 'i386-mingw32', 'x64-mingw32']
rescue RuntimeError
# noop
end
end
end

Expand Down
82 changes: 59 additions & 23 deletions tasks/vendor_sqlite3.rake
Original file line number Diff line number Diff line change
Expand Up @@ -2,50 +2,86 @@ require "rake/clean"
require "rake/extensioncompiler"
require "mini_portile"

$recipes = {}
CLOBBER.include("ports")

$recipes[:sqlite3] = MiniPortile.new "sqlite3", BINARY_VERSION
$recipes[:sqlite3].files << "http://sqlite.org/sqlite-autoconf-#{URL_VERSION}.tar.gz"
directory "ports"

namespace :ports do
directory "ports"
def define_sqlite_task(platform, host)
recipe = MiniPortile.new "sqlite3", BINARY_VERSION
recipe.files << "http://sqlite.org#{URL_PATH}/sqlite-autoconf-#{URL_VERSION}.tar.gz"
recipe.host = host

desc "Install port sqlite3 #{$recipes[:sqlite3].version}"
task :sqlite3 => ["ports"] do |t|
recipe = $recipes[:sqlite3]
desc "Compile sqlite3 for #{platform} (#{host})"
task "ports:sqlite3:#{platform}" => ["ports"] do |t|
checkpoint = "ports/.#{recipe.name}-#{recipe.version}-#{recipe.host}.installed"

unless File.exist?(checkpoint)
cflags = "-O2 -DSQLITE_ENABLE_COLUMN_METADATA"
cflags << " -fPIC" if recipe.host && recipe.host.include?("x86_64")
cflags << " -fPIC" if recipe.host.include?("x86_64")
recipe.configure_options << "CFLAGS='#{cflags}'"
recipe.cook
touch checkpoint
end

recipe.activate
end

recipe
end

# native sqlite3 compilation
define_sqlite_task RUBY_PLATFORM, RbConfig::CONFIG["host"]

# trick to test local compilation of sqlite3
if ENV["USE_MINI_PORTILE"] == "true"
# fake recipe so we can build a directory to it
recipe = MiniPortile.new "sqlite3", BINARY_VERSION
recipe.host = RbConfig::CONFIG["host"]

RUBY_EXTENSION.config_options << "--with-opt-dir=#{recipe.path}"

# compile sqlite3 first
Rake::Task["compile"].prerequisites.unshift "ports:sqlite3:#{RUBY_PLATFORM}"
end

# force compilation of sqlite3 when working natively under MinGW
if RUBY_PLATFORM =~ /mingw/
Rake::Task['compile'].prerequisites.unshift "ports:sqlite3"
Rake::Task['compile'].prerequisites.unshift "ports:sqlite3:#{RUBY_PLATFORM}"
end

if ENV["USE_MINI_PORTILE"] == "true"
Rake::Task["compile"].prerequisites.unshift "ports:sqlite3"
# iterate over all cross-compilation platforms and define the proper
# sqlite3 recipe for it.
if RUBY_EXTENSION.cross_compile
config_path = File.expand_path("~/.rake-compiler/config.yml")
if File.exist?(config_path)
# obtains platforms from rake-compiler's config.yml
config_file = YAML.load_file(config_path)

Array(RUBY_EXTENSION.cross_platform).each do |platform|
# obtain platform from rbconfig file
config_key = config_file.keys.sort.find { |key|
key.start_with?("rbconfig-#{platform}-")
}
rbfile = config_file[config_key]

# skip if rbconfig cannot be read
next unless File.exist?(rbfile)

host = IO.read(rbfile).match(/CONFIG\["CC"\] = "(.*)"/)[1].sub(/\-gcc/, '')
recipe = define_sqlite_task(platform, host)

RUBY_EXTENSION.cross_config_options << {
platform => "--with-opt-dir=#{recipe.path}"
}

# pre-compile sqlite3 port when cross-compiling
task :cross => "ports:sqlite3:#{platform}"
end
else
warn "rake-compiler configuration doesn't exist, but is required for ports"
end
end

task :cross do
["CC", "CXX", "LDFLAGS", "CPPFLAGS", "RUBYOPT"].each do |var|
ENV.delete(var)
end
host = ENV.fetch("HOST", Rake::ExtensionCompiler.mingw_host)
$recipes.each do |_, recipe|
recipe.host = host
end

# hook compile task with dependencies
Rake::Task["compile"].prerequisites.unshift "ports:sqlite3"
end

CLOBBER.include("ports")

0 comments on commit 5a1b6d8

Please sign in to comment.