rake-compiler 0.5.0 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,3 +1,33 @@
1
+ === 0.6.x (in Git)
2
+
3
+ * Enhancements
4
+ * Implemented 'fat-binaries' generation for cross compiling
5
+ (for now). Thanks to Aaron Patterson for the suggestion and
6
+ original idea.
7
+
8
+ rake cross native gem RUBY_CC_VERSION=1.8.6:1.9.1
9
+
10
+ Will package extensions for 1.8 and 1.9 versions of Ruby.
11
+ * Can now cross compile extensions for 1.9 using 1.8.x as base.
12
+ Be warned: works from 1.8 to 1.9, but not if your default ruby is 1.9
13
+
14
+ rake cross compile RUBY_CC_VERSION=1.9.1
15
+
16
+ * Allow simultaneous versions of Ruby to compile extensions.
17
+ This change allow 1.8.x compiles co-exist with 1.9.x ones
18
+ and don't override each other.
19
+
20
+ Please perform <tt>rake clobber</tt> prior compiling again.
21
+ * Allow optional source file URL for cross-compile tasks.
22
+ (Thanks to deepj for the patches)
23
+
24
+ rake-compiler cross-ruby VERSION=1.9.1-p0 SOURCE=http://ftp.ruby-lang.org/pub/ruby/1.9/ruby-1.9.1-p0.tar.bz2
25
+
26
+ * Bugfixes
27
+ * Removed strict versioning for gems since it clash with fat binaries.
28
+ From now on, if your gem only targets a specific version of Ruby, please
29
+ indicate it in the Gem::Specification (<tt>required_ruby_version</tt>)
30
+
1
31
  === 0.5.0 / 2009-04-25
2
32
 
3
33
  * Enhancements
@@ -1,12 +1,12 @@
1
1
  = rake-compiler
2
2
 
3
3
  rake-compiler aims to help Gem developers while dealing with Ruby C
4
- extensions, simplifiying the code and reducing the duplication.
4
+ extensions, simplifying the code and reducing the duplication.
5
5
 
6
- It follows *convention over configuration* and set an standarized
6
+ It follows *convention over configuration* and set an standardized
7
7
  structure to build and package C extensions in your gems.
8
8
 
9
- This is the result of expriences dealing with several Gems that required
9
+ This is the result of experiences dealing with several Gems that required
10
10
  native extensions across platforms and different user configurations
11
11
  where details like portability and clarity of code were lacking.
12
12
 
@@ -160,7 +160,7 @@ personalize several settings for <tt>Rake::ExtensionTask</tt>:
160
160
 
161
161
  == Future is now: Cross compilation
162
162
 
163
- rake-compiler provides now an standarized way to generate, from Linux or OSX
163
+ rake-compiler provides now an standardized way to generate, from Linux or OSX
164
164
  both extensions and gem binaries for Windows!
165
165
 
166
166
  It takes advantages from GCC host/target to build binaries (for target) on
@@ -171,12 +171,12 @@ different OS (hosts).
171
171
  Besides having the development tool chain installed (GCC), you should install
172
172
  also <tt>mingw32</tt> cross compilation package.
173
173
 
174
- Dependending on your operating system distribution, a simple <tt>apt-get install mingw32</tt>
175
- will be enough.
174
+ This depends on your operating system distribution, a simple
175
+ <tt>apt-get install mingw32</tt> will be enough.
176
176
 
177
177
  Please check OSX documentation about installing mingw32 from macports.
178
178
 
179
- === I have my toolchain, now what?
179
+ === I have my tool-chain, now what?
180
180
 
181
181
  You need to build Ruby for Windows.
182
182
 
@@ -194,7 +194,7 @@ supply a <tt>VERSION</tt>:
194
194
 
195
195
  === Let's build some gems!
196
196
 
197
- Now, you only need to use additional options in your extension defintion:
197
+ Now, you only need to use additional options in your extension definition:
198
198
 
199
199
  Rake::ExtensionTask.new('my_extension', gem_spec) do |ext|
200
200
  ext.cross_compile = true # enable cross compilation (requires cross compile toolchain)
@@ -225,11 +225,26 @@ And you're done, yeah.
225
225
 
226
226
  You can specify against with version of Ruby you want to build the extension:
227
227
 
228
- rake cross compile RUBY_CC_VERSION=1.8
228
+ rake cross compile RUBY_CC_VERSION=1.8.6
229
229
 
