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,182 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
|
2
|
+
|
3
|
+
require 'rake/javaextensiontask'
|
4
|
+
require 'rbconfig'
|
5
|
+
|
6
|
+
describe Rake::JavaExtensionTask do
|
7
|
+
context '#new' do
|
8
|
+
context '(basic)' do
|
9
|
+
it 'should raise an error if no name is provided' do
|
10
|
+
lambda {
|
11
|
+
Rake::JavaExtensionTask.new
|
12
|
+
}.should raise_error(RuntimeError, /Extension name must be provided/)
|
13
|
+
end
|
14
|
+
|
15
|
+
it 'should allow string as extension name assignation' do
|
16
|
+
ext = Rake::JavaExtensionTask.new('extension_one')
|
17
|
+
ext.name.should == 'extension_one'
|
18
|
+
end
|
19
|
+
|
20
|
+
it 'should allow string as extension name using block assignation' do
|
21
|
+
ext = Rake::JavaExtensionTask.new do |ext|
|
22
|
+
ext.name = 'extension_two'
|
23
|
+
end
|
24
|
+
ext.name.should == 'extension_two'
|
25
|
+
end
|
26
|
+
|
27
|
+
it 'should return itself for the block' do
|
28
|
+
from_block = nil
|
29
|
+
from_lasgn = Rake::JavaExtensionTask.new('extension_three') do |ext|
|
30
|
+
from_block = ext
|
31
|
+
end
|
32
|
+
from_block.should == from_lasgn
|
33
|
+
end
|
34
|
+
|
35
|
+
it 'should accept a gem specification as parameter' do
|
36
|
+
spec = mock_gem_spec
|
37
|
+
ext = Rake::JavaExtensionTask.new('extension_three', spec)
|
38
|
+
ext.gem_spec.should == spec
|
39
|
+
end
|
40
|
+
|
41
|
+
it 'should allow gem specification be defined using block assignation' do
|
42
|
+
spec = mock_gem_spec
|
43
|
+
ext = Rake::JavaExtensionTask.new('extension_four') do |ext|
|
44
|
+
ext.gem_spec = spec
|
45
|
+
end
|
46
|
+
ext.gem_spec.should == spec
|
47
|
+
end
|
48
|
+
|
49
|
+
it 'should allow forcing of platform' do
|
50
|
+
ext = Rake::JavaExtensionTask.new('weird_extension') do |ext|
|
51
|
+
ext.platform = 'java-128bit'
|
52
|
+
end
|
53
|
+
ext.platform.should == 'java-128bit'
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
context '(defaults)' do
|
59
|
+
before :each do
|
60
|
+
@ext = Rake::JavaExtensionTask.new('extension_one')
|
61
|
+
end
|
62
|
+
|
63
|
+
it 'should dump intermediate files to tmp/' do
|
64
|
+
@ext.tmp_dir.should == 'tmp'
|
65
|
+
end
|
66
|
+
|
67
|
+
it 'should copy build extension into lib/' do
|
68
|
+
@ext.lib_dir.should == 'lib'
|
69
|
+
end
|
70
|
+
|
71
|
+
it 'should look for Java files pattern (.java)' do
|
72
|
+
@ext.source_pattern.should == "**/*.java"
|
73
|
+
end
|
74
|
+
|
75
|
+
it 'should have no configuration options preset to delegate' do
|
76
|
+
@ext.config_options.should be_empty
|
77
|
+
end
|
78
|
+
|
79
|
+
it 'should default to Java platform' do
|
80
|
+
@ext.platform.should == 'java'
|
81
|
+
end
|
82
|
+
|
83
|
+
context '(tasks)' do
|
84
|
+
before :each do
|
85
|
+
Rake.application.clear
|
86
|
+
CLEAN.clear
|
87
|
+
CLOBBER.clear
|
88
|
+
end
|
89
|
+
|
90
|
+
context '(one extension)' do
|
91
|
+
before :each do
|
92
|
+
Rake::FileList.stub!(:[]).and_return(["ext/extension_one/source.java"])
|
93
|
+
@ext = Rake::JavaExtensionTask.new('extension_one')
|
94
|
+
@ext_bin = ext_bin('extension_one')
|
95
|
+
@platform = 'java'
|
96
|
+
end
|
97
|
+
|
98
|
+
context 'compile' do
|
99
|
+
it 'should define as task' do
|
100
|
+
Rake::Task.task_defined?('compile').should be_true
|
101
|
+
end
|
102
|
+
|
103
|
+
it "should depend on 'compile:{platform}'" do
|
104
|
+
pending 'needs fixing'
|
105
|
+
Rake::Task['compile'].prerequisites.should include("compile:#{@platform}")
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
context 'compile:extension_one' do
|
110
|
+
it 'should define as task' do
|
111
|
+
Rake::Task.task_defined?('compile:extension_one').should be_true
|
112
|
+
end
|
113
|
+
|
114
|
+
it "should depend on 'compile:extension_one:{platform}'" do
|
115
|
+
pending 'needs fixing'
|
116
|
+
Rake::Task['compile:extension_one'].prerequisites.should include("compile:extension_one:#{@platform}")
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
context 'lib/extension_one.jar' do
|
121
|
+
it 'should define as task' do
|
122
|
+
pending 'needs fixing'
|
123
|
+
Rake::Task.task_defined?("lib/#{@ext_bin}").should be_true
|
124
|
+
end
|
125
|
+
|
126
|
+
it "should depend on 'copy:extension_one:{platform}'" do
|
127
|
+
pending 'needs fixing'
|
128
|
+
Rake::Task["lib/#{@ext_bin}"].prerequisites.should include("copy:extension_one:#{@platform}")
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
context 'tmp/{platform}/extension_one/extension_one.jar' do
|
133
|
+
it 'should define as task' do
|
134
|
+
Rake::Task.task_defined?("tmp/#{@platform}/extension_one/#{@ext_bin}").should be_true
|
135
|
+
end
|
136
|
+
|
137
|
+
it "should depend on checkpoint file" do
|
138
|
+
Rake::Task["tmp/#{@platform}/extension_one/#{@ext_bin}"].prerequisites.should include("tmp/#{@platform}/extension_one/.build")
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
context 'tmp/{platform}/extension_one/.build' do
|
143
|
+
it 'should define as task' do
|
144
|
+
Rake::Task.task_defined?("tmp/#{@platform}/extension_one/.build").should be_true
|
145
|
+
end
|
146
|
+
|
147
|
+
it 'should depend on source files' do
|
148
|
+
Rake::Task["tmp/#{@platform}/extension_one/.build"].prerequisites.should include("ext/extension_one/source.java")
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
context 'clean' do
|
153
|
+
it "should include 'tmp/{platform}/extension_one' in the pattern" do
|
154
|
+
CLEAN.should include("tmp/#{@platform}/extension_one")
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
context 'clobber' do
|
159
|
+
it "should include 'lib/extension_one.jar'" do
|
160
|
+
CLOBBER.should include("lib/#{@ext_bin}")
|
161
|
+
end
|
162
|
+
|
163
|
+
it "should include 'tmp'" do
|
164
|
+
CLOBBER.should include('tmp')
|
165
|
+
end
|
166
|
+
end
|
167
|
+
end
|
168
|
+
end
|
169
|
+
end
|
170
|
+
private
|
171
|
+
|
172
|
+
def ext_bin(extension_name)
|
173
|
+
"#{extension_name}.jar"
|
174
|
+
end
|
175
|
+
|
176
|
+
def mock_gem_spec(stubs = {})
|
177
|
+
mock(Gem::Specification,
|
178
|
+
{ :name => 'my_gem', :platform => 'ruby' }.merge(stubs)
|
179
|
+
)
|
180
|
+
end
|
181
|
+
|
182
|
+
end
|
data/spec/spec.opts
ADDED
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'rspec'
|
2
|
+
|
3
|
+
# Console redirection helper
|
4
|
+
require File.expand_path('../support/capture_output_helper', __FILE__)
|
5
|
+
|
6
|
+
RSpec.configure do |config|
|
7
|
+
config.include CaptureOutputHelper
|
8
|
+
end
|
9
|
+
|
10
|
+
# Rake::Task matcher helper
|
11
|
+
RSpec::Matchers.define :have_defined do |task|
|
12
|
+
match do |tasks|
|
13
|
+
tasks.task_defined?(task)
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module CaptureOutputHelper
|
2
|
+
def capture_output(&block)
|
3
|
+
old_stdout = $stdout
|
4
|
+
old_stderr = $stderr
|
5
|
+
|
6
|
+
stream_out = StringIO.new
|
7
|
+
stream_err = StringIO.new
|
8
|
+
|
9
|
+
begin
|
10
|
+
$stdout = stream_out
|
11
|
+
$stderr = stream_err
|
12
|
+
yield
|
13
|
+
ensure
|
14
|
+
$stdout = old_stdout
|
15
|
+
$stderr = old_stderr
|
16
|
+
end
|
17
|
+
stream_out.rewind
|
18
|
+
stream_err.rewind
|
19
|
+
|
20
|
+
[stream_out.read, stream_err.read]
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,213 @@
|
|
1
|
+
#--
|
2
|
+
# Cross-compile ruby, using Rake
|
3
|
+
#
|
4
|
+
# This source code is released under the MIT License.
|
5
|
+
# See LICENSE file for details
|
6
|
+
#++
|
7
|
+
|
8
|
+
#
|
9
|
+
# This code is inspired and based on notes from the following sites:
|
10
|
+
#
|
11
|
+
# http://tenderlovemaking.com/2008/11/21/cross-compiling-ruby-gems-for-win32/
|
12
|
+
# http://github.com/jbarnette/johnson/tree/master/cross-compile.txt
|
13
|
+
# http://eigenclass.org/hiki/cross+compiling+rcovrt
|
14
|
+
#
|
15
|
+
# This recipe only cleanup the dependency chain and automate it.
|
16
|
+
# Also opens the door to usage different ruby versions
|
17
|
+
# for cross-compilation.
|
18
|
+
#
|
19
|
+
|
20
|
+
abort <<-EOT if RUBY_PLATFORM =~ /mingw|mswin/
|
21
|
+
This tool is meant to be executed under Linux or OSX, not Windows.
|
22
|
+
It is used for cross-compilation only.
|
23
|
+
EOT
|
24
|
+
|
25
|
+
require 'rake'
|
26
|
+
require 'rake/clean'
|
27
|
+
|
28
|
+
require 'rbconfig'
|
29
|
+
require 'safe_yaml/load'
|
30
|
+
|
31
|
+
ruby_src = ENV['SRC']
|
32
|
+
ruby_svn = ENV['SVN']
|
33
|
+
|
34
|
+
make_command = ENV.fetch('MAKE') {
|
35
|
+
require 'nuggets/file/which'
|
36
|
+
File.which_command(%w[gmake make])
|
37
|
+
}
|
38
|
+
|
39
|
+
mingw_host = ENV.fetch('HOST') {
|
40
|
+
require 'rake/extensioncompiler'
|
41
|
+
Rake::ExtensionCompiler.mingw_host
|
42
|
+
}
|
43
|
+
|
44
|
+
version_name = 'ruby-%s' % ENV.fetch('VERSION') {
|
45
|
+
'%s-p%s' % [RUBY_VERSION, RUBY_PATCHLEVEL]
|
46
|
+
}
|
47
|
+
|
48
|
+
# Grab the major "1.8" or "1.9" part of the version number
|
49
|
+
version_major = version_name[/.*-(\d\.\d)\.\d/, 1]
|
50
|
+
|
51
|
+
download_url = "http://cache.ruby-lang.org/pub/ruby/#{version_major}"
|
52
|
+
svn_repo_url = 'http://svn.ruby-lang.org/repos/ruby'
|
53
|
+
|
54
|
+
base_directory = File.expand_path('~/.rake-compiler')
|
55
|
+
config_file = File.join(base_directory, 'config.yml')
|
56
|
+
|
57
|
+
sources_directory = File.join(base_directory, 'sources')
|
58
|
+
builds_directory = File.join(base_directory, 'builds')
|
59
|
+
targets_directory = File.join(base_directory, 'ruby')
|
60
|
+
|
61
|
+
source_directory = File.join(sources_directory, version_name)
|
62
|
+
build_directory = File.join(builds_directory, mingw_host, version_name)
|
63
|
+
target_directory = File.join(targets_directory, mingw_host, version_name)
|
64
|
+
|
65
|
+
tarball_file = !ruby_src ? source_directory + '.tar.bz2' :
|
66
|
+
File.join(sources_directory, File.basename(ruby_src))
|
67
|
+
|
68
|
+
makefile_file = File.join(build_directory, 'Makefile')
|
69
|
+
makefile_in_file = File.join(source_directory, 'Makefile.in')
|
70
|
+
makefile_in_bak_file = makefile_in_file + '.bak'
|
71
|
+
|
72
|
+
build_ruby_exe_file = File.join(build_directory, 'ruby.exe')
|
73
|
+
target_ruby_exe_file = File.join(target_directory, 'bin', 'ruby.exe')
|
74
|
+
|
75
|
+
# Unset any possible variable that might affect compilation
|
76
|
+
%w[CC CXX CPPFLAGS LDFLAGS RUBYOPT].each { |k| ENV.delete(k) }
|
77
|
+
|
78
|
+
# Define a location where sources will be stored
|
79
|
+
directory source_directory
|
80
|
+
directory build_directory
|
81
|
+
|
82
|
+
# Clean intermediate files and folders
|
83
|
+
CLEAN.include(source_directory)
|
84
|
+
CLEAN.include(build_directory)
|
85
|
+
|
86
|
+
# Remove the final products and sources
|
87
|
+
CLOBBER.include(sources_directory)
|
88
|
+
CLOBBER.include(builds_directory)
|
89
|
+
CLOBBER.include(target_directory)
|
90
|
+
CLOBBER.include(config_file)
|
91
|
+
|
92
|
+
# Ruby source file should be stored here
|
93
|
+
file tarball_file => sources_directory do |t|
|
94
|
+
url = ruby_src || File.join(download_url, File.basename(t.name))
|
95
|
+
chdir(sources_directory) { sh "wget #{url} || curl -O #{url}" }
|
96
|
+
end
|
97
|
+
|
98
|
+
# Extract the sources
|
99
|
+
if ruby_svn
|
100
|
+
file source_directory => sources_directory do |t|
|
101
|
+
sh "svn export -q #{File.join(svn_repo_url, ruby_svn)} #{t.name}"
|
102
|
+
chdir(source_directory) { sh 'autoreconf' }
|
103
|
+
end
|
104
|
+
else
|
105
|
+
file source_directory => tarball_file do |t|
|
106
|
+
chdir(sources_directory) { sh "tar xf #{tarball_file}" }
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
# Backup makefile.in
|
111
|
+
file makefile_in_bak_file => source_directory do |t|
|
112
|
+
cp makefile_in_file, t.name
|
113
|
+
end
|
114
|
+
|
115
|
+
# Correct the makefile
|
116
|
+
file makefile_in_file => makefile_in_bak_file do |t|
|
117
|
+
out = ''
|
118
|
+
|
119
|
+
File.foreach(t.name) { |line|
|
120
|
+
line.sub!(/\A(\s*ALT_SEPARATOR =).*/, "\\1 \"\\\\\\\\\"; \\\n")
|
121
|
+
out << line
|
122
|
+
}
|
123
|
+
|
124
|
+
when_writing('Patching Makefile.in') { File.write(t.name, out) }
|
125
|
+
end
|
126
|
+
|
127
|
+
# Generate the makefile in a clean build location
|
128
|
+
file makefile_file => [build_directory, makefile_in_file] do |t|
|
129
|
+
options = %W[
|
130
|
+
--host=#{mingw_host}
|
131
|
+
--target=#{mingw_host.gsub('msvc', '')}
|
132
|
+
--build=#{RbConfig::CONFIG['host']}
|
133
|
+
--prefix=#{target_directory}
|
134
|
+
--enable-shared
|
135
|
+
--disable-install-doc
|
136
|
+
--without-tk
|
137
|
+
--without-tcl
|
138
|
+
]
|
139
|
+
|
140
|
+
# Force Winsock2 for Ruby 1.8, 1.9 defaults to it
|
141
|
+
options << '--with-winsock2' if version_major == '1.8'
|
142
|
+
|
143
|
+
chdir(build_directory) {
|
144
|
+
sh File.join(source_directory, 'configure'), *options
|
145
|
+
}
|
146
|
+
end
|
147
|
+
|
148
|
+
# Make
|
149
|
+
file build_ruby_exe_file => makefile_file do |t|
|
150
|
+
chdir(build_directory) { sh make_command }
|
151
|
+
end
|
152
|
+
|
153
|
+
# Make install
|
154
|
+
file target_ruby_exe_file => build_ruby_exe_file do |t|
|
155
|
+
chdir(build_directory) { sh "#{make_command} install" }
|
156
|
+
end
|
157
|
+
|
158
|
+
task :install => target_ruby_exe_file
|
159
|
+
|
160
|
+
task :mingw32 do
|
161
|
+
abort <<-EOT unless mingw_host
|
162
|
+
You need to install mingw32 cross compile functionality to be able to continue.
|
163
|
+
Please refer to your distribution/package manager documentation about installation.
|
164
|
+
EOT
|
165
|
+
end
|
166
|
+
|
167
|
+
desc 'Update rake-compiler list of installed Ruby versions'
|
168
|
+
task 'update-config' do
|
169
|
+
config = if File.exist?(config_file)
|
170
|
+
puts "Updating #{config_file}"
|
171
|
+
SafeYAML.load_file(config_file)
|
172
|
+
else
|
173
|
+
puts "Generating #{config_file}"
|
174
|
+
{}
|
175
|
+
end
|
176
|
+
|
177
|
+
Dir["#{targets_directory}/*/*/**/rbconfig.rb"].sort.each { |rbconfig|
|
178
|
+
if rbconfig =~ %r{.*-(\d.\d.\d).*/([-\w]+)/rbconfig}
|
179
|
+
version, platform = $1, $2
|
180
|
+
else
|
181
|
+
warn "Invalid pattern: #{rbconfig}"
|
182
|
+
next
|
183
|
+
end
|
184
|
+
|
185
|
+
platforms, key = [platform], "rbconfig-%s-#{version}"
|
186
|
+
|
187
|
+
# Fake alternate (binary compatible) i386-mswin32-60 platform
|
188
|
+
platforms << 'i386-mswin32-60' if platform == 'i386-mingw32'
|
189
|
+
|
190
|
+
platforms.each { |pf|
|
191
|
+
config[key % pf] = rbconfig
|
192
|
+
|
193
|
+
# Also store RubyGems-compatible version
|
194
|
+
config[key % Gem::Platform.new(pf)] = rbconfig
|
195
|
+
}
|
196
|
+
|
197
|
+
puts "Found Ruby version #{version} for platform #{platform} (#{rbconfig})"
|
198
|
+
}
|
199
|
+
|
200
|
+
when_writing("Saving changes into #{config_file}") {
|
201
|
+
File.open(config_file, 'w') { |f| YAML.dump(config, f) }
|
202
|
+
}
|
203
|
+
end
|
204
|
+
|
205
|
+
task :default do
|
206
|
+
# Force the display of the available tasks when no option is given
|
207
|
+
Rake.application.options.show_task_pattern = //
|
208
|
+
Rake.application.options.show_tasks = :tasks
|
209
|
+
Rake.application.display_tasks_and_comments
|
210
|
+
end
|
211
|
+
|
212
|
+
desc "Build #{version_name} suitable for cross-platform development."
|
213
|
+
task 'cross-ruby' => [:mingw32, :install, 'update-config']
|
@@ -0,0 +1,11 @@
|
|
1
|
+
desc 'Ensure all the cross compiled versions are installed'
|
2
|
+
task :bootstrap do
|
3
|
+
fail "Sorry, this only works on OSX and Linux" if RUBY_PLATFORM =~ /mswin|mingw/
|
4
|
+
|
5
|
+
versions = %w(1.8.7-p371 1.9.3-p392 2.0.0-p0)
|
6
|
+
|
7
|
+
versions.each do |version|
|
8
|
+
puts "[INFO] Attempt to cross-compile Ruby #{version}"
|
9
|
+
ruby "-Ilib bin/rake-compiler cross-ruby VERSION=#{version}"
|
10
|
+
end
|
11
|
+
end
|