micro-fast-tool 0.0.1
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/micro-fast-tool.gemspec +12 -0
- data/rake-compiler-1.3.1/Gemfile +8 -0
- data/rake-compiler-1.3.1/History.md +695 -0
- data/rake-compiler-1.3.1/LICENSE.txt +20 -0
- data/rake-compiler-1.3.1/README.md +476 -0
- data/rake-compiler-1.3.1/Rakefile +15 -0
- data/rake-compiler-1.3.1/appveyor.yml +22 -0
- data/rake-compiler-1.3.1/bin/rake-compiler +24 -0
- data/rake-compiler-1.3.1/cucumber.yml +4 -0
- data/rake-compiler-1.3.1/features/compile.feature +79 -0
- data/rake-compiler-1.3.1/features/cross-compile.feature +23 -0
- data/rake-compiler-1.3.1/features/cross-package-multi.feature +15 -0
- data/rake-compiler-1.3.1/features/cross-package.feature +14 -0
- data/rake-compiler-1.3.1/features/java-compile.feature +22 -0
- data/rake-compiler-1.3.1/features/java-no-native-compile.feature +33 -0
- data/rake-compiler-1.3.1/features/java-package.feature +24 -0
- data/rake-compiler-1.3.1/features/package.feature +40 -0
- data/rake-compiler-1.3.1/features/step_definitions/compilation.rb +70 -0
- data/rake-compiler-1.3.1/features/step_definitions/cross_compilation.rb +27 -0
- data/rake-compiler-1.3.1/features/step_definitions/execution.rb +52 -0
- data/rake-compiler-1.3.1/features/step_definitions/folders.rb +32 -0
- data/rake-compiler-1.3.1/features/step_definitions/gem.rb +46 -0
- data/rake-compiler-1.3.1/features/step_definitions/java_compilation.rb +7 -0
- data/rake-compiler-1.3.1/features/support/env.rb +10 -0
- data/rake-compiler-1.3.1/features/support/file_template_helpers.rb +137 -0
- data/rake-compiler-1.3.1/features/support/generator_helpers.rb +123 -0
- data/rake-compiler-1.3.1/features/support/platform_extension_helpers.rb +27 -0
- data/rake-compiler-1.3.1/lib/rake/baseextensiontask.rb +90 -0
- data/rake-compiler-1.3.1/lib/rake/compiler_config.rb +38 -0
- data/rake-compiler-1.3.1/lib/rake/extensioncompiler.rb +51 -0
- data/rake-compiler-1.3.1/lib/rake/extensiontask.rb +589 -0
- data/rake-compiler-1.3.1/lib/rake/javaextensiontask.rb +321 -0
- data/rake-compiler-1.3.1/tasks/bin/cross-ruby.rake +189 -0
- data/rake-compiler-1.3.1/tasks/bootstrap.rake +11 -0
- data/rake-compiler-1.3.1/tasks/common.rake +10 -0
- data/rake-compiler-1.3.1/tasks/cucumber.rake +23 -0
- data/rake-compiler-1.3.1/tasks/gem.rake +15 -0
- data/rake-compiler-1.3.1/tasks/rspec.rake +9 -0
- metadata +79 -0
|
@@ -0,0 +1,589 @@
|
|
|
1
|
+
require "rbconfig"
|
|
2
|
+
require "shellwords"
|
|
3
|
+
|
|
4
|
+
require 'rake/baseextensiontask'
|
|
5
|
+
require "rubygems/package_task"
|
|
6
|
+
|
|
7
|
+
# Define a series of tasks to aid in the compilation of C extensions for
|
|
8
|
+
# gem developer/creators.
|
|
9
|
+
|
|
10
|
+
module Rake
|
|
11
|
+
class ExtensionTask < BaseExtensionTask
|
|
12
|
+
attr_accessor :config_script
|
|
13
|
+
attr_accessor :cross_compile
|
|
14
|
+
attr_writer :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,cc,cpp}"
|
|
23
|
+
@compiled_pattern = "*.{o,obj,so,bundle,dSYM}"
|
|
24
|
+
@cross_compile = false
|
|
25
|
+
@cross_config_options = []
|
|
26
|
+
@cross_compiling = nil
|
|
27
|
+
@no_native = (ENV["RAKE_EXTENSION_TASK_NO_NATIVE"] == "true")
|
|
28
|
+
@config_includes = []
|
|
29
|
+
# Default to an empty list of ruby versions for each platform
|
|
30
|
+
@ruby_versions_per_platform = Hash.new { |h, k| h[k] = [] }
|
|
31
|
+
@make = nil
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def cross_platform
|
|
35
|
+
@cross_platform ||= 'i386-mingw32'
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def cross_compiling(&block)
|
|
39
|
+
@cross_compiling = block if block_given?
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def binary(platform = nil)
|
|
43
|
+
if platform == "java"
|
|
44
|
+
"#{name}.#{RbConfig::MAKEFILE_CONFIG['DLEXT']}"
|
|
45
|
+
else
|
|
46
|
+
super
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def define
|
|
51
|
+
super
|
|
52
|
+
|
|
53
|
+
unless compiled_files.empty?
|
|
54
|
+
warn "WARNING: rake-compiler found compiled files in '#{@ext_dir}' directory. Please remove them."
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
# only gems with 'ruby' platforms are allowed to define native tasks
|
|
58
|
+
define_native_tasks if !@no_native && (@gem_spec && @gem_spec.platform == 'ruby')
|
|
59
|
+
|
|
60
|
+
# only define cross platform functionality when enabled
|
|
61
|
+
return unless @cross_compile
|
|
62
|
+
|
|
63
|
+
if cross_platform.is_a?(Array) then
|
|
64
|
+
cross_platform.each { |platf| define_cross_platform_tasks(platf) }
|
|
65
|
+
else
|
|
66
|
+
define_cross_platform_tasks(cross_platform)
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def cross_config_options(for_platform=nil)
|
|
71
|
+
return @cross_config_options unless for_platform
|
|
72
|
+
|
|
73
|
+
# apply options for this platform, only
|
|
74
|
+
@cross_config_options.map do |option|
|
|
75
|
+
if option.kind_of?(Hash)
|
|
76
|
+
option[for_platform] || []
|
|
77
|
+
else
|
|
78
|
+
option
|
|
79
|
+
end
|
|
80
|
+
end.flatten
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
def make_makefile_cmd(root_path, tmp_path, extconf, cross_platform) # :nodoc:
|
|
84
|
+
# include current directory
|
|
85
|
+
include_dirs = ['.'].concat(@config_includes).uniq.join(File::PATH_SEPARATOR)
|
|
86
|
+
|
|
87
|
+
# build a relative path to extconf script
|
|
88
|
+
abs_tmp_path = (Pathname.new(root_path) + tmp_path).realpath
|
|
89
|
+
abs_extconf = (Pathname.new(root_path) + extconf).realpath
|
|
90
|
+
rel_extconf = abs_extconf.relative_path_from(abs_tmp_path).to_s
|
|
91
|
+
|
|
92
|
+
# base command
|
|
93
|
+
cmd = [Gem.ruby, "-I#{include_dirs}", rel_extconf]
|
|
94
|
+
|
|
95
|
+
# add all the options
|
|
96
|
+
cmd += @config_options
|
|
97
|
+
cmd += cross_config_options(cross_platform) if cross_platform
|
|
98
|
+
cmd += extra_options
|
|
99
|
+
|
|
100
|
+
cmd.compact
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
private
|
|
104
|
+
# copy other gem files to staging directory
|
|
105
|
+
def define_staging_file_tasks(files, lib_path, stage_path, platf, ruby_ver)
|
|
106
|
+
# lib_binary_path
|
|
107
|
+
lib_binary_path = "#{lib_path}/#{File.basename(binary(platf))}"
|
|
108
|
+
|
|
109
|
+
files.each do |gem_file|
|
|
110
|
+
# ignore directories and the binary extension
|
|
111
|
+
next if File.directory?(gem_file) || gem_file == lib_binary_path
|
|
112
|
+
stage_file = "#{stage_path}/#{gem_file}"
|
|
113
|
+
|
|
114
|
+
# copy each file from base to stage directory
|
|
115
|
+
unless Rake::Task.task_defined?(stage_file) then
|
|
116
|
+
directory File.dirname(stage_file)
|
|
117
|
+
file stage_file => [File.dirname(stage_file), gem_file] do
|
|
118
|
+
cp gem_file, stage_file
|
|
119
|
+
end
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
# append each file to the copy task
|
|
123
|
+
task "copy:#{@name}:#{platf}:#{ruby_ver}" => [stage_file]
|
|
124
|
+
end
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
def define_compile_tasks(for_platform = nil, ruby_ver = RUBY_VERSION)
|
|
128
|
+
# platform usage
|
|
129
|
+
platf = for_platform || platform
|
|
130
|
+
|
|
131
|
+
binary_path = binary(platf)
|
|
132
|
+
binary_base_name = File.basename(binary_path)
|
|
133
|
+
|
|
134
|
+
# lib_path
|
|
135
|
+
lib_path = lib_dir
|
|
136
|
+
|
|
137
|
+
# lib_binary_path
|
|
138
|
+
lib_binary_path = "#{lib_path}/#{binary_base_name}"
|
|
139
|
+
|
|
140
|
+
# tmp_path
|
|
141
|
+
tmp_path = "#{@tmp_dir}/#{platf}/#{@name}/#{ruby_ver}"
|
|
142
|
+
stage_path = "#{@tmp_dir}/#{platf}/stage"
|
|
143
|
+
|
|
144
|
+
tmp_binary_path = "#{tmp_path}/#{binary_path}"
|
|
145
|
+
tmp_binary_dir_path = File.dirname(tmp_binary_path)
|
|
146
|
+
stage_binary_path = "#{stage_path}/#{lib_binary_path}"
|
|
147
|
+
stage_binary_dir_path = File.dirname(stage_binary_path)
|
|
148
|
+
|
|
149
|
+
# cleanup and clobbering
|
|
150
|
+
CLEAN.include(tmp_path)
|
|
151
|
+
CLEAN.include(stage_path)
|
|
152
|
+
CLOBBER.include(lib_binary_path)
|
|
153
|
+
CLOBBER.include("#{@tmp_dir}")
|
|
154
|
+
|
|
155
|
+
# directories we need
|
|
156
|
+
directory tmp_path
|
|
157
|
+
directory tmp_binary_dir_path
|
|
158
|
+
directory lib_path
|
|
159
|
+
directory stage_binary_dir_path
|
|
160
|
+
|
|
161
|
+
# copy binary from temporary location to final lib
|
|
162
|
+
# tmp/extension_name/extension_name.{so,bundle} => lib/
|
|
163
|
+
task "copy:#{@name}:#{platf}:#{ruby_ver}" => [lib_path, tmp_binary_path, "#{tmp_path}/Makefile"] do
|
|
164
|
+
# install in lib for native platform only
|
|
165
|
+
unless for_platform
|
|
166
|
+
relative_lib_path = Pathname(lib_path).relative_path_from(Pathname.new(tmp_path))
|
|
167
|
+
|
|
168
|
+
make_command_line = Shellwords.shellsplit(make)
|
|
169
|
+
make_command_line << "install"
|
|
170
|
+
make_command_line << "sitearchdir=#{relative_lib_path}"
|
|
171
|
+
make_command_line << "sitelibdir=#{relative_lib_path}"
|
|
172
|
+
make_command_line << "target_prefix="
|
|
173
|
+
|
|
174
|
+
sh(*make_command_line, chdir: tmp_path)
|
|
175
|
+
end
|
|
176
|
+
end
|
|
177
|
+
# copy binary from temporary location to staging directory
|
|
178
|
+
task "copy:#{@name}:#{platf}:#{ruby_ver}" => [stage_binary_dir_path, tmp_binary_path] do
|
|
179
|
+
cp tmp_binary_path, stage_binary_path
|
|
180
|
+
end
|
|
181
|
+
|
|
182
|
+
# copy other gem files to staging directory
|
|
183
|
+
define_staging_file_tasks(@gem_spec.files, lib_path, stage_path, platf, ruby_ver) if @gem_spec
|
|
184
|
+
|
|
185
|
+
# binary in temporary folder depends on makefile and source files
|
|
186
|
+
# tmp/extension_name/extension_name.{so,bundle}
|
|
187
|
+
file tmp_binary_path => [tmp_binary_dir_path, "#{tmp_path}/Makefile"] + source_files do
|
|
188
|
+
jruby_compile_msg = <<-EOF
|
|
189
|
+
Compiling a native C extension on JRuby. This is discouraged and a
|
|
190
|
+
Java extension should be preferred.
|
|
191
|
+
EOF
|
|
192
|
+
warn_once(jruby_compile_msg) if defined?(JRUBY_VERSION)
|
|
193
|
+
|
|
194
|
+
chdir tmp_path do
|
|
195
|
+
sh make
|
|
196
|
+
if binary_path != binary_base_name
|
|
197
|
+
cp binary_base_name, binary_path
|
|
198
|
+
end
|
|
199
|
+
end
|
|
200
|
+
end
|
|
201
|
+
|
|
202
|
+
# makefile depends of tmp_dir and config_script
|
|
203
|
+
# tmp/extension_name/Makefile
|
|
204
|
+
file "#{tmp_path}/Makefile" => [tmp_path, extconf] do |t|
|
|
205
|
+
if t.prerequisites.include?("#{tmp_path}/fake.rb")
|
|
206
|
+
cross_platform = platf
|
|
207
|
+
else
|
|
208
|
+
cross_platform = nil
|
|
209
|
+
end
|
|
210
|
+
|
|
211
|
+
command = make_makefile_cmd(Dir.pwd, tmp_path, extconf, cross_platform)
|
|
212
|
+
|
|
213
|
+
chdir tmp_path do
|
|
214
|
+
sh(*command)
|
|
215
|
+
end
|
|
216
|
+
end
|
|
217
|
+
|
|
218
|
+
# compile tasks
|
|
219
|
+
unless Rake::Task.task_defined?('compile') then
|
|
220
|
+
desc "Compile all the extensions"
|
|
221
|
+
task "compile"
|
|
222
|
+
end
|
|
223
|
+
|
|
224
|
+
# compile:name
|
|
225
|
+
unless Rake::Task.task_defined?("compile:#{@name}") then
|
|
226
|
+
desc "Compile #{@name}"
|
|
227
|
+
task "compile:#{@name}"
|
|
228
|
+
end
|
|
229
|
+
|
|
230
|
+
# Allow segmented compilation by platform (open door for 'cross compile')
|
|
231
|
+
task "compile:#{@name}:#{platf}" => ["copy:#{@name}:#{platf}:#{ruby_ver}"]
|
|
232
|
+
task "compile:#{platf}" => ["compile:#{@name}:#{platf}"]
|
|
233
|
+
|
|
234
|
+
# Only add this extension to the compile chain if current
|
|
235
|
+
# platform matches the indicated one.
|
|
236
|
+
if platf == RUBY_PLATFORM then
|
|
237
|
+
# ensure file is always copied
|
|
238
|
+
file lib_binary_path => ["copy:#{name}:#{platf}:#{ruby_ver}"]
|
|
239
|
+
|
|
240
|
+
task "compile:#{@name}" => ["compile:#{@name}:#{platf}"]
|
|
241
|
+
task "compile" => ["compile:#{platf}"]
|
|
242
|
+
end
|
|
243
|
+
end
|
|
244
|
+
|
|
245
|
+
def define_native_tasks(for_platform = nil, ruby_ver = RUBY_VERSION, callback = nil)
|
|
246
|
+
platf = for_platform || platform
|
|
247
|
+
|
|
248
|
+
# tmp_path
|
|
249
|
+
stage_path = "#{@tmp_dir}/#{platf}/stage"
|
|
250
|
+
|
|
251
|
+
# lib_path
|
|
252
|
+
lib_path = lib_dir
|
|
253
|
+
|
|
254
|
+
# lib_binary_path
|
|
255
|
+
lib_binary_path = "#{lib_path}/#{File.basename(binary(platf))}"
|
|
256
|
+
|
|
257
|
+
# Update compiled platform/version combinations
|
|
258
|
+
@ruby_versions_per_platform[platf] << ruby_ver
|
|
259
|
+
|
|
260
|
+
# create 'native:gem_name' and chain it to 'native' task
|
|
261
|
+
unless Rake::Task.task_defined?("native:#{@gem_spec.name}:#{platf}")
|
|
262
|
+
task "native:#{@gem_spec.name}:#{platf}" do |t|
|
|
263
|
+
# FIXME: workaround Gem::Specification limitation around cache_file:
|
|
264
|
+
# http://github.com/rubygems/rubygems/issues/78
|
|
265
|
+
spec = gem_spec.dup
|
|
266
|
+
spec.instance_variable_set(:"@cache_file", nil) if spec.respond_to?(:cache_file)
|
|
267
|
+
|
|
268
|
+
# adjust to specified platform
|
|
269
|
+
spec.platform = Gem::Platform.new(platf)
|
|
270
|
+
|
|
271
|
+
# set ruby version constraints
|
|
272
|
+
ruby_versions = @ruby_versions_per_platform[platf]
|
|
273
|
+
sorted_ruby_versions = ruby_versions.sort_by do |ruby_version|
|
|
274
|
+
ruby_version.split(".").collect(&:to_i)
|
|
275
|
+
end
|
|
276
|
+
spec.required_ruby_version = [
|
|
277
|
+
">= #{ruby_api_version(sorted_ruby_versions.first)}",
|
|
278
|
+
"< #{ruby_api_version(sorted_ruby_versions.last).succ}.dev"
|
|
279
|
+
]
|
|
280
|
+
|
|
281
|
+
# set rubygems version constraints
|
|
282
|
+
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new("3.3.22") &&
|
|
283
|
+
spec.platform.os == "linux" && !spec.platform.version.nil?
|
|
284
|
+
spec.required_rubygems_version = if spec.required_rubygems_version == Gem::Requirement.default
|
|
285
|
+
[">= 3.3.22"]
|
|
286
|
+
else
|
|
287
|
+
Gem::Requirement.new(gem_spec.required_rubygems_version, ">= 3.3.22")
|
|
288
|
+
end
|
|
289
|
+
end
|
|
290
|
+
|
|
291
|
+
# clear the extensions defined in the specs
|
|
292
|
+
spec.extensions.clear
|
|
293
|
+
|
|
294
|
+
# add the binaries that this task depends on
|
|
295
|
+
ext_files = []
|
|
296
|
+
|
|
297
|
+
# go through native prerequisites and grab the real extension files from there
|
|
298
|
+
t.prerequisites.each do |ext|
|
|
299
|
+
# strip stage path and keep lib/... only
|
|
300
|
+
ext_files << ext.sub(stage_path+"/", '')
|
|
301
|
+
end
|
|
302
|
+
|
|
303
|
+
# include the files in the gem specification
|
|
304
|
+
spec.files += ext_files
|
|
305
|
+
|
|
306
|
+
# expose gem specification for customization
|
|
307
|
+
callback.call(spec) if callback
|
|
308
|
+
|
|
309
|
+
# Generate a package for this gem
|
|
310
|
+
pkg = Gem::PackageTask.new(spec) do |p|
|
|
311
|
+
p.need_zip = false
|
|
312
|
+
p.need_tar = false
|
|
313
|
+
# Do not copy any files per PackageTask, because
|
|
314
|
+
# we need the files from the staging directory
|
|
315
|
+
p.package_files.clear
|
|
316
|
+
end
|
|
317
|
+
|
|
318
|
+
# copy other gem files to staging directory if added by the callback
|
|
319
|
+
define_staging_file_tasks(spec.files, lib_path, stage_path, platf, ruby_ver)
|
|
320
|
+
|
|
321
|
+
# Copy from staging directory to gem package directory.
|
|
322
|
+
# This is derived from the code of Gem::PackageTask
|
|
323
|
+
# but uses stage_path as source directory.
|
|
324
|
+
stage_files = spec.files.map do |gem_file|
|
|
325
|
+
File.join(stage_path, gem_file)
|
|
326
|
+
end
|
|
327
|
+
file pkg.package_dir_path => stage_files do
|
|
328
|
+
mkdir_p pkg.package_dir rescue nil
|
|
329
|
+
spec.files.each do |ft|
|
|
330
|
+
fn = File.join(stage_path, ft)
|
|
331
|
+
f = File.join(pkg.package_dir_path, ft)
|
|
332
|
+
fdir = File.dirname(f)
|
|
333
|
+
mkdir_p(fdir) if !File.exist?(fdir)
|
|
334
|
+
if File.directory?(fn)
|
|
335
|
+
mkdir_p(f)
|
|
336
|
+
else
|
|
337
|
+
rm_f f
|
|
338
|
+
safe_ln(fn, f)
|
|
339
|
+
end
|
|
340
|
+
end
|
|
341
|
+
end
|
|
342
|
+
end
|
|
343
|
+
end
|
|
344
|
+
|
|
345
|
+
# add binaries to the dependency chain
|
|
346
|
+
task "native:#{@gem_spec.name}:#{platf}" => ["#{stage_path}/#{lib_binary_path}"]
|
|
347
|
+
|
|
348
|
+
# ensure the extension get copied
|
|
349
|
+
unless Rake::Task.task_defined?(lib_binary_path) then
|
|
350
|
+
file lib_binary_path => ["copy:#{@name}:#{platf}:#{ruby_ver}"]
|
|
351
|
+
end
|
|
352
|
+
file "#{stage_path}/#{lib_binary_path}" => ["copy:#{@name}:#{platf}:#{ruby_ver}"]
|
|
353
|
+
|
|
354
|
+
# Allow segmented packaging by platform (open door for 'cross compile')
|
|
355
|
+
task "native:#{platf}" => ["native:#{@gem_spec.name}:#{platf}"]
|
|
356
|
+
|
|
357
|
+
# Only add this extension to the compile chain if current
|
|
358
|
+
# platform matches the indicated one.
|
|
359
|
+
if platf == RUBY_PLATFORM then
|
|
360
|
+
task "native:#{@gem_spec.name}" => ["native:#{@gem_spec.name}:#{platf}"]
|
|
361
|
+
task "native" => ["native:#{platf}"]
|
|
362
|
+
end
|
|
363
|
+
end
|
|
364
|
+
|
|
365
|
+
def define_cross_platform_tasks(for_platform)
|
|
366
|
+
if ruby_vers = ENV['RUBY_CC_VERSION']
|
|
367
|
+
ruby_vers = ENV['RUBY_CC_VERSION'].split(':')
|
|
368
|
+
else
|
|
369
|
+
ruby_vers = [RUBY_VERSION]
|
|
370
|
+
end
|
|
371
|
+
|
|
372
|
+
multi = (ruby_vers.size > 1) ? true : false
|
|
373
|
+
|
|
374
|
+
ruby_vers.each do |version|
|
|
375
|
+
# save original lib_dir
|
|
376
|
+
orig_lib_dir = @lib_dir
|
|
377
|
+
|
|
378
|
+
# tweak lib directory only when targeting multiple versions
|
|
379
|
+
if multi then
|
|
380
|
+
version =~ /(\d+\.\d+)/
|
|
381
|
+
@lib_dir = "#{@lib_dir}/#{$1}"
|
|
382
|
+
end
|
|
383
|
+
|
|
384
|
+
define_cross_platform_tasks_with_version(for_platform, version)
|
|
385
|
+
|
|
386
|
+
# restore lib_dir
|
|
387
|
+
@lib_dir = orig_lib_dir
|
|
388
|
+
end
|
|
389
|
+
end
|
|
390
|
+
|
|
391
|
+
def define_cross_platform_tasks_with_version(for_platform, ruby_ver)
|
|
392
|
+
config_path = File.expand_path("~/.rake-compiler/config.yml")
|
|
393
|
+
|
|
394
|
+
# warn the user about the need of configuration to use cross compilation.
|
|
395
|
+
unless File.exist?(config_path)
|
|
396
|
+
define_dummy_cross_platform_tasks
|
|
397
|
+
return
|
|
398
|
+
end
|
|
399
|
+
|
|
400
|
+
rbconfig_file = Rake::CompilerConfig.new(config_path).find(ruby_ver, for_platform)
|
|
401
|
+
unless rbconfig_file
|
|
402
|
+
warn "no configuration section for specified version of Ruby (rbconfig-#{for_platform}-#{ruby_ver})"
|
|
403
|
+
return
|
|
404
|
+
end
|
|
405
|
+
|
|
406
|
+
# tmp_path
|
|
407
|
+
tmp_path = "#{@tmp_dir}/#{for_platform}/#{@name}/#{ruby_ver}"
|
|
408
|
+
|
|
409
|
+
# lib_path
|
|
410
|
+
lib_path = lib_dir
|
|
411
|
+
|
|
412
|
+
# lib_binary_path
|
|
413
|
+
lib_binary_path = "#{lib_path}/#{File.basename(binary(for_platform))}"
|
|
414
|
+
|
|
415
|
+
# mkmf
|
|
416
|
+
mkmf_file = File.expand_path(File.join(File.dirname(rbconfig_file), '..', 'mkmf.rb'))
|
|
417
|
+
|
|
418
|
+
# define compilation tasks for cross platform!
|
|
419
|
+
define_compile_tasks(for_platform, ruby_ver)
|
|
420
|
+
|
|
421
|
+
# chain fake.rb and mkmf.rb to Makefile generation
|
|
422
|
+
file "#{tmp_path}/Makefile" => ["#{tmp_path}/fake.rb",
|
|
423
|
+
"#{tmp_path}/mkmf.rb"]
|
|
424
|
+
|
|
425
|
+
# copy the rbconfig from the cross-ruby location and
|
|
426
|
+
# genearte fake.rb for different ruby versions
|
|
427
|
+
file "#{tmp_path}/fake.rb" => [rbconfig_file] do |t|
|
|
428
|
+
File.open(t.name, 'w') do |f|
|
|
429
|
+
# Keep the original RbConfig::CONFIG["ENABLE_SHARED"] to use
|
|
430
|
+
# the same RubyGems extension directory. See also
|
|
431
|
+
# Gem::BasicSpecificaion#extenions_dir and
|
|
432
|
+
# Gem.extension_api_version.
|
|
433
|
+
#
|
|
434
|
+
# if RbConfig::CONFIG["ENABLE_SHARED"] == "no"
|
|
435
|
+
# "extensions/x86_64-linux/2.5.0-static"
|
|
436
|
+
# else
|
|
437
|
+
# "extensions/x86_64-linux/2.5.0"
|
|
438
|
+
# end
|
|
439
|
+
f.puts("require 'rbconfig'")
|
|
440
|
+
f.puts("original_enable_shared = RbConfig::CONFIG['ENABLE_SHARED']")
|
|
441
|
+
f.puts(fake_rb(for_platform, ruby_ver))
|
|
442
|
+
f.puts("require #{t.prerequisites.first.dump}")
|
|
443
|
+
f.puts("RbConfig::CONFIG['ENABLE_SHARED'] = original_enable_shared")
|
|
444
|
+
end
|
|
445
|
+
end
|
|
446
|
+
|
|
447
|
+
# copy mkmf from cross-ruby location
|
|
448
|
+
file "#{tmp_path}/mkmf.rb" => [mkmf_file] do |t|
|
|
449
|
+
File.open(t.name, 'w') do |f|
|
|
450
|
+
content = File.read(t.prerequisites.first)
|
|
451
|
+
content.sub!(/^(require ')rbconfig(')$/, '\\1fake\\2')
|
|
452
|
+
if ruby_ver < "1.9" && "1.9" <= RUBY_VERSION
|
|
453
|
+
content.sub!(/^( break )\*(defaults)$/, '\\1\\2.first')
|
|
454
|
+
content.sub!(/^( return )\*(defaults)$/, '\\1\\2.first')
|
|
455
|
+
content.sub!(/^( mfile\.)print( configuration\(srcprefix\))$/, '\\1puts\\2')
|
|
456
|
+
end
|
|
457
|
+
f.write content
|
|
458
|
+
end
|
|
459
|
+
end
|
|
460
|
+
|
|
461
|
+
# now define native tasks for cross compiled files
|
|
462
|
+
if @gem_spec && @gem_spec.platform == 'ruby' then
|
|
463
|
+
define_native_tasks(for_platform, ruby_ver, @cross_compiling)
|
|
464
|
+
end
|
|
465
|
+
|
|
466
|
+
# create cross task
|
|
467
|
+
task 'cross' do
|
|
468
|
+
# clear compile dependencies
|
|
469
|
+
Rake::Task['compile'].prerequisites.reject! { |t| !compiles_cross_platform.include?(t) }
|
|
470
|
+
|
|
471
|
+
# chain the cross platform ones
|
|
472
|
+
task 'compile' => ["compile:#{for_platform}"]
|
|
473
|
+
|
|
474
|
+
# clear lib/binary dependencies and trigger cross platform ones
|
|
475
|
+
# check if lib/binary is defined (damn bundle versus so versus dll)
|
|
476
|
+
if Rake::Task.task_defined?(lib_binary_path) then
|
|
477
|
+
Rake::Task[lib_binary_path].prerequisites.clear
|
|
478
|
+
end
|
|
479
|
+
|
|
480
|
+
# FIXME: targeting multiple platforms copies the file twice
|
|
481
|
+
file lib_binary_path => ["copy:#{@name}:#{for_platform}:#{ruby_ver}"]
|
|
482
|
+
|
|
483
|
+
# if everything for native task is in place
|
|
484
|
+
if @gem_spec && @gem_spec.platform == 'ruby' then
|
|
485
|
+
# double check: only cross platform native tasks should be here
|
|
486
|
+
# FIXME: Sooo brittle
|
|
487
|
+
Rake::Task['native'].prerequisites.reject! { |t| !natives_cross_platform.include?(t) }
|
|
488
|
+
task 'native' => ["native:#{for_platform}"]
|
|
489
|
+
end
|
|
490
|
+
end
|
|
491
|
+
end
|
|
492
|
+
|
|
493
|
+
def define_dummy_cross_platform_tasks
|
|
494
|
+
task 'cross' do
|
|
495
|
+
Rake::Task['compile'].clear
|
|
496
|
+
task 'compile' do
|
|
497
|
+
raise "rake-compiler must be configured first to enable cross-compilation"
|
|
498
|
+
end
|
|
499
|
+
end
|
|
500
|
+
end
|
|
501
|
+
|
|
502
|
+
def extconf
|
|
503
|
+
"#{@ext_dir}/#{@config_script}"
|
|
504
|
+
end
|
|
505
|
+
|
|
506
|
+
def make
|
|
507
|
+
unless @make
|
|
508
|
+
@make =
|
|
509
|
+
if RUBY_PLATFORM =~ /mswin/ then
|
|
510
|
+
'nmake'
|
|
511
|
+
else
|
|
512
|
+
ENV['MAKE'] || find_make
|
|
513
|
+
end
|
|
514
|
+
end
|
|
515
|
+
|
|
516
|
+
unless @make
|
|
517
|
+
raise "Couldn't find a suitable `make` tool. Use `MAKE` env to set an alternative."
|
|
518
|
+
end
|
|
519
|
+
|
|
520
|
+
@make
|
|
521
|
+
end
|
|
522
|
+
|
|
523
|
+
def find_make
|
|
524
|
+
candidates = ["gmake", "make"]
|
|
525
|
+
paths = (ENV["PATH"] || "").split(File::PATH_SEPARATOR)
|
|
526
|
+
paths = paths.collect do |path|
|
|
527
|
+
Pathname(path).cleanpath
|
|
528
|
+
end
|
|
529
|
+
|
|
530
|
+
exeext = RbConfig::CONFIG["EXEEXT"]
|
|
531
|
+
candidates.each do |candidate|
|
|
532
|
+
paths.each do |path|
|
|
533
|
+
make = path + "#{candidate}#{exeext}"
|
|
534
|
+
return make.to_s if make.executable?
|
|
535
|
+
end
|
|
536
|
+
end
|
|
537
|
+
|
|
538
|
+
nil
|
|
539
|
+
end
|
|
540
|
+
|
|
541
|
+
def compiled_files
|
|
542
|
+
FileList["#{@ext_dir}/#{@compiled_pattern}"]
|
|
543
|
+
end
|
|
544
|
+
|
|
545
|
+
def compiles_cross_platform
|
|
546
|
+
[*@cross_platform].map { |p| "compile:#{p}" }
|
|
547
|
+
end
|
|
548
|
+
|
|
549
|
+
def natives_cross_platform
|
|
550
|
+
[*@cross_platform].map { |p| "native:#{p}" }
|
|
551
|
+
end
|
|
552
|
+
|
|
553
|
+
def ruby_api_version(ruby_version)
|
|
554
|
+
ruby_version.split(".")[0, 2].join(".")
|
|
555
|
+
end
|
|
556
|
+
|
|
557
|
+
def fake_rb(platform, version)
|
|
558
|
+
<<-FAKE_RB
|
|
559
|
+
# Pre-load resolver library before faking, in order to avoid error
|
|
560
|
+
# "cannot load such file -- win32/resolv" when it is required later on.
|
|
561
|
+
# See also: https://github.com/tjschuck/rake-compiler-dev-box/issues/5
|
|
562
|
+
require 'resolv'
|
|
563
|
+
require 'rbconfig'
|
|
564
|
+
|
|
565
|
+
class Object
|
|
566
|
+
remove_const :RbConfig
|
|
567
|
+
remove_const :RUBY_PLATFORM
|
|
568
|
+
remove_const :RUBY_VERSION
|
|
569
|
+
remove_const :RUBY_DESCRIPTION if defined?(RUBY_DESCRIPTION)
|
|
570
|
+
RUBY_PLATFORM = "#{platform}"
|
|
571
|
+
RUBY_VERSION = "#{version}"
|
|
572
|
+
RUBY_DESCRIPTION = "ruby \#{RUBY_VERSION} (\#{RUBY_RELEASE_DATE}) [\#{RUBY_PLATFORM}]"
|
|
573
|
+
end
|
|
574
|
+
if RUBY_PLATFORM =~ /mswin|bccwin|mingw/
|
|
575
|
+
class File
|
|
576
|
+
remove_const :ALT_SEPARATOR
|
|
577
|
+
ALT_SEPARATOR = "\\\\"
|
|
578
|
+
end
|
|
579
|
+
end
|
|
580
|
+
|
|
581
|
+
posthook = proc do
|
|
582
|
+
$ruby = "#{Gem.ruby}"
|
|
583
|
+
untrace_var(:$ruby, posthook)
|
|
584
|
+
end
|
|
585
|
+
trace_var(:$ruby, posthook)
|
|
586
|
+
FAKE_RB
|
|
587
|
+
end
|
|
588
|
+
end
|
|
589
|
+
end
|