230
230
  If you installed <tt>1.9.1</tt>, you can do:
231
231
 
232
- rake cross compile RUBY_CC_VERSION=1.9
232
+ rake cross compile RUBY_CC_VERSION=1.9.1
233
+
234
+ Even more, you can target multiple versions (ie. 1.8.6 and 1.9.1):
235
+
236
+ rake cross compile RUBY_CC_VERSION=1.8.6:1.9.1
237
+
238
+ And more exiting, bundle both binaries in one "fat" Gem:
239
+
240
+ rake cross native gem RUBY_CC_VERSION=1.8.6:1.9.1
241
+
242
+ That will place binaries for 1.8 and 1.9 versions of ruby inside <tt>lib_dir</tt>
243
+
244
+ lib/1.8/my_extension.so
245
+ lib/1.9/my_extension.so
246
+
247
+ Now is up to you to make your gem load the proper one ;-)
233
248
 
234
249
  == Future
235
250
 
@@ -11,3 +11,12 @@ Feature: Cross-compile C extensions
11
11
  When rake task 'cross compile' is invoked
12
12
  Then rake task 'cross compile' succeeded
13
13
  And binaries for platform 'i386-mingw32' get generated
14
+
15
+ Scenario: compile single extension to multiple versions
16
+ Given that all my source files are in place
17
+ And I'm running a POSIX operating system
18
+ And I've installed cross compile toolchain
19
+ When rake task 'cross compile RUBY_CC_VERSION=1.8.6:1.9.1' is invoked
20
+ Then rake task 'cross compile RUBY_CC_VERSION=1.8.6:1.9.1' succeeded
21
+ And binaries for platform 'i386-mingw32' version '1.8' get copied
22
+ And binaries for platform 'i386-mingw32' version '1.9' get copied
@@ -13,19 +13,20 @@ Given %r{^I've installed cross compile toolchain$} do
13
13
  File.exist? File.join(path, comp)
14
14
  end
15
15
  end
16
- raise "Cannot locate '#{compiler}' in the PATH." unless compiler
16
+ pending "Cannot locate suitable compiler in the PATH." unless compiler
17
17
  end
18
18
 
19
19
  Then /^binaries for platform '(.*)' get generated$/ do |platform|
20
- ext = case platform
21
- when /darwin/
22
- 'bundle'
23
- when /mingw|mswin|linux/
24
- 'so'
25
- else
26
- RbConfig::CONFIG['DLEXT']
27
- end
20
+ ext = binary_extension(platform)
28
21
 
29
22
  ext_for_platform = Dir.glob("tmp/#{platform}/**/*.#{ext}")
30
23
  ext_for_platform.should_not be_empty
31
24
  end
25
+
26
+ Then /^binaries for platform '(.*)' version '(.*)' get copied$/ do |platform, version|
27
+ lib_path = "lib/#{version}"
28
+ ext = binary_extension(platform)
29
+
30
+ ext_for_platform = Dir.glob("#{lib_path}/*.#{ext}")
31
+ ext_for_platform.should_not be_empty
32
+ end
@@ -28,5 +28,5 @@ Then /^'(.*)' folder do not exist$/ do |folder|
28
28
  end
29
29
 
30
30
  Then /^no left over from '(.*)' remains in '(.*)'$/ do |name, folder|
31
- Dir.glob("#{folder}/**/#{name}").should be_empty
31
+ Dir.glob("#{folder}/**/#{name}/#{RUBY_VERSION}").should be_empty
32
32
  end
@@ -0,0 +1,14 @@
1
+ module PlatformExtensionHelpers
2
+ def binary_extension(platform = RUBY_PLATFORM)
3
+ case platform
4
+ when /darwin/
5
+ 'bundle'
6
+ when /mingw|mswin|linux/
7
+ 'so'
8
+ else
9
+ RbConfig::CONFIG['DLEXT']
10
+ end
11
+ end
12
+ end
13
+
14
+ World(PlatformExtensionHelpers)
@@ -72,16 +72,19 @@ module Rake
72
72
  end
73
73
 
74
74
  private
75
- def define_compile_tasks(for_platform = nil)
75
+ def define_compile_tasks(for_platform = nil, ruby_ver = RUBY_VERSION)
76
76
  # platform usage
77
77
  platf = for_platform || platform
78
78
 
79
+ # lib_path
80
+ lib_path = lib_dir
81
+
79
82
  # tmp_path
80
- tmp_path = "#{@tmp_dir}/#{platf}/#{@name}"
83
+ tmp_path = "#{@tmp_dir}/#{platf}/#{@name}/#{ruby_ver}"
81
84
 
82
85
  # cleanup and clobbering
83
86
  CLEAN.include(tmp_path)
84
- CLOBBER.include("#{@lib_dir}/#{binary(platf)}")
87
+ CLOBBER.include("#{lib_path}/#{binary(platf)}")
85
88
  CLOBBER.include("#{@tmp_dir}")
86
89
 
87
90
  # directories we need
@@ -90,8 +93,8 @@ module Rake
90
93
 
91
94
  # copy binary from temporary location to final lib
92
95
  # tmp/extension_name/extension_name.{so,bundle} => lib/
93
- task "copy:#{@name}:#{platf}" => [lib_dir, "#{tmp_path}/#{binary(platf)}"] do
94
- cp "#{tmp_path}/#{binary(platf)}", "#{@lib_dir}/#{binary(platf)}"
96
+ task "copy:#{@name}:#{platf}:#{ruby_ver}" => [lib_path, "#{tmp_path}/#{binary(platf)}"] do
97
+ cp "#{tmp_path}/#{binary(platf)}", "#{lib_path}/#{binary(platf)}"
95
98
  end
96
99
 
97
100
  # binary in temporary folder depends on makefile and source files
@@ -147,25 +150,28 @@ module Rake
147
150
  end
148
151
 
149
152
  # Allow segmented compilation by platform (open door for 'cross compile')
150
- task "compile:#{@name}:#{platf}" => ["copy:#{@name}:#{platf}"]
153
+ task "compile:#{@name}:#{platf}" => ["copy:#{@name}:#{platf}:#{ruby_ver}"]
151
154
  task "compile:#{platf}" => ["compile:#{@name}:#{platf}"]
152
155
 
153
156
  # Only add this extension to the compile chain if current
154
157
  # platform matches the indicated one.
155
158
  if platf == RUBY_PLATFORM then
156
159
  # ensure file is always copied
157
- file "#{@lib_dir}/#{binary(platf)}" => ["copy:#{name}:#{platf}"]
160
+ file "#{lib_path}/#{binary(platf)}" => ["copy:#{name}:#{platf}:#{ruby_ver}"]
158
161
 
159
162
  task "compile:#{@name}" => ["compile:#{@name}:#{platf}"]
160
163
  task "compile" => ["compile:#{platf}"]
161
164
  end
162
165
  end
163
166
 
164
- def define_native_tasks(for_platform = nil)
167
+ def define_native_tasks(for_platform = nil, ruby_ver = RUBY_VERSION)
165
168
  platf = for_platform || platform
166
169
 
167
170
  # tmp_path
168
- tmp_path = "#{@tmp_dir}/#{platf}/#{@name}"
171
+ tmp_path = "#{@tmp_dir}/#{platf}/#{@name}/#{ruby_ver}"
172
+
173
+ # lib_path
174
+ lib_path = lib_dir
169
175
 
170
176
  # create 'native:gem_name' and chain it to 'native' task
171
177
  unless Rake::Task.task_defined?("native:#{@gem_spec.name}:#{platf}")
@@ -181,36 +187,31 @@ module Rake
181
187
  spec.extensions.clear
182
188
 
183
189
  # add the binaries that this task depends on
184
- # ensure the files get properly copied to lib_dir
185
- ext_files = t.prerequisites.map { |ext| "#{@lib_dir}/#{File.basename(ext)}" }
186
- ext_files.each do |ext|
187
- unless Rake::Task.task_defined?("#{@lib_dir}/#{File.basename(ext)}") then
188
- # strip out path and .so/.bundle
189
- file "#{@lib_dir}/#{File.basename(ext)}" => ["copy:#{File.basename(ext).ext('')}:#{platf}"]
190
- end
190
+ ext_files = []
191
+
192
+ # go through native prerequisites and grab the real extension files from there
193
+ t.prerequisites.each do |ext|
194
+ ext_files << ext
191
195
  end
192
196
 
193
197
  # include the files in the gem specification
194
198
  spec.files += ext_files
195
199
 
196
- # Make sure that the required ruby version matches the ruby version
197
- # we've used for cross compiling:
198
- target_version = RUBY_VERSION =~ /^1.8/ ? '1.8.6' : '1.9.0'
199
- spec.required_ruby_version = "~> #{target_version}"
200
-
201
200
  # Generate a package for this gem
202
201
  gem_package = Rake::GemPackageTask.new(spec) do |pkg|
203
202
  pkg.need_zip = false
204
203
  pkg.need_tar = false
205
204
  end
206
-
207
- # ensure the binaries are copied
208
- task "#{gem_package.package_dir}/#{gem_package.gem_file}" => ["copy:#{@name}:#{platf}"]
209
205
  end
210
206
  end
211
207
 
212
208
  # add binaries to the dependency chain
213
- task "native:#{@gem_spec.name}:#{platf}" => ["#{tmp_path}/#{binary(platf)}"]
209
+ task "native:#{@gem_spec.name}:#{platf}" => ["#{lib_path}/#{binary(platf)}"]
210
+
211
+ # ensure the extension get copied
212
+ unless Rake::Task.task_defined?("#{lib_path}/#{binary(platf)}") then
213
+ file "#{lib_path}/#{binary(platf)}" => ["copy:#{@name}:#{platf}:#{ruby_ver}"]
214
+ end
214
215
 
215
216
  # Allow segmented packaging by platfrom (open door for 'cross compile')
216
217
  task "native:#{platf}" => ["native:#{@gem_spec.name}:#{platf}"]
@@ -224,8 +225,33 @@ module Rake
224
225
  end
225
226
 
226
227
  def define_cross_platform_tasks(for_platform)
228
+ if ruby_vers = ENV['RUBY_CC_VERSION']
229
+ ruby_vers = ENV['RUBY_CC_VERSION'].split(File::PATH_SEPARATOR)
230
+ else
231
+ ruby_vers = [RUBY_VERSION]
232
+ end
233
+
234
+ multi = (ruby_vers.size > 1) ? true : false
235
+
236
+ ruby_vers.each do |version|
237
+ # save original lib_dir
238
+ orig_lib_dir = @lib_dir
239
+
240
+ # tweak lib directory only when targeting multiple versions
241
+ if multi then
242
+ version =~ /(\d+.\d+)/
243
+ @lib_dir = "#{@lib_dir}/#{$1}"
244
+ end
245
+
246
+ define_cross_platform_tasks_with_version(for_platform, version)
247
+
248
+ # restore lib_dir
249
+ @lib_dir = orig_lib_dir
250
+ end
251
+ end
252
+
253
+ def define_cross_platform_tasks_with_version(for_platform, ruby_ver)
227
254
  config_path = File.expand_path("~/.rake-compiler/config.yml")
228
- ruby_ver = ENV['RUBY_CC_VERSION'] || RUBY_VERSION
229
255
 
230
256
  # warn the user about the need of configuration to use cross compilation.
231
257
  unless File.exist?(config_path)
@@ -236,24 +262,37 @@ module Rake
236
262
  config_file = YAML.load_file(config_path)
237
263
 
238
264
  # tmp_path
239
- tmp_path = "#{@tmp_dir}/#{for_platform}/#{@name}"
265
+ tmp_path = "#{@tmp_dir}/#{for_platform}/#{@name}/#{ruby_ver}"
266
+
267
+ # lib_path
268
+ lib_path = lib_dir
240
269
 
241
270
  unless rbconfig_file = config_file["rbconfig-#{ruby_ver}"] then
242
271
  warn "no configuration section for specified version of Ruby (rbconfig-#{ruby_ver})"
243
272
  return
244
273
  end
245
274
 
275
+ # mkmf
276
+ mkmf_file = File.expand_path(File.join(File.dirname(rbconfig_file), '..', 'mkmf.rb'))
277
+
246
278
  # define compilation tasks for cross platfrom!
247
- define_compile_tasks(for_platform)
279
+ define_compile_tasks(for_platform, ruby_ver)
248
280
 
249
- # chain fake.rb and rbconfig.rb to Makefile generation
250
- file "#{tmp_path}/Makefile" => ["#{tmp_path}/fake.rb", "#{tmp_path}/rbconfig.rb"]
281
+ # chain fake.rb, rbconfig.rb and mkmf.rb to Makefile generation
282
+ file "#{tmp_path}/Makefile" => ["#{tmp_path}/fake.rb",
283
+ "#{tmp_path}/rbconfig.rb",
284
+ "#{tmp_path}/mkmf.rb"]
251
285
 
252
286
  # copy the file from the cross-ruby location
253
287
  file "#{tmp_path}/rbconfig.rb" => [rbconfig_file] do |t|
254
288
  cp t.prerequisites.first, t.name
255
289
  end
256
290
 
291
+ # copy mkmf from cross-ruby location
292
+ file "#{tmp_path}/mkmf.rb" => [mkmf_file] do |t|
293
+ cp t.prerequisites.first, t.name
294
+ end
295
+
257
296
  # genearte fake.rb for different ruby versions
258
297
  file "#{tmp_path}/fake.rb" do |t|
259
298
  File.open(t.name, 'w') do |f|
@@ -262,7 +301,7 @@ module Rake
262
301
  end
263
302
 
264
303
  # now define native tasks for cross compiled files
265
- define_native_tasks(for_platform) if @gem_spec && @gem_spec.platform == 'ruby'
304
+ define_native_tasks(for_platform, ruby_ver) if @gem_spec && @gem_spec.platform == 'ruby'
266
305
 
267
306
  # create cross task
268
307
  task 'cross' do
@@ -274,12 +313,12 @@ module Rake
274
313
 
275
314
  # clear lib/binary dependencies and trigger cross platform ones
276
315
  # check if lib/binary is defined (damn bundle versus so versus dll)
277
- if Rake::Task.task_defined?("#{@lib_dir}/#{binary(for_platform)}") then
278
- Rake::Task["#{@lib_dir}/#{binary(for_platform)}"].prerequisites.clear
316
+ if Rake::Task.task_defined?("#{lib_path}/#{binary(for_platform)}") then
317
+ Rake::Task["#{lib_path}/#{binary(for_platform)}"].prerequisites.clear
279
318
  end
280
319
 
281
320
  # FIXME: targeting multiple platforms copies the file twice
282
- file "#{@lib_dir}/#{binary(for_platform)}" => ["copy:#{@name}:#{for_platform}"]
321
+ file "#{lib_path}/#{binary(for_platform)}" => ["copy:#{@name}:#{for_platform}:#{ruby_ver}"]
283
322
 
284
323
  # if everything for native task is in place
285
324
  if @gem_spec && @gem_spec.platform == 'ruby' then
@@ -110,6 +110,7 @@ describe Rake::ExtensionTask do
110
110
  @ext = Rake::ExtensionTask.new('extension_one')
111
111
  @ext_bin = ext_bin('extension_one')
112
112
  @platform = RUBY_PLATFORM
113
+ @ruby_ver = RUBY_VERSION
113
114
  end
114
115
 
115
116
  context 'compile' do
@@ -137,46 +138,46 @@ describe Rake::ExtensionTask do
137
138
  Rake::Task.task_defined?("lib/#{@ext_bin}").should be_true
138
139
  end
139
140
 
140
- it "should depend on 'copy:extension_one:{platform}'" do
141
- Rake::Task["lib/#{@ext_bin}"].prerequisites.should include("copy:extension_one:#{@platform}")
141
+ it "should depend on 'copy:extension_one:{platform}:{ruby_ver}'" do
142
+ Rake::Task["lib/#{@ext_bin}"].prerequisites.should include("copy:extension_one:#{@platform}:#{@ruby_ver}")
142
143
  end
143
144
  end
144
145
 
145
- context 'tmp/{platform}/extension_one/extension_one.{so,bundle}' do
146
+ context 'tmp/{platform}/extension_one/{ruby_ver}/extension_one.{so,bundle}' do
146
147
  it 'should define as task' do
147
- Rake::Task.task_defined?("tmp/#{@platform}/extension_one/#{@ext_bin}").should be_true
148
+ Rake::Task.task_defined?("tmp/#{@platform}/extension_one/#{@ruby_ver}/#{@ext_bin}").should be_true
148
149
  end
149
150
 
150
- it "should depend on 'tmp/{platform}/extension_one/Makefile'" do
151
- Rake::Task["tmp/#{@platform}/extension_one/#{@ext_bin}"].prerequisites.should include("tmp/#{@platform}/extension_one/Makefile")
151
+ it "should depend on 'tmp/{platform}/extension_one/{ruby_ver}/Makefile'" do
152
+ Rake::Task["tmp/#{@platform}/extension_one/#{@ruby_ver}/#{@ext_bin}"].prerequisites.should include("tmp/#{@platform}/extension_one/#{@ruby_ver}/Makefile")
152
153
  end
153
154
 
154
155
  it "should depend on 'ext/extension_one/source.c'" do
155
- Rake::Task["tmp/#{@platform}/extension_one/#{@ext_bin}"].prerequisites.should include("ext/extension_one/source.c")
156
+ Rake::Task["tmp/#{@platform}/extension_one/#{@ruby_ver}/#{@ext_bin}"].prerequisites.should include("ext/extension_one/source.c")
156
157
  end
157
158
 
158
159
  it "should not depend on 'ext/extension_one/source.h'" do
159
- Rake::Task["tmp/#{@platform}/extension_one/#{@ext_bin}"].prerequisites.should_not include("ext/extension_one/source.h")
160
+ Rake::Task["tmp/#{@platform}/extension_one/#{@ruby_ver}/#{@ext_bin}"].prerequisites.should_not include("ext/extension_one/source.h")
160
161
  end
161
162
  end
162
163
 
163
- context 'tmp/{platform}/extension_one/Makefile' do
164
+ context 'tmp/{platform}/extension_one/{ruby_ver}/Makefile' do
164
165
  it 'should define as task' do
165
- Rake::Task.task_defined?("tmp/#{@platform}/extension_one/Makefile").should be_true
166
+ Rake::Task.task_defined?("tmp/#{@platform}/extension_one/#{@ruby_ver}/Makefile").should be_true
166
167
  end
167
168
 
168
- it "should depend on 'tmp/{platform}/extension_one'" do
169
- Rake::Task["tmp/#{@platform}/extension_one/Makefile"].prerequisites.should include("tmp/#{@platform}/extension_one")
169
+ it "should depend on 'tmp/{platform}/extension_one/{ruby_ver}'" do
170
+ Rake::Task["tmp/#{@platform}/extension_one/#{@ruby_ver}/Makefile"].prerequisites.should include("tmp/#{@platform}/extension_one/#{@ruby_ver}")
170
171
  end
171
172
 
172
173
  it "should depend on 'ext/extension_one/extconf.rb'" do
173
- Rake::Task["tmp/#{@platform}/extension_one/Makefile"].prerequisites.should include("ext/extension_one/extconf.rb")
174
+ Rake::Task["tmp/#{@platform}/extension_one/#{@ruby_ver}/Makefile"].prerequisites.should include("ext/extension_one/extconf.rb")
174
175
  end
175
176
  end
176
177
 
177
178
  context 'clean' do
178
- it "should include 'tmp/{platform}/extension_one' in the pattern" do
179
- CLEAN.should include("tmp/#{@platform}/extension_one")
179
+ it "should include 'tmp/{platform}/extension_one/{ruby_ver}' in the pattern" do
180
+ CLEAN.should include("tmp/#{@platform}/extension_one/#{@ruby_ver}")
180
181
  end
181
182
  end
182
183
 
@@ -199,11 +200,12 @@ describe Rake::ExtensionTask do
199
200
  end
200
201
  @ext_bin = ext_bin('extension_one')
201
202
  @platform = RUBY_PLATFORM
203
+ @ruby_ver = RUBY_VERSION
202
204
  end
203
205
 
204
- context 'tmp/{platform}/extension_one/Makefile' do
206
+ context 'tmp/{platform}/extension_one/{ruby_ver}/Makefile' do
205
207
  it "should depend on 'custom/ext/foo/extconf.rb'" do
206
- Rake::Task["tmp/#{@platform}/extension_one/Makefile"].prerequisites.should include("custom/ext/foo/extconf.rb")
208
+ Rake::Task["tmp/#{@platform}/extension_one/#{@ruby_ver}/Makefile"].prerequisites.should include("custom/ext/foo/extconf.rb")
207
209
  end
208
210
  end
209
211
  end
@@ -214,6 +216,7 @@ describe Rake::ExtensionTask do
214
216
  @spec = mock_gem_spec
215
217
  @ext_bin = ext_bin('extension_one')
216
218
  @platform = RUBY_PLATFORM
219
+ @ruby_ver = RUBY_VERSION
217
220
  end
218
221
 
219
222
  context 'native' do
@@ -246,7 +249,7 @@ describe Rake::ExtensionTask do
246
249
  context 'native:my_gem:{platform}' do
247
250
  it 'should depend on binary extension' do
248
251
  Rake::ExtensionTask.new('extension_one', @spec)
249
- Rake::Task["native:my_gem:#{@platform}"].prerequisites.should include("tmp/#{@platform}/extension_one/#{@ext_bin}")
252
+ Rake::Task["native:my_gem:#{@platform}"].prerequisites.should include("lib/#{@ext_bin}")
250
253
  end
251
254
  end
252
255
  end
@@ -307,10 +310,41 @@ describe Rake::ExtensionTask do
307
310
  end
308
311
  end
309
312
 
313
+ it 'should allow multiple versions be supplied to RUBY_CC_VERSION' do
314
+ config = mock(Hash)
315
+ config.should_receive(:[]).once.with("rbconfig-1.8.6").and_return('/path/to/ruby/1.8.6/rbconfig.rb')
316
+ config.should_receive(:[]).once.with("rbconfig-1.9.1").and_return('/path/to/ruby/1.9.1/rbconfig.rb')
317
+ YAML.stub!(:load_file).and_return(config)
318
+
319
+ ENV['RUBY_CC_VERSION'] = '1.8.6:1.9.1'
320
+ Rake::ExtensionTask.new('extension_one') do |ext|
321
+ ext.cross_compile = true
322
+ end
323
+ end
324
+
310
325
  after :each do
311
326
  ENV.delete('RUBY_CC_VERSION')
312
327
  end
313
328
 
329
+ context "(cross compile for multiple versions)" do
330
+ before :each do
331
+ config = mock(Hash)
332
+ config.stub!(:[]).and_return('/path/to/ruby/1.8.6/rbconfig.rb', '/path/to/ruby/1.9.1/rbconfig.rb')
333
+ YAML.stub!(:load_file).and_return(config)
334
+
335
+ ENV['RUBY_CC_VERSION'] = '1.8.6:1.9.1'
336
+ @ext = Rake::ExtensionTask.new('extension_one') do |ext|
337
+ ext.cross_compile = true
338
+ ext.cross_platform = 'universal-unknown'
339
+ end
340
+ end
341
+
342
+ it 'should create specific copy of binaries for each version' do
343
+ Rake::Task.should have_defined("copy:extension_one:universal-unknown:1.8.6")
344
+ Rake::Task.should have_defined("copy:extension_one:universal-unknown:1.9.1")
345
+ end
346
+ end
347
+
314
348
  context "(cross for 'universal-unknown' platform)" do
315
349
  before :each do
316
350
  @ext = Rake::ExtensionTask.new('extension_one', @spec) do |ext|
@@ -321,17 +355,28 @@ describe Rake::ExtensionTask do
321
355
 
322
356
  context 'fake' do
323
357
  it 'should chain fake task to Makefile generation' do
324
- Rake::Task['tmp/universal-unknown/extension_one/Makefile'].prerequisites.should include('tmp/universal-unknown/extension_one/fake.rb')
358
+ Rake::Task["tmp/universal-unknown/extension_one/#{@ruby_ver}/Makefile"].prerequisites.should include("tmp/universal-unknown/extension_one/#{@ruby_ver}/fake.rb")
325
359
  end
326
360
  end
327
361
 
328
362
  context 'rbconfig' do
329
363
  it 'should chain rbconfig tasks to Makefile generation' do
330
- Rake::Task['tmp/universal-unknown/extension_one/Makefile'].prerequisites.should include('tmp/universal-unknown/extension_one/rbconfig.rb')
364
+ Rake::Task["tmp/universal-unknown/extension_one/#{@ruby_ver}/Makefile"].prerequisites.should include("tmp/universal-unknown/extension_one/#{@ruby_ver}/rbconfig.rb")
331
365
  end
332
366
 
333
367
  it 'should take rbconfig from rake-compiler configuration' do
334
- Rake::Task['tmp/universal-unknown/extension_one/rbconfig.rb'].prerequisites.should include(@config_path)
368
+ Rake::Task["tmp/universal-unknown/extension_one/#{@ruby_ver}/rbconfig.rb"].prerequisites.should include(@config_path)
369
+ end
370
+ end
371
+
372
+ context 'mkmf' do
373
+ it 'should chain mkmf tasks to Makefile generation' do
374
+ Rake::Task["tmp/universal-unknown/extension_one/#{@ruby_ver}/Makefile"].prerequisites.should include("tmp/universal-unknown/extension_one/#{@ruby_ver}/mkmf.rb")
375
+ end
376
+
377
+ it 'should take mkmf from rake-compiler configuration' do
378
+ mkmf_path = File.expand_path(File.join(File.dirname(@config_path), '..', 'mkmf.rb'))
379
+ Rake::Task["tmp/universal-unknown/extension_one/#{@ruby_ver}/mkmf.rb"].prerequisites.should include(mkmf_path)
335
380
  end
336
381
  end
337
382
 
@@ -9,7 +9,12 @@ require 'spec'
9
9
  require File.expand_path(File.join(File.dirname(__FILE__), 'support/capture_output_helper'))
10
10
 
11
11
  Spec::Runner.configure do |config|
12
- config.predicate_matchers[:have_defined] = :task_defined?
13
-
14
12
  include CaptureOutputHelper
15
13
  end
14
+
15
+ # Rake::Task matcher helper
16
+ Spec::Matchers.define :have_defined do |task|
17
+ match do |tasks|
18
+ tasks.task_defined?(task)
19
+ end
20
+ end
@@ -30,6 +30,7 @@ require 'rake/extensioncompiler'
30
30
 
31
31
  USER_HOME = File.expand_path("~/.rake-compiler")
32
32
  RUBY_CC_VERSION = "ruby-#{ENV['VERSION'] || '1.8.6-p287'}"
33
+ RUBY_SOURCE = ENV['SOURCE']
33
34
 
34
35
  # grab the major "1.8" or "1.9" part of the version number
35
36
  MAJOR = RUBY_CC_VERSION.match(/.*-(\d.\d).\d/)[1]
@@ -55,13 +56,18 @@ CLOBBER.include("#{USER_HOME}/config.yml")
55
56
  file "#{USER_HOME}/sources/#{RUBY_CC_VERSION}.tar.gz" => ["#{USER_HOME}/sources"] do |t|
56
57
  # download the source file using wget or curl
57
58
  chdir File.dirname(t.name) do
58
- url = "http://ftp.ruby-lang.org/pub/ruby/#{MAJOR}/#{File.basename(t.name)}"
59
+ if RUBY_SOURCE
60
+ url = RUBY_SOURCE
61
+ else
62
+ url = "http://ftp.ruby-lang.org/pub/ruby/#{MAJOR}/#{File.basename(t.name)}"
63
+ end
59
64
  sh "wget #{url} || curl -O #{url}"
60
65
  end
61
66
  end
62
67
 
63
68
  # Extract the sources
64
- file "#{USER_HOME}/sources/#{RUBY_CC_VERSION}" => ["#{USER_HOME}/sources/#{RUBY_CC_VERSION}.tar.gz"] do |t|
69
+ source_file = RUBY_SOURCE ? RUBY_SOURCE.split('/').last : "#{RUBY_CC_VERSION}.tar.gz"
70
+ file "#{USER_HOME}/sources/#{RUBY_CC_VERSION}" => ["#{USER_HOME}/sources/#{source_file}"] do |t|
65
71
  chdir File.dirname(t.name) do
66
72
  t.prerequisites.each { |f| sh "tar xfz #{File.basename(f)}" }
67
73
  end
@@ -3,7 +3,7 @@ require 'rubygems/package_task'
3
3
  GEM_SPEC = Gem::Specification.new do |s|
4
4
  # basic information
5
5
  s.name = "rake-compiler"
6
- s.version = "0.5.0"
6
+ s.version = "0.6.0"
7
7
  s.platform = Gem::Platform::RUBY
8
8
 
9
9
  # description and details
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rake-compiler
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.0
4
+ version: 0.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Luis Lavena
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-04-25 00:00:00 -03:00
12
+ date: 2009-07-25 00:00:00 -03:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -51,6 +51,7 @@ files:
51
51
  - features/support/env.rb
52
52
  - features/support/file_template_helpers.rb
53
53
  - features/support/generator_helpers.rb
54
+ - features/support/platform_extension_helpers.rb
54
55
  - bin/rake-compiler
55
56
  - lib/rake/extensioncompiler.rb
56
57
  - lib/rake/extensiontask.rb
@@ -98,7 +99,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
98
99
  requirements: []
99
100
 
100
101
  rubyforge_project: rake-compiler
101
- rubygems_version: 1.3.2
102
+ rubygems_version: 1.3.4
102
103
  signing_key:
103
104
  specification_version: 3
104
105
  summary: Rake-based Ruby C Extension task generator.