rake-compiler-sgonyea 0.8.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.
Files changed (43) hide show
  1. data/History.txt +254 -0
  2. data/Isolate +6 -0
  3. data/LICENSE.txt +20 -0
  4. data/README.rdoc +393 -0
  5. data/Rakefile +21 -0
  6. data/bin/rake-compiler +24 -0
  7. data/cucumber.yml +4 -0
  8. data/features/compile.feature +79 -0
  9. data/features/cross-compile.feature +22 -0
  10. data/features/cross-package-multi.feature +15 -0
  11. data/features/cross-package.feature +14 -0
  12. data/features/java-compile.feature +22 -0
  13. data/features/java-no-native-compile.feature +33 -0
  14. data/features/java-package.feature +24 -0
  15. data/features/package.feature +40 -0
  16. data/features/step_definitions/compilation.rb +70 -0
  17. data/features/step_definitions/cross_compilation.rb +25 -0
  18. data/features/step_definitions/execution.rb +52 -0
  19. data/features/step_definitions/folders.rb +32 -0
  20. data/features/step_definitions/gem.rb +46 -0
  21. data/features/step_definitions/java_compilation.rb +7 -0
  22. data/features/support/env.rb +6 -0
  23. data/features/support/file_template_helpers.rb +137 -0
  24. data/features/support/generator_helpers.rb +123 -0
  25. data/features/support/platform_extension_helpers.rb +27 -0
  26. data/lib/rake/baseextensiontask.rb +90 -0
  27. data/lib/rake/extensioncompiler.rb +53 -0
  28. data/lib/rake/extensiontask.rb +431 -0
  29. data/lib/rake/javaextensiontask.rb +226 -0
  30. data/spec/lib/rake/extensiontask_spec.rb +481 -0
  31. data/spec/lib/rake/javaextensiontask_spec.rb +182 -0
  32. data/spec/spec.opts +3 -0
  33. data/spec/spec_helper.rb +15 -0
  34. data/spec/support/capture_output_helper.rb +22 -0
  35. data/tasks/bin/cross-ruby.rake +196 -0
  36. data/tasks/bootstrap.rake +11 -0
  37. data/tasks/common.rake +10 -0
  38. data/tasks/cucumber.rake +23 -0
  39. data/tasks/gem.rake +53 -0
  40. data/tasks/news.rake +39 -0
  41. data/tasks/release.rake +26 -0
  42. data/tasks/rspec.rake +9 -0
  43. metadata +145 -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
