blackwinter-rake-compiler 0.9.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/Gemfile +8 -0
- data/History.txt +308 -0
- data/LICENSE.txt +20 -0
- data/README.rdoc +415 -0
- data/Rakefile +15 -0
- data/bin/rake-compiler +24 -0
- data/cucumber.yml +4 -0
- data/features/compile.feature +79 -0
- data/features/cross-compile.feature +23 -0
- data/features/cross-package-multi.feature +15 -0
- data/features/cross-package.feature +14 -0
- data/features/java-compile.feature +22 -0
- data/features/java-no-native-compile.feature +33 -0
- data/features/java-package.feature +24 -0
- data/features/package.feature +40 -0
- data/features/step_definitions/compilation.rb +70 -0
- data/features/step_definitions/cross_compilation.rb +27 -0
- data/features/step_definitions/execution.rb +52 -0
- data/features/step_definitions/folders.rb +32 -0
- data/features/step_definitions/gem.rb +46 -0
- data/features/step_definitions/java_compilation.rb +7 -0
- data/features/support/env.rb +10 -0
- data/features/support/file_template_helpers.rb +137 -0
- data/features/support/generator_helpers.rb +123 -0
- data/features/support/platform_extension_helpers.rb +27 -0
- data/lib/rake/baseextensiontask.rb +90 -0
- data/lib/rake/extensioncompiler.rb +53 -0
- data/lib/rake/extensiontask.rb +513 -0
- data/lib/rake/javaextensiontask.rb +226 -0
- data/spec/lib/rake/extensiontask_spec.rb +501 -0
- data/spec/lib/rake/javaextensiontask_spec.rb +182 -0
- data/spec/spec.opts +3 -0
- data/spec/spec_helper.rb +15 -0
- data/spec/support/capture_output_helper.rb +22 -0
- data/tasks/bin/cross-ruby.rake +213 -0
- data/tasks/bootstrap.rake +11 -0
- data/tasks/common.rake +10 -0
- data/tasks/cucumber.rake +23 -0
- data/tasks/gem.rake +52 -0
- data/tasks/news.rake +39 -0
- data/tasks/release.rake +26 -0
- data/tasks/rspec.rake +9 -0
- metadata +138 -0
@@ -0,0 +1,53 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
module Rake
|
4
|
+
|
5
|
+
#
|
6
|
+
# HACK: Lousy API design, sue me. At least works ;-)
|
7
|
+
#
|
8
|
+
# Define a series of helpers to aid in search and usage of MinGW (GCC) Compiler
|
9
|
+
# by gem developer/creators.
|
10
|
+
#
|
11
|
+
module ExtensionCompiler
|
12
|
+
# return the host portion from the installed MinGW
|
13
|
+
def self.mingw_host
|
14
|
+
return @mingw_host if @mingw_host
|
15
|
+
|
16
|
+
# the mingw_gcc_executable is helpful here
|
17
|
+
if target = mingw_gcc_executable then
|
18
|
+
# we only care for the filename
|
19
|
+
target = File.basename(target)
|
20
|
+
|
21
|
+
# now strip the extension (if present)
|
22
|
+
target.sub!(File.extname(target), '')
|
23
|
+
|
24
|
+
# get rid of '-gcc' portion too ;-)
|
25
|
+
target.sub!('-gcc', '')
|
26
|
+
end
|
27
|
+
|
28
|
+
raise "No MinGW tools or unknown setup platform?" unless target
|
29
|
+
|
30
|
+
@mingw_host = target
|
31
|
+
end
|
32
|
+
|
33
|
+
# return the first compiler found that includes both mingw and gcc conditions
|
34
|
+
# (this assumes you have one installed)
|
35
|
+
def self.mingw_gcc_executable
|
36
|
+
return @mingw_gcc_executable if @mingw_gcc_executable
|
37
|
+
|
38
|
+
# grab the paths defined in the environment
|
39
|
+
paths = ENV['PATH'].split(File::PATH_SEPARATOR)
|
40
|
+
|
41
|
+
# the pattern to look into (captures *nix and windows executables)
|
42
|
+
pattern = "{mingw32-,i?86*mingw*}gcc{,.*}"
|
43
|
+
|
44
|
+
@mingw_gcc_executable = paths.find do |path|
|
45
|
+
# cleanup paths before globbing
|
46
|
+
gcc = Dir.glob("#{File.expand_path(path)}/#{pattern}").first
|
47
|
+
break gcc if gcc
|
48
|
+
end
|
49
|
+
|
50
|
+
@mingw_gcc_executable
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,513 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'rake/baseextensiontask'
|
4
|
+
require "rubygems/package_task"
|
5
|
+
|
6
|
+
# Define a series of tasks to aid in the compilation of C extensions for
|
7
|
+
# gem developer/creators.
|
8
|
+
|
9
|
+
module Rake
|
10
|
+
class ExtensionTask < BaseExtensionTask
|
11
|
+
|
12
|
+
attr_accessor :config_script
|
13
|
+
attr_accessor :cross_compile
|
14
|
+
attr_accessor :cross_platform
|
15
|
+
attr_writer :cross_config_options
|
16
|
+
attr_accessor :no_native
|
17
|
+
attr_accessor :config_includes
|
18
|
+
|
19
|
+
def init(name = nil, gem_spec = nil)
|
20
|
+
super
|
21
|
+
@config_script = 'extconf.rb'
|
22
|
+
@source_pattern = "*.c"
|
23
|
+
@compiled_pattern = "*.{o,obj,so,bundle,dSYM}"
|
24
|
+
@cross_compile = false
|
25
|
+
@cross_config_options = []
|
26
|
+
@cross_compiling = nil
|
27
|
+
@no_native = false
|
28
|
+
@config_includes = []
|
29
|
+
end
|
30
|
+
|
31
|
+
def cross_platform
|
32
|
+
@cross_platform ||= 'i386-mingw32'
|
33
|
+
end
|
34
|
+
|
35
|
+
def cross_compiling(&block)
|
36
|
+
@cross_compiling = block if block_given?
|
37
|
+
end
|
38
|
+
|
39
|
+
def binary(platform = nil)
|
40
|
+
if platform == "java"
|
41
|
+
"#{name}.#{RbConfig::MAKEFILE_CONFIG['DLEXT']}"
|
42
|
+
else
|
43
|
+
super
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def define
|
48
|
+
if (defined?(RUBY_ENGINE) && RUBY_ENGINE == 'ironruby')
|
49
|
+
warn_once <<-EOF
|
50
|
+
WARNING: You're attempting to (cross-)compile C extensions from a platform
|
51
|
+
(#{RUBY_ENGINE}) that does not support native extensions or mkmf.rb.
|
52
|
+
Rerun `rake` under MRI Ruby 1.8.x/1.9.x to cross/native compile.
|
53
|
+
EOF
|
54
|
+
return
|
55
|
+
end
|
56
|
+
|
57
|
+
super
|
58
|
+
|
59
|
+
unless compiled_files.empty?
|
60
|
+
warn "WARNING: rake-compiler found compiled files in '#{@ext_dir}' directory. Please remove them."
|
61
|
+
end
|
62
|
+
|
63
|
+
# only gems with 'ruby' platforms are allowed to define native tasks
|
64
|
+
define_native_tasks if !@no_native && (@gem_spec && @gem_spec.platform == 'ruby')
|
65
|
+
|
66
|
+
# only define cross platform functionality when enabled
|
67
|
+
return unless @cross_compile
|
68
|
+
|
69
|
+
if cross_platform.is_a?(Array) then
|
70
|
+
cross_platform.each { |platf| define_cross_platform_tasks(platf) }
|
71
|
+
else
|
72
|
+
define_cross_platform_tasks(cross_platform)
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
def cross_config_options(for_platform=nil)
|
77
|
+
return @cross_config_options unless for_platform
|
78
|
+
|
79
|
+
# apply options for this platform, only
|
80
|
+
@cross_config_options.map do |option|
|
81
|
+
if option.kind_of?(Hash)
|
82
|
+
option[for_platform] || []
|
83
|
+
else
|
84
|
+
option
|
85
|
+
end
|
86
|
+
end.flatten
|
87
|
+
end
|
88
|
+
|
89
|
+
private
|
90
|
+
def define_compile_tasks(for_platform = nil, ruby_ver = RUBY_VERSION)
|
91
|
+
# platform usage
|
92
|
+
platf = for_platform || platform
|
93
|
+
|
94
|
+
# lib_path
|
95
|
+
lib_path = lib_dir
|
96
|
+
|
97
|
+
# tmp_path
|
98
|
+
tmp_path = "#{@tmp_dir}/#{platf}/#{@name}/#{ruby_ver}"
|
99
|
+
stage_path = "#{@tmp_dir}/#{platf}/stage"
|
100
|
+
|
101
|
+
# cleanup and clobbering
|
102
|
+
CLEAN.include(tmp_path)
|
103
|
+
CLEAN.include(stage_path)
|
104
|
+
CLOBBER.include("#{lib_path}/#{binary(platf)}")
|
105
|
+
CLOBBER.include("#{@tmp_dir}")
|
106
|
+
|
107
|
+
# directories we need
|
108
|
+
directory tmp_path
|
109
|
+
directory "#{stage_path}/#{lib_path}"
|
110
|
+
directory lib_dir
|
111
|
+
|
112
|
+
# copy binary from temporary location to final lib
|
113
|
+
# tmp/extension_name/extension_name.{so,bundle} => lib/
|
114
|
+
task "copy:#{@name}:#{platf}:#{ruby_ver}" => [lib_path, "#{tmp_path}/#{binary(platf)}"] do
|
115
|
+
install "#{tmp_path}/#{binary(platf)}", "#{lib_path}/#{binary(platf)}"
|
116
|
+
end
|
117
|
+
# copy binary from temporary location to staging directory
|
118
|
+
task "copy:#{@name}:#{platf}:#{ruby_ver}" => ["#{stage_path}/#{lib_path}", "#{tmp_path}/#{binary(platf)}"] do
|
119
|
+
cp "#{tmp_path}/#{binary(platf)}", "#{stage_path}/#{lib_path}/#{binary(platf)}"
|
120
|
+
end
|
121
|
+
|
122
|
+
# copy other gem files to staging directory
|
123
|
+
if @gem_spec
|
124
|
+
@gem_spec.files.each do |gem_file|
|
125
|
+
# ignore directories and the binary extension
|
126
|
+
next if File.directory?(gem_file) || gem_file == "#{lib_path}/#{binary(platf)}"
|
127
|
+
stage_file = "#{stage_path}/#{gem_file}"
|
128
|
+
|
129
|
+
# copy each file from base to stage directory
|
130
|
+
unless Rake::Task.task_defined?(stage_file) then
|
131
|
+
directory File.dirname(stage_file)
|
132
|
+
file stage_file => [File.dirname(stage_file), gem_file] do
|
133
|
+
cp gem_file, stage_file
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
# append each file to the copy task
|
138
|
+
task "copy:#{@name}:#{platf}:#{ruby_ver}" => [stage_file]
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
# binary in temporary folder depends on makefile and source files
|
143
|
+
# tmp/extension_name/extension_name.{so,bundle}
|
144
|
+
file "#{tmp_path}/#{binary(platf)}" => ["#{tmp_path}/Makefile"] + source_files do
|
145
|
+
jruby_compile_msg = <<-EOF
|
146
|
+
Compiling a native C extension on JRuby. This is discouraged and a
|
147
|
+
Java extension should be preferred.
|
148
|
+
EOF
|
149
|
+
warn_once(jruby_compile_msg) if defined?(JRUBY_VERSION)
|
150
|
+
|
151
|
+
chdir tmp_path do
|
152
|
+
sh make
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
# makefile depends of tmp_dir and config_script
|
157
|
+
# tmp/extension_name/Makefile
|
158
|
+
file "#{tmp_path}/Makefile" => [tmp_path, extconf] do |t|
|
159
|
+
options = @config_options.dup
|
160
|
+
|
161
|
+
# include current directory
|
162
|
+
include_dirs = ['.'].concat(@config_includes).uniq.join(File::PATH_SEPARATOR)
|
163
|
+
cmd = [Gem.ruby, "-I#{include_dirs}"]
|
164
|
+
|
165
|
+
# build a relative path to extconf script
|
166
|
+
abs_tmp_path = (Pathname.new(Dir.pwd) + tmp_path).realpath
|
167
|
+
abs_extconf = (Pathname.new(Dir.pwd) + extconf).realpath
|
168
|
+
|
169
|
+
# now add the extconf script
|
170
|
+
cmd << abs_extconf.relative_path_from(abs_tmp_path)
|
171
|
+
|
172
|
+
# rbconfig.rb will be present if we are cross compiling
|
173
|
+
if t.prerequisites.include?("#{tmp_path}/rbconfig.rb") then
|
174
|
+
options.push(*cross_config_options(platf))
|
175
|
+
end
|
176
|
+
|
177
|
+
# add options to command
|
178
|
+
cmd.push(*options)
|
179
|
+
|
180
|
+
# add any extra command line options
|
181
|
+
unless extra_options.empty?
|
182
|
+
cmd.push(*extra_options)
|
183
|
+
end
|
184
|
+
|
185
|
+
chdir tmp_path do
|
186
|
+
# FIXME: Rake is broken for multiple arguments system() calls.
|
187
|
+
# Add current directory to the search path of Ruby
|
188
|
+
sh cmd.join(' ')
|
189
|
+
end
|
190
|
+
end
|
191
|
+
|
192
|
+
# compile tasks
|
193
|
+
unless Rake::Task.task_defined?('compile') then
|
194
|
+
desc "Compile all the extensions"
|
195
|
+
task "compile"
|
196
|
+
end
|
197
|
+
|
198
|
+
# compile:name
|
199
|
+
unless Rake::Task.task_defined?("compile:#{@name}") then
|
200
|
+
desc "Compile #{@name}"
|
201
|
+
task "compile:#{@name}"
|
202
|
+
end
|
203
|
+
|
204
|
+
# Allow segmented compilation by platform (open door for 'cross compile')
|
205
|
+
task "compile:#{@name}:#{platf}" => ["copy:#{@name}:#{platf}:#{ruby_ver}"]
|
206
|
+
task "compile:#{platf}" => ["compile:#{@name}:#{platf}"]
|
207
|
+
|
208
|
+
# Only add this extension to the compile chain if current
|
209
|
+
# platform matches the indicated one.
|
210
|
+
if platf == RUBY_PLATFORM then
|
211
|
+
# ensure file is always copied
|
212
|
+
file "#{lib_path}/#{binary(platf)}" => ["copy:#{name}:#{platf}:#{ruby_ver}"]
|
213
|
+
|
214
|
+
task "compile:#{@name}" => ["compile:#{@name}:#{platf}"]
|
215
|
+
task "compile" => ["compile:#{platf}"]
|
216
|
+
end
|
217
|
+
end
|
218
|
+
|
219
|
+
def define_native_tasks(for_platform = nil, ruby_ver = RUBY_VERSION, callback = nil)
|
220
|
+
platf = for_platform || platform
|
221
|
+
|
222
|
+
# tmp_path
|
223
|
+
tmp_path = "#{@tmp_dir}/#{platf}/#{@name}/#{ruby_ver}"
|
224
|
+
stage_path = "#{@tmp_dir}/#{platf}/stage"
|
225
|
+
|
226
|
+
# lib_path
|
227
|
+
lib_path = lib_dir
|
228
|
+
|
229
|
+
# create 'native:gem_name' and chain it to 'native' task
|
230
|
+
unless Rake::Task.task_defined?("native:#{@gem_spec.name}:#{platf}")
|
231
|
+
task "native:#{@gem_spec.name}:#{platf}" do |t|
|
232
|
+
# FIXME: workaround Gem::Specification limitation around cache_file:
|
233
|
+
# http://github.com/rubygems/rubygems/issues/78
|
234
|
+
spec = gem_spec.dup
|
235
|
+
spec.instance_variable_set(:"@cache_file", nil) if spec.respond_to?(:cache_file)
|
236
|
+
|
237
|
+
# adjust to specified platform
|
238
|
+
spec.platform = Gem::Platform.new(platf)
|
239
|
+
|
240
|
+
# clear the extensions defined in the specs
|
241
|
+
spec.extensions.clear
|
242
|
+
|
243
|
+
# add the binaries that this task depends on
|
244
|
+
ext_files = []
|
245
|
+
|
246
|
+
# go through native prerequisites and grab the real extension files from there
|
247
|
+
t.prerequisites.each do |ext|
|
248
|
+
# strip stage path and keep lib/... only
|
249
|
+
ext_files << ext.sub(stage_path+"/", '')
|
250
|
+
end
|
251
|
+
|
252
|
+
# include the files in the gem specification
|
253
|
+
spec.files += ext_files
|
254
|
+
|
255
|
+
# expose gem specification for customization
|
256
|
+
if callback
|
257
|
+
callback.call(spec)
|
258
|
+
end
|
259
|
+
|
260
|
+
# Generate a package for this gem
|
261
|
+
pkg = Gem::PackageTask.new(spec) do |pkg|
|
262
|
+
pkg.need_zip = false
|
263
|
+
pkg.need_tar = false
|
264
|
+
# Do not copy any files per PackageTask, because
|
265
|
+
# we need the files from the staging directory
|
266
|
+
pkg.package_files.clear
|
267
|
+
end
|
268
|
+
|
269
|
+
# Copy from staging directory to gem package directory.
|
270
|
+
# This is derived from the code of Gem::PackageTask
|
271
|
+
# but uses stage_path as source directory.
|
272
|
+
stage_files = spec.files.map do |gem_file|
|
273
|
+
File.join(stage_path, gem_file)
|
274
|
+
end
|
275
|
+
file pkg.package_dir_path => stage_files do
|
276
|
+
mkdir_p pkg.package_dir rescue nil
|
277
|
+
spec.files.each do |ft|
|
278
|
+
fn = File.join(stage_path, ft)
|
279
|
+
f = File.join(pkg.package_dir_path, ft)
|
280
|
+
fdir = File.dirname(f)
|
281
|
+
mkdir_p(fdir) if !File.exist?(fdir)
|
282
|
+
if File.directory?(fn)
|
283
|
+
mkdir_p(f)
|
284
|
+
else
|
285
|
+
rm_f f
|
286
|
+
safe_ln(fn, f)
|
287
|
+
end
|
288
|
+
end
|
289
|
+
end
|
290
|
+
end
|
291
|
+
end
|
292
|
+
|
293
|
+
# add binaries to the dependency chain
|
294
|
+
task "native:#{@gem_spec.name}:#{platf}" => ["#{stage_path}/#{lib_dir}/#{binary(platf)}"]
|
295
|
+
|
296
|
+
# ensure the extension get copied
|
297
|
+
unless Rake::Task.task_defined?("#{lib_path}/#{binary(platf)}") then
|
298
|
+
file "#{lib_path}/#{binary(platf)}" => ["copy:#{@name}:#{platf}:#{ruby_ver}"]
|
299
|
+
end
|
300
|
+
file "#{stage_path}/#{lib_dir}/#{binary(platf)}" => ["copy:#{@name}:#{platf}:#{ruby_ver}"]
|
301
|
+
|
302
|
+
# Allow segmented packaging by platform (open door for 'cross compile')
|
303
|
+
task "native:#{platf}" => ["native:#{@gem_spec.name}:#{platf}"]
|
304
|
+
|
305
|
+
# Only add this extension to the compile chain if current
|
306
|
+
# platform matches the indicated one.
|
307
|
+
if platf == RUBY_PLATFORM then
|
308
|
+
task "native:#{@gem_spec.name}" => ["native:#{@gem_spec.name}:#{platf}"]
|
309
|
+
task "native" => ["native:#{platf}"]
|
310
|
+
end
|
311
|
+
end
|
312
|
+
|
313
|
+
def define_cross_platform_tasks(for_platform)
|
314
|
+
if ruby_vers = ENV['RUBY_CC_VERSION']
|
315
|
+
ruby_vers = ENV['RUBY_CC_VERSION'].split(':')
|
316
|
+
else
|
317
|
+
ruby_vers = [RUBY_VERSION]
|
318
|
+
end
|
319
|
+
|
320
|
+
multi = (ruby_vers.size > 1) ? true : false
|
321
|
+
|
322
|
+
ruby_vers.each do |version|
|
323
|
+
# save original lib_dir
|
324
|
+
orig_lib_dir = @lib_dir
|
325
|
+
|
326
|
+
# tweak lib directory only when targeting multiple versions
|
327
|
+
if multi then
|
328
|
+
version =~ /(\d+.\d+)/
|
329
|
+
@lib_dir = "#{@lib_dir}/#{$1}"
|
330
|
+
end
|
331
|
+
|
332
|
+
define_cross_platform_tasks_with_version(for_platform, version)
|
333
|
+
|
334
|
+
# restore lib_dir
|
335
|
+
@lib_dir = orig_lib_dir
|
336
|
+
end
|
337
|
+
end
|
338
|
+
|
339
|
+
def define_cross_platform_tasks_with_version(for_platform, ruby_ver)
|
340
|
+
config_path = File.expand_path("~/.rake-compiler/config.yml")
|
341
|
+
|
342
|
+
# warn the user about the need of configuration to use cross compilation.
|
343
|
+
unless File.exist?(config_path)
|
344
|
+
define_dummy_cross_platform_tasks
|
345
|
+
return
|
346
|
+
end
|
347
|
+
|
348
|
+
config_file = YAML.load_file(config_path)
|
349
|
+
|
350
|
+
# tmp_path
|
351
|
+
tmp_path = "#{@tmp_dir}/#{for_platform}/#{@name}/#{ruby_ver}"
|
352
|
+
|
353
|
+
# lib_path
|
354
|
+
lib_path = lib_dir
|
355
|
+
|
356
|
+
unless rbconfig_file = config_file["rbconfig-#{for_platform}-#{ruby_ver}"] then
|
357
|
+
warn "no configuration section for specified version of Ruby (rbconfig-#{for_platform}-#{ruby_ver})"
|
358
|
+
return
|
359
|
+
end
|
360
|
+
|
361
|
+
# mkmf
|
362
|
+
mkmf_file = File.expand_path(File.join(File.dirname(rbconfig_file), '..', 'mkmf.rb'))
|
363
|
+
|
364
|
+
# define compilation tasks for cross platform!
|
365
|
+
define_compile_tasks(for_platform, ruby_ver)
|
366
|
+
|
367
|
+
# chain fake.rb, rbconfig.rb and mkmf.rb to Makefile generation
|
368
|
+
file "#{tmp_path}/Makefile" => ["#{tmp_path}/fake.rb",
|
369
|
+
"#{tmp_path}/rbconfig.rb",
|
370
|
+
"#{tmp_path}/mkmf.rb"]
|
371
|
+
|
372
|
+
# copy the file from the cross-ruby location
|
373
|
+
file "#{tmp_path}/rbconfig.rb" => [rbconfig_file] do |t|
|
374
|
+
File.open(t.name, 'w') do |f|
|
375
|
+
f.write "require 'fake.rb'\n\n"
|
376
|
+
f.write File.read(t.prerequisites.first)
|
377
|
+
end
|
378
|
+
end
|
379
|
+
|
380
|
+
# copy mkmf from cross-ruby location
|
381
|
+
file "#{tmp_path}/mkmf.rb" => [mkmf_file] do |t|
|
382
|
+
cp t.prerequisites.first, t.name
|
383
|
+
if ruby_ver < "1.9" && "1.9" <= RUBY_VERSION
|
384
|
+
File.open(t.name, 'r+t') do |f|
|
385
|
+
content = f.read
|
386
|
+
content.sub!(/^( break )\*(defaults)$/, '\\1\\2.first')
|
387
|
+
content.sub!(/^( return )\*(defaults)$/, '\\1\\2.first')
|
388
|
+
content.sub!(/^( mfile\.)print( configuration\(srcprefix\))$/, '\\1puts\\2')
|
389
|
+
f.rewind
|
390
|
+
f.write content
|
391
|
+
f.truncate(f.tell)
|
392
|
+
end
|
393
|
+
end
|
394
|
+
end
|
395
|
+
|
396
|
+
# genearte fake.rb for different ruby versions
|
397
|
+
file "#{tmp_path}/fake.rb" do |t|
|
398
|
+
File.open(t.name, 'w') do |f|
|
399
|
+
f.write fake_rb(for_platform, ruby_ver)
|
400
|
+
end
|
401
|
+
end
|
402
|
+
|
403
|
+
# now define native tasks for cross compiled files
|
404
|
+
if @gem_spec && @gem_spec.platform == 'ruby' then
|
405
|
+
define_native_tasks(for_platform, ruby_ver, @cross_compiling)
|
406
|
+
end
|
407
|
+
|
408
|
+
# create cross task
|
409
|
+
task 'cross' do
|
410
|
+
# clear compile dependencies
|
411
|
+
Rake::Task['compile'].prerequisites.reject! { |t| !compiles_cross_platform.include?(t) }
|
412
|
+
|
413
|
+
# chain the cross platform ones
|
414
|
+
task 'compile' => ["compile:#{for_platform}"]
|
415
|
+
|
416
|
+
# clear lib/binary dependencies and trigger cross platform ones
|
417
|
+
# check if lib/binary is defined (damn bundle versus so versus dll)
|
418
|
+
if Rake::Task.task_defined?("#{lib_path}/#{binary(for_platform)}") then
|
419
|
+
Rake::Task["#{lib_path}/#{binary(for_platform)}"].prerequisites.clear
|
420
|
+
end
|
421
|
+
|
422
|
+
# FIXME: targeting multiple platforms copies the file twice
|
423
|
+
file "#{lib_path}/#{binary(for_platform)}" => ["copy:#{@name}:#{for_platform}:#{ruby_ver}"]
|
424
|
+
|
425
|
+
# if everything for native task is in place
|
426
|
+
if @gem_spec && @gem_spec.platform == 'ruby' then
|
427
|
+
# double check: only cross platform native tasks should be here
|
428
|
+
# FIXME: Sooo brittle
|
429
|
+
Rake::Task['native'].prerequisites.reject! { |t| !natives_cross_platform.include?(t) }
|
430
|
+
task 'native' => ["native:#{for_platform}"]
|
431
|
+
end
|
432
|
+
end
|
433
|
+
end
|
434
|
+
|
435
|
+
def define_dummy_cross_platform_tasks
|
436
|
+
task 'cross' do
|
437
|
+
Rake::Task['compile'].clear
|
438
|
+
task 'compile' do
|
439
|
+
raise "rake-compiler must be configured first to enable cross-compilation"
|
440
|
+
end
|
441
|
+
end
|
442
|
+
end
|
443
|
+
|
444
|
+
def extconf
|
445
|
+
"#{@ext_dir}/#{@config_script}"
|
446
|
+
end
|
447
|
+
|
448
|
+
def make
|
449
|
+
unless @make
|
450
|
+
@make =
|
451
|
+
if RUBY_PLATFORM =~ /mswin/ then
|
452
|
+
'nmake'
|
453
|
+
else
|
454
|
+
ENV['MAKE'] || %w[gmake make].find { |c|
|
455
|
+
system("#{c} -v >> #{dev_null} 2>&1")
|
456
|
+
}
|
457
|
+
end
|
458
|
+
end
|
459
|
+
|
460
|
+
unless @make
|
461
|
+
raise "Couldn't find a suitable `make` tool. Use `MAKE` env to set an alternative."
|
462
|
+
end
|
463
|
+
|
464
|
+
@make
|
465
|
+
end
|
466
|
+
|
467
|
+
def dev_null
|
468
|
+
windows? ? 'NUL' : '/dev/null'
|
469
|
+
end
|
470
|
+
|
471
|
+
def compiled_files
|
472
|
+
FileList["#{@ext_dir}/#{@compiled_pattern}"]
|
473
|
+
end
|
474
|
+
|
475
|
+
def compiles_cross_platform
|
476
|
+
[*@cross_platform].map { |p| "compile:#{p}" }
|
477
|
+
end
|
478
|
+
|
479
|
+
def natives_cross_platform
|
480
|
+
[*@cross_platform].map { |p| "native:#{p}" }
|
481
|
+
end
|
482
|
+
|
483
|
+
def fake_rb(platform, version)
|
484
|
+
<<-FAKE_RB
|
485
|
+
# Pre-load resolver library before faking, in order to avoid error
|
486
|
+
# "cannot load such file -- win32/resolv" when it is required later on.
|
487
|
+
# See also: https://github.com/tjschuck/rake-compiler-dev-box/issues/5
|
488
|
+
require 'resolv'
|
489
|
+
|
490
|
+
class Object
|
491
|
+
remove_const :RUBY_PLATFORM
|
492
|
+
remove_const :RUBY_VERSION
|
493
|
+
remove_const :RUBY_DESCRIPTION if defined?(RUBY_DESCRIPTION)
|
494
|
+
RUBY_PLATFORM = "#{platform}"
|
495
|
+
RUBY_VERSION = "#{version}"
|
496
|
+
RUBY_DESCRIPTION = "ruby \#{RUBY_VERSION} (\#{RUBY_RELEASE_DATE}) [\#{RUBY_PLATFORM}]"
|
497
|
+
end
|
498
|
+
if RUBY_PLATFORM =~ /mswin|bccwin|mingw/
|
499
|
+
class File
|
500
|
+
remove_const :ALT_SEPARATOR
|
501
|
+
ALT_SEPARATOR = "\\\\"
|
502
|
+
end
|
503
|
+
end
|
504
|
+
|
505
|
+
posthook = proc do
|
506
|
+
$ruby = "#{Gem.ruby}"
|
507
|
+
untrace_var(:$ruby, posthook)
|
508
|
+
end
|
509
|
+
trace_var(:$ruby, posthook)
|
510
|
+
FAKE_RB
|
511
|
+
end
|
512
|
+
end
|
513
|
+
end
|