/
extension.rake
217 lines (198 loc) · 6.07 KB
/
extension.rake
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
#-----------------------------------------------------------------------
# Extensions
#-----------------------------------------------------------------------
require 'pathname'
namespace :ext do
def current_sqlite_version
ext = Util.platform_gemspec.extensions.first
path = Pathname.new( ext )
h_path = path.dirname.realpath + "sqlite3.h"
File.open( h_path ) do |f|
f.each_line do |line|
if line =~ /\A#define SQLITE_VERSION\s+/ then
define ,constant ,value = line.split
return value
end
end
end
end
desc "Build the SQLite extension version #{current_sqlite_version}"
task :build => :clean do
with_each_extension do |extension|
path = Pathname.new(extension)
parts = path.split
conf = parts.last
Dir.chdir(path.dirname) do |d|
ruby conf.to_s
sh "make"
# install into requireable location so specs will run
mkdir_p ext_dest_dir, :verbose => true
cp "amalgalite3.#{Config::CONFIG['DLEXT']}", ext_dest_dir, :verbose => true
end
end
end
def ext_dest_dir
version_sub = RUBY_VERSION.sub(/\.\d$/,'')
dest_dir = Util.proj_path( 'lib', 'amalgalite', version_sub)
end
def with_each_extension
Util.platform_gemspec.extensions.each do |ext|
yield ext
end
end
def myruby
require 'rbconfig'
x = File.join(
RbConfig::CONFIG['bindir'],
RbConfig::CONFIG['ruby_install_name']
)
#puts "myruby = #{x}"
return x
end
# FIXME: building on windows is broken
def build_win( version = "1.8.7" )
ext_config = Util.platform_gemspec.extensions.first
rbconfig = ext_config.cross_rbconfig["rbconfig-#{version}"]
raise ArgumentError, "No cross compiler for version #{version}, we have #{ext_config.cross_rbconfig.keys.join(",")}" unless rbconfig
with_each_extension do |extension|
path = Pathname.new(extension)
parts = path.split
conf = parts.last
rvm = File.expand_path( "~/.rvm/bin/rvm" )
Dir.chdir(path.dirname) do |d|
if File.exist?( "Makefile" ) then
sh "make clean distclean"
end
cp "#{rbconfig}", "rbconfig.rb"
rubylib = ENV['RUBYLIB']
ENV['RUBYLIB'] = "."
sh %[ #{rvm} #{version} -S extconf.rb #{myruby} ]
ENV['RUBYLIB'] = rubylib
sh "make"
end
end
end
win_builds = []
# ext_config.cross_rbconfig.keys.each do |v|
# s = v.split("-").last
# desc "Build the extension for windows version #{s}"
# win_bname = "build_win-#{s}"
# win_builds << win_bname
# task win_bname => :clean do
# build_win( s )
# end
# end
task :clean do
with_each_extension do |extension|
path = Pathname.new(extension)
parts = path.split
conf = parts.last
Dir.chdir(path.dirname) do |d|
if File.exist?( "Makefile" ) then
sh "make clean"
end
rm_f "rbconfig.rb"
end
end
end
desc "List the sqlite api calls that are not implemented"
task :todo do
not_implementing = %w[
sqlite3_exec
sqlite3_open
sqlite3_os_end
sqlite3_os_init
sqlite3_malloc
sqlite3_realloc
sqlite3_free
sqlite3_get_table
sqlite3_free_table
sqlite3_key
sqlite3_rekey
sqlite3_next_stmt
sqlite3_release_memory
sqlite3_sleep
sqlite3_snprintf
sqlite3_vmprintf
sqlite3_strnicmp
sqlite3_test_control
sqlite3_unlock_notify
sqlite3_vfs_find
sqlite3_vfs_register
sqlite3_vfs_unregister
]
sqlite_h = File.join( *%w[ ext amalgalite sqlite3.h ] )
api_todo = {}
IO.readlines( sqlite_h ).each do |line|
if line =~ /\ASQLITE_API/ then
if line !~ /SQLITE_DEPRECATED/ and line !~ /SQLITE_EXPERIMENTAL/ then
if md = line.match( /(sqlite3_[^(\s]+)\(/ ) then
next if not_implementing.include?(md.captures[0])
api_todo[md.captures[0]] = true
end
end
end
end
Dir.glob("ext/amalgalite/amalgalite*.c").each do |am_file|
IO.readlines( am_file ).each do |am_line|
if md = am_line.match( /(sqlite3_[^(\s]+)\(/ ) then
api_todo.delete( md.captures[0] )
end
end
end
puts "#{api_todo.keys.size} functions to still implement"
puts api_todo.keys.sort.join("\n")
end
task :clobber do
with_each_extension do |extension|
path = Pathname.new(extension)
parts = path.split
conf = parts.last
Dir.chdir(path.dirname) do |d|
if File.exist?( "Makefile") then
sh "make distclean"
end
rm_f "rbconfig.rb"
end
end
FileUtils.rm_rf ext_dest_dir, :verbose => true
end
desc "Download and integrate the next version of sqlite (use VERSION=x.y.z)"
task :update_sqlite do
require 'uri'
require 'net/http'
parts = ENV['VERSION'].split(".")
next_version = [ parts.shift.to_s ]
parts.each do |p|
next_version << "#{"%02d" % p }"
end
next_version << "00" if next_version.size == 3
next_version = next_version.join('')
raise "VERSION env variable must be set" unless next_version
url = ::URI.parse("http://sqlite.org/sqlite-amalgamation-#{next_version}.zip")
puts "downloading #{url.to_s} ..."
file = "tmp/#{File.basename( url.path ) }"
FileUtils.mkdir "tmp" unless File.directory?( "tmp" )
File.open( file, "wb+") do |f|
res = Net::HTTP.get_response( url )
f.write( res.body )
end
puts "extracting..."
upstream_files = %w[ sqlite3.h sqlite3.c sqlite3ext.h ]
Zip::ZipInputStream.open( file ) do |io|
loop do
entry = io.get_next_entry
break unless entry
bname = File.basename( entry.name )
if upstream_files.include?( bname ) then
dest_file = File.join( "ext", "amalgalite", bname )
puts "updating #{dest_file}"
entry.extract( dest_file ) { true }
end
end
end
end
end
task :clobber => 'ext:clobber'
task :clean => 'ext:clean'
task :test => 'ext:build'