@@ -0,0 +1,3 @@
1
+ --colour
2
+ --format nested
3
+ --loadby mtime
@@ -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,196 @@
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
+ require 'rake'
21
+ require 'rake/clean'
22
+
23
+ begin
24
+ require 'psych'
25
+ rescue LoadError
26
+ end
27
+
28
+ require 'yaml'
29
+ require "rbconfig"
30
+
31
+ # load compiler helpers
32
+ # add lib directory to the search path
33
+ libdir = File.expand_path(File.join(File.dirname(__FILE__), '..', '..', 'lib'))
34
+ $LOAD_PATH.unshift(libdir) unless $LOAD_PATH.include?(libdir)
35
+
36
+ if RUBY_PLATFORM =~ /mingw|mswin/ then
37
+ puts "This command is meant to be executed under Linux or OSX, not Windows (is for cross-compilation)"
38
+ exit(1)
39
+ end
40
+
41
+ require 'rake/extensioncompiler'
42
+
43
+ MAKE = ENV['MAKE'] || %w[gmake make].find { |c| system("#{c} -v > /dev/null 2>&1") }
44
+ USER_HOME = File.expand_path("~/.rake-compiler")
45
+ RUBY_CC_VERSION = "ruby-" << ENV.fetch("VERSION", "1.8.7-p334")
46
+ RUBY_SOURCE = ENV['SOURCE']
47
+ RUBY_BUILD = RbConfig::CONFIG["host"]
48
+
49
+ # grab the major "1.8" or "1.9" part of the version number
50
+ MAJOR = RUBY_CC_VERSION.match(/.*-(\d.\d).\d/)[1]
51
+
52
+ # Use Rake::ExtensionCompiler helpers to find the proper host
53
+ MINGW_HOST = ENV['HOST'] || Rake::ExtensionCompiler.mingw_host
54
+ MINGW_TARGET = MINGW_HOST.gsub('msvc', '')
55
+
56
+ # define a location where sources will be stored
57
+ directory "#{USER_HOME}/sources/#{RUBY_CC_VERSION}"
58
+ directory "#{USER_HOME}/builds/#{RUBY_CC_VERSION}"
59
+
60
+ # clean intermediate files and folders
61
+ CLEAN.include("#{USER_HOME}/sources/#{RUBY_CC_VERSION}")
62
+ CLEAN.include("#{USER_HOME}/builds/#{RUBY_CC_VERSION}")
63
+
64
+ # remove the final products and sources
65
+ CLOBBER.include("#{USER_HOME}/sources")
66
+ CLOBBER.include("#{USER_HOME}/builds")
67
+ CLOBBER.include("#{USER_HOME}/ruby/#{RUBY_CC_VERSION}")
68
+ CLOBBER.include("#{USER_HOME}/config.yml")
69
+
70
+ # ruby source file should be stored there
71
+ file "#{USER_HOME}/sources/#{RUBY_CC_VERSION}.tar.bz2" => ["#{USER_HOME}/sources"] do |t|
72
+ # download the source file using wget or curl
73
+ chdir File.dirname(t.name) do
74
+ if RUBY_SOURCE
75
+ url = RUBY_SOURCE
76
+ else
77
+ url = "http://ftp.ruby-lang.org/pub/ruby/#{MAJOR}/#{File.basename(t.name)}"
78
+ end
79
+ sh "wget #{url} || curl -O #{url}"
80
+ end
81
+ end
82
+
83
+ # Extract the sources
84
+ source_file = RUBY_SOURCE ? RUBY_SOURCE.split('/').last : "#{RUBY_CC_VERSION}.tar.bz2"
85
+ file "#{USER_HOME}/sources/#{RUBY_CC_VERSION}" => ["#{USER_HOME}/sources/#{source_file}"] do |t|
86
+ chdir File.dirname(t.name) do
87
+ t.prerequisites.each { |f| sh "tar xf #{File.basename(f)}" }
88
+ end
89
+ end
90
+
91
+ # backup makefile.in
92
+ file "#{USER_HOME}/sources/#{RUBY_CC_VERSION}/Makefile.in.bak" => ["#{USER_HOME}/sources/#{RUBY_CC_VERSION}"] do |t|
93
+ cp "#{USER_HOME}/sources/#{RUBY_CC_VERSION}/Makefile.in", t.name
94
+ end
95
+
96
+ # correct the makefiles
97
+ file "#{USER_HOME}/sources/#{RUBY_CC_VERSION}/Makefile.in" => ["#{USER_HOME}/sources/#{RUBY_CC_VERSION}/Makefile.in.bak"] do |t|
98
+ content = File.open(t.name, 'rb') { |f| f.read }
99
+
100
+ out = ""
101
+
102
+ content.each_line do |line|
103
+ if line =~ /^\s*ALT_SEPARATOR =/
104
+ out << "\t\t ALT_SEPARATOR = \"\\\\\\\\\"; \\\n"
105
+ else
106
+ out << line
107
+ end
108
+ end
109
+
110
+ when_writing("Patching Makefile.in") {
111
+ File.open(t.name, 'wb') { |f| f.write(out) }
112
+ }
113
+ end
114
+
115
+ task :mingw32 do
116
+ unless MINGW_HOST then
117
+ warn "You need to install mingw32 cross compile functionality to be able to continue."
118
+ warn "Please refer to your distribution/package manager documentation about installation."
119
+ fail
120
+ end
121
+ end
122
+
123
+ # generate the makefile in a clean build location
124
+ file "#{USER_HOME}/builds/#{RUBY_CC_VERSION}/Makefile" => ["#{USER_HOME}/builds/#{RUBY_CC_VERSION}",
125
+ "#{USER_HOME}/sources/#{RUBY_CC_VERSION}/Makefile.in"] do |t|
126
+
127
+ options = [
128
+ "--host=#{MINGW_HOST}",
129
+ "--target=#{MINGW_TARGET}",
130
+ "--build=#{RUBY_BUILD}",
131
+ '--enable-shared',
132
+ '--disable-install-doc',
133
+ '--without-tk',
134
+ '--without-tcl'
135
+ ]
136
+
137
+ # Force Winsock2 for Ruby 1.8, 1.9 defaults to it
138
+ options << "--with-winsock2" if MAJOR == "1.8"
139
+
140
+ chdir File.dirname(t.name) do
141
+ prefix = File.expand_path("../../ruby/#{RUBY_CC_VERSION}")
142
+ options << "--prefix=#{prefix}"
143
+ sh File.expand_path("../../sources/#{RUBY_CC_VERSION}/configure"), *options
144
+ end
145
+ end
146
+
147
+ # make
148
+ file "#{USER_HOME}/builds/#{RUBY_CC_VERSION}/ruby.exe" => ["#{USER_HOME}/builds/#{RUBY_CC_VERSION}/Makefile"] do |t|
149
+ chdir File.dirname(t.prerequisites.first) do
150
+ sh MAKE
151
+ end
152
+ end
153
+
154
+ # make install
155
+ file "#{USER_HOME}/ruby/#{RUBY_CC_VERSION}/bin/ruby.exe" => ["#{USER_HOME}/builds/#{RUBY_CC_VERSION}/ruby.exe"] do |t|
156
+ chdir File.dirname(t.prerequisites.first) do
157
+ sh "#{MAKE} install"
158
+ end
159
+ end
160
+ task :install => ["#{USER_HOME}/ruby/#{RUBY_CC_VERSION}/bin/ruby.exe"]
161
+
162
+ desc "Update rake-compiler list of installed Ruby versions"
163
+ task 'update-config' do
164
+ config_file = "#{USER_HOME}/config.yml"
165
+ if File.exist?(config_file) then
166
+ puts "Updating #{config_file}"
167
+ config = YAML.load_file(config_file)
168
+ else
169
+ puts "Generating #{config_file}"
170
+ config = {}
171
+ end
172
+
173
+ files = Dir.glob("#{USER_HOME}/ruby/*/**/rbconfig.rb").sort
174
+
175
+ files.each do |rbconfig|
176
+ version = rbconfig.match(/.*-(\d.\d.\d)/)[1]
177
+ config["rbconfig-#{version}"] = rbconfig
178
+ puts "Found Ruby version #{version} (#{rbconfig})"
179
+ end
180
+
181
+ when_writing("Saving changes into #{config_file}") {
182
+ File.open(config_file, 'w') do |f|
183
+ f.puts config.to_yaml
184
+ end
185
+ }
186
+ end
187
+
188
+ task :default do
189
+ # Force the display of the available tasks when no option is given
190
+ Rake.application.options.show_task_pattern = //
191
+ Rake.application.display_tasks_and_comments
192
+ end
193
+
194
+ desc "Build #{RUBY_CC_VERSION} suitable for cross-platform development."
195
+ task 'cross-ruby' => [:mingw32, :install, 'update-config']
196
+
@@ -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.6-p398 1.9.1-p243 1.9.2-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
@@ -0,0 +1,10 @@
1
+ require 'rake/clean'
2
+
3
+ # common pattern cleanup
4
+ CLOBBER.include('tmp')
5
+
6
+ # set default task
7
+ task :default => [:spec, :features]
8
+
9
+ # make packing depend on success of running specs and features
10
+ task :package => [:spec, :features]
@@ -0,0 +1,23 @@
1
+ begin
2
+ require 'cucumber/rake/task'
3
+ rescue LoadError
4
+ warn "Cucumber gem is required, please install it. (gem install cucumber)"
5
+ end
6
+
7
+ if defined?(Cucumber)
8
+ namespace :cucumber do
9
+ Cucumber::Rake::Task.new('default', 'Run features testing C extension support') do |t|
10
+ t.profile = 'default'
11
+ t.cucumber_opts = '--format pretty --no-source'
12
+ end
13
+ Cucumber::Rake::Task.new('java', 'Run features testing Java extension support') do |t|
14
+ t.profile = 'java'
15
+ t.cucumber_opts = '--format pretty --no-source'
16
+ end
17
+
18
+ desc 'Run all features'
19
+ task :all => [:default, :java]
20
+ end
21
+ desc 'Alias for cucumber:default'
22
+ task :cucumber => 'cucumber:default'
23
+ end