rake-compiler 0.6.0 → 0.7.0

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.
data/History.txt CHANGED
@@ -1,4 +1,53 @@
1
- === 0.6.x (in Git)
1
+ === 0.7.0 / 2009-12-08
2
+
3
+ * Enhancements
4
+ * Allow generation of JRuby extensions. Thanks to Alex Coles (myabc) for the
5
+ contribution.
6
+ This will allow, with proper JDK tools, cross compilation of JRuby gems
7
+ from MRI.
8
+
9
+ Rake::JavaExtensionTask.new('my_java_extension', GEM_SPEC) do |ext|
10
+ # most of ExtensionTask options can be used
11
+ # plus, java_compiling:
12
+ ext.java_compiling do |gem_spec|
13
+ gem_spec.post_install_message = "This is a native JRuby gem!"
14
+ end
15
+ end
16
+
17
+ Please note that cross-compiling JRuby gems requires either JRUBY_HOME or
18
+ JRUBY_PARENT_CLASSPATH environment variables being properly set.
19
+
20
+ * Allow alteration of the Gem Specification when cross compiling. Closes GH-3
21
+ This is useful to indicate a custom requirement message, like DLLs
22
+ installation or similar.
23
+
24
+ Rake::ExtensionTask.new('my_extension', GEM_SPEC) do |ext|
25
+ ext.cross_compile = true
26
+ # ...
27
+ ext.cross_compiling do |gem_spec|
28
+ gem_spec.post_install_message = "You've installed a binary version of this gem"
29
+ end
30
+ end
31
+
32
+ * Bugfixes
33
+ * Detect GNU make independently of distribution based naming.
34
+ Thanks to flori for patches.
35
+ * Usage of #dup to duplicate gemspec instead of YAML dumping.
36
+ * No longer support Ruby older than 1.8.6
37
+ * No longer support RubyGems older than 1.3.5
38
+ * Force definition of binary directory and executables. Closes GH-11
39
+ * Workaround path with spaces issues using relative paths. Closes GH-6
40
+ * Removed gemspec, GitHub gems no more
41
+
42
+ * Known issues
43
+ * Usage of rake-compiler under projects with Jeweler requires some tweaks
44
+ Please read issue GH-73 for Jeweler:
45
+ http://github.com/technicalpickles/jeweler/issues#issue/73
46
+
47
+ For a workaround, look here:
48
+ http://gist.github.com/251663
49
+
50
+ === 0.6.0 / 2009-07-25
2
51
 
3
52
  * Enhancements
4
53
  * Implemented 'fat-binaries' generation for cross compiling
data/README.rdoc CHANGED
@@ -1,14 +1,14 @@
1
1
  = rake-compiler
2
2
 
3
- rake-compiler aims to help Gem developers while dealing with Ruby C
4
- extensions, simplifying the code and reducing the duplication.
3
+ rake-compiler aims to help Gem developers deal with Ruby extensions, simplifying
4
+ code and reducing duplication.
5
5
 
6
- It follows *convention over configuration* and set an standardized
7
- structure to build and package C extensions in your gems.
6
+ It followss *convention over configuration* and sets a standardized structure to
7
+ build and package both C and Java extensions in your gems.
8
8
 
9
- This is the result of experiences dealing with several Gems that required
10
- native extensions across platforms and different user configurations
11
- where details like portability and clarity of code were lacking.
9
+ This is the result of experiences dealing with several Gems that required native
10
+ extensions across platforms and different user configurations where details like
11
+ portability and clarity of code were lacking.
12
12
 
13
13
  == An Overview
14
14
 
@@ -18,9 +18,12 @@ Let's summarize what rake-compiler provides:
18
18
 
19
19
  * Painlessly build extensions on different platforms (Linux, OSX and Windows).
20
20
 
21
+ * Painlessly build extensions for different Ruby implementations (JRuby,
22
+ Rubinius and MRI).
23
+
21
24
  * Allow multiple extensions be compiled inside the same gem.
22
25
 
23
- * Mimics RubyGems installation process, so helps as test environment.
26
+ * Mimics RubyGems installation process, so helps as a test environment.
24
27
 
25
28
  * Simplify cross platform compilation of extensions (target Windows from Linux).
26
29
 
@@ -32,13 +35,6 @@ First, you need to install the gem:
32
35
 
33
36
  $ gem install rake-compiler
34
37
 
35
- Since this package is in constant evolution, you could try installing it
36
- from GitHub:
37
-
38
- $ gem install luislavena-rake-compiler --source http://gems.github.com
39
-
40
- The development gem is usually in pretty good shape actually.
41
-
42
38
  == Now what? (Usage)
43
39
 
44
40
  Now that you have the gem installed, let's give your project some structure.
@@ -46,11 +42,12 @@ Now that you have the gem installed, let's give your project some structure.
46
42
  === Structure
47
43
 
48
44
  Let's say we want to compile an extension called 'hello_world', so we should
49
- organize the code and folders that will help rake-compiler do it's job:
45
+ organize the code and folders that will help rake-compiler do its job:
50
46
 
51
47
  |-- ext
52
48
  | `-- hello_world
53
49
  | |-- extconf.rb
50
+ | |-- HelloWorldService.java
54
51
  | `-- hello_world.c
55
52
  |-- lib
56
53
  `-- Rakefile
@@ -63,20 +60,28 @@ to find code and also contribute back to your project more easily.
63
60
  So now it's time to introduce the code to compile our extension:
64
61
 
65
62
  # File: Rakefile
66
-
63
+
67
64
  require 'rake/extensiontask'
68
-
65
+
69
66
  Rake::ExtensionTask.new('hello_world')
70
67
 
71
68
  Ok, that's it. No other line of code.
72
69
 
70
+ If we wanted to do the same for a JRuby extension (written in Java):
71
+
72
+ # File: Rakefile
73
+
74
+ require 'rake/javaextensiontask'
75
+
76
+ Rake::JavaExtensionTask.new('hello_world')
77
+
73
78
  === Compile process
74
79
 
75
80
  Those *two* lines of code automatically added the needed rake tasks to build
76
- the hello_world extension:
81
+ the hello_world extension. Running Rake on 1.8.x/1.9 (MRI):
77
82
 
78
83
  $ rake -T
79
- (in /home/user/my_extesion)
84
+ (in /home/user/my_extension)
80
85
  rake compile # Compile the extension(s)
81
86
  rake compile:hello_world # Compile just the hello_world extension
82
87
 
@@ -91,6 +96,10 @@ NOTE: Please be aware that building C extensions requires the proper
91
96
  development environment for your Platform, which includes libraries, headers
92
97
  and build tools. Check your distro / vendor documentation on how to install it.
93
98
 
99
+ NOTE: Building Java extensions requires the <tt>javac</tt>, part of the Java
100
+ Development Kit (JDK). This should be included by default on Mac OS X, and
101
+ downloadable from http://java.sun.com for other operating systems.
102
+
94
103
  === Generate native gems
95
104
 
96
105
  A common usage scenario of rake-compiler is generate native gems that bundles
@@ -141,6 +150,23 @@ Plus, you have the functionality to build native versions of the gem:
141
150
 
142
151
  You get two gems for the price of one.
143
152
 
153
+ And the same for JRuby extensions:
154
+
155
+ # rake java gem
156
+ (... compilation output ...)
157
+ mkdir -p pkg
158
+ Successfully built RubyGem
159
+ Name: my_gem
160
+ Version: 0.1.0
161
+ File: my_gem-0.1.0.gem
162
+ mv my_gem-0.1.0.gem pkg/my_gem-0.1.0.gem
163
+ Successfully built RubyGem
164
+ Name: my_gem
165
+ Version: 0.1.0
166
+ File: my_gem-0.1.0-java.gem
167
+ mv my_gem-0.1.0-java.gem pkg/my_gem-0.1.0-java.gem
168
+
169
+
144
170
  === What about breaking the standards? (Customization)
145
171
 
146
172
  In case you want to bend the convention established, rake-compiler let you
@@ -163,7 +189,7 @@ personalize several settings for <tt>Rake::ExtensionTask</tt>:
163
189
  rake-compiler provides now an standardized way to generate, from Linux or OSX
164
190
  both extensions and gem binaries for Windows!
165
191
 
166
- It takes advantages from GCC host/target to build binaries (for target) on
192
+ It takes advantages from GCC host/target to build binaries (for target) on
167
193
  different OS (hosts).
168
194
 
169
195
  === How I enjoy this?
@@ -171,16 +197,19 @@ different OS (hosts).
171
197
  Besides having the development tool chain installed (GCC), you should install
172
198
  also <tt>mingw32</tt> cross compilation package.
173
199
 
174
- This depends on your operating system distribution, a simple
175
- <tt>apt-get install mingw32</tt> will be enough.
200
+ Installation depends will depend on your operating system/distribution. On
201
+ Ubuntu and Debian machines, a simple <tt>apt-get install mingw32</tt> will be
202
+ enough.
176
203
 
177
- Please check OSX documentation about installing mingw32 from macports.
204
+ On OSX, mingw32 is available via MacPorts: <tt>port install i386-mingw32-gcc</tt>
205
+ (ensure you update your ports tree before hand as <tt>mingw32</tt> has been
206
+ been broken).
178
207
 
179
208
  === I have my tool-chain, now what?
180
209
 
181
210
  You need to build Ruby for Windows.
182
211
 
183
- Relax, no need to freak out. rake-compiler do it for you:
212
+ Relax, no need to freak out! Let rake-compiler do it for you:
184
213
 
185
214
  rake-compiler cross-ruby
186
215
 
@@ -201,6 +230,11 @@ Now, you only need to use additional options in your extension definition:
201
230
  ext.cross_platform = 'i386-mswin32' # forces the Windows platform instead of the default one
202
231
  # configure options only for cross compile
203
232
  ext.cross_config_options << '--with-something'
233
+
234
+ # perform alterations on the gemspec when cross compiling
235
+ ext.cross_compiling do |gem_spec|
236
+ gem_spec.post_install_message = "You installed the binary version of this gem!"
237
+ end
204
238
  end
205
239
 
206
240
  By default, cross compilation targets 'i386-mingw32' which is default GCC platform
@@ -257,12 +291,6 @@ Blog: http://blog.mmediasys.com
257
291
  RubyForge: http://rubyforge.org/projects/rake-compiler
258
292
  GitHub: http://github.com/luislavena/rake-compiler
259
293
 
260
- === Some of the desired features
261
-
262
- * <tt>Rake::JavaJarTask</tt> to generate <tt>jar</tt> packages and gems for JRuby.
263
-
264
- $ rake java gem
265
-
266
294
  == Disclaimer
267
295
 
268
296
  If you have any trouble, don't hesitate to contact the author. As always,
data/cucumber.yml CHANGED
@@ -1 +1,4 @@
1
+ default: --tags ~@java --format progress features
2
+ java: --tags @java --format progress features
3
+ all: --format progress features
1
4
  autotest: --format progress features
@@ -0,0 +1,22 @@
1
+ Feature: JCompile Java extensions
2
+
3
+ In order to avoid bitching from Enterprise users
4
+ As a Ruby developer
5
+ I want some rake tasks that take away the pain of compilation
6
+
7
+ @java
8
+ Scenario: Compile single Java extension (with default Rake)
9
+ Given that all my Java source files are in place
10
+ And I've installed the Java Development Kit
11
+ When rake task 'java compile' is invoked
12
+ Then rake task 'java compile' succeeded
13
+ And binaries for platform 'java' get generated
14
+
15
+ @java
16
+ Scenario: Compile single Java extension (with Rake on JRuby)
17
+ Given that all my Java source files are in place
18
+ And I've installed the Java Development Kit
19
+ When I've installed JRuby
20
+ When rake task 'java compile' is invoked on JRuby
21
+ Then rake task 'java compile' succeeded
22
+ And binaries for platform 'java' get generated
@@ -0,0 +1,33 @@
1
+ Feature: No native or cross compilation on JRuby
2
+
3
+ In order to present a good user experience to users of rake-compiler
4
+ As a user of JRuby
5
+ I want to be warned that my platform does not provide any support for C Extensions
6
+ I want to be be informed of this without rake-compiler blowing up in my face
7
+
8
+ @java
9
+ Scenario: Attempting to do a cross compilation while on JRuby (without prerequisites)
10
+ Given that all my source files are in place
11
+ And I'm running a POSIX operating system
12
+ When rake task 'cross compile' is invoked on JRuby
13
+ Then rake task 'cross compile' should fail
14
+ And output of rake task 'cross compile' warns
15
+ """
16
+ WARNING: You're attempting to (cross-)compile C extensions from a platform
17
+ (jruby) that does not support native extensions or mkmf.rb.
18
+ """
19
+ And output of rake task 'cross compile' contains /Don't know how to build task 'cross'/
20
+
21
+ @java
22
+ Scenario: Attempting to do a cross compilation while on JRuby (even with prerequisites)
23
+ Given that all my source files are in place
24
+ And I'm running a POSIX operating system
25
+ And I've installed cross compile toolchain
26
+ When rake task 'cross compile' is invoked on JRuby
27
+ Then rake task 'cross compile' should fail
28
+ And output of rake task 'cross compile' warns
29
+ """
30
+ WARNING: You're attempting to (cross-)compile C extensions from a platform
31
+ (jruby) that does not support native extensions or mkmf.rb.
32
+ """
33
+ And output of rake task 'cross compile' contains /Don't know how to build task 'cross'/
@@ -0,0 +1,24 @@
1
+ Feature: Generate JRuby gems from JRuby or MRI
2
+
3
+ In order to keep sanity in the Ruby world
4
+ As a Gem developer who used to do J2EE development
5
+ I want more rake magic that turns monotony into joy.
6
+
7
+ @java
8
+ Scenario: package a gem for Java (with default Rake)
9
+ Given that my JRuby gem source is all in place
10
+ And I've installed the Java Development Kit
11
+ And I've already successfully executed rake task 'java compile'
12
+ When rake task 'java gem' is invoked
13
+ Then rake task 'java gem' succeeded
14
+ And gem for platform 'java' get generated
15
+
16
+ @java
17
+ Scenario: package a gem for Java (with Rake on JRuby)
18
+ Given that my JRuby gem source is all in place
19
+ And I've installed the Java Development Kit
20
+ And I've installed JRuby
21
+ And I've already successfully executed rake task 'java compile' on JRuby
22
+ When rake task 'java gem' is invoked
23
+ Then rake task 'java gem' succeeded
24
+ And gem for platform 'java' get generated
@@ -8,6 +8,11 @@ Given /^a extension cross-compilable '(.*)'$/ do |extension_name|
8
8
  generate_source_code_for extension_name
9
9
  end
10
10
 
11
+ Given /^a extension Java-compilable '(.*)'$/ do |extension_name|
12
+ generate_java_compile_extension_task_for extension_name
13
+ generate_java_source_code_for extension_name
14
+ end
15
+
11
16
  Given /^a extension '(.*)' multi cross\-compilable$/ do |extension_name|
12
17
  generate_multi_cross_compile_extension_task_for extension_name
13
18
  generate_source_code_for extension_name
@@ -23,12 +28,23 @@ Given /^that all my source files are in place$/ do
23
28
  Given "a extension cross-compilable 'extension_one'"
24
29
  end
25
30
 
31
+ Given /^that all my Java source files are in place$/ do
32
+ Given "a safe project directory"
33
+ Given "a extension Java-compilable 'extension_one'"
34
+ end
35
+
26
36
  Given /^that my gem source is all in place$/ do
27
37
  Given "a safe project directory"
28
38
  Given "a gem named 'gem_abc'"
29
39
  Given "a extension cross-compilable 'extension_one'"
30
40
  end
31
41
 
42
+ Given /^that my JRuby gem source is all in place$/ do
43
+ Given "a safe project directory"
44
+ Given "a gem named 'gem_abc'"
45
+ Given "a extension Java-compilable 'extension_one'"
46
+ end
47
+
32
48
  Given /^that my gem source is all in place to target two platforms$/ do
33
49
  Given "a safe project directory"
34
50
  Given "a gem named 'gem_abc'"
@@ -1,19 +1,12 @@
1
1
  # Naive way of looking into platforms, please include others like FreeBSD?
2
2
  Given %r{^I'm running a POSIX operating system$} do
3
- unless RUBY_PLATFORM =~ /linux|darwin/ then
3
+ unless RbConfig::CONFIG['host_os'] =~ /linux|darwin/ then
4
4
  raise Cucumber::Pending.new("You need a POSIX operating system, no cheating ;-)")
5
5
  end
6
6
  end
7
7
 
8
8
  Given %r{^I've installed cross compile toolchain$} do
9
- compilers = %w(i586-mingw32msvc-gcc i386-mingw32-gcc)
10
- paths = ENV['PATH'].split(File::PATH_SEPARATOR)
11
- compiler = compilers.find do |comp|
12
- paths.find do |path|
13
- File.exist? File.join(path, comp)
14
- end
15
- end
16
- pending "Cannot locate suitable compiler in the PATH." unless compiler
9
+ pending 'Cannot locate suitable compiler in the PATH.' unless search_path(%w(i586-mingw32msvc-gcc i386-mingw32-gcc))
17
10
  end
18
11
 
19
12
  Then /^binaries for platform '(.*)' get generated$/ do |platform|
@@ -1,15 +1,25 @@
1
- Given %r{^I've already successfully executed rake task '(.*)'$} do |task_name|
2
- emptyness = `rake #{task_name} 2>&1`
1
+ # FIXME: Make the Transform work
2
+ #
3
+ # Transform /^| on JRuby$/ do |step_arg|
4
+ # / on JRuby/.match(step_arg) != nil
5
+ # end
6
+
7
+ Given %r{^I've already successfully executed rake task '(.*)'(| on JRuby)$} do |task_name, on_jruby|
8
+ rake_cmd = "rake #{task_name}"
9
+ rake_cmd = 'jruby -S ' << rake_cmd if on_jruby == ' on JRuby'
10
+ emptyness = `#{rake_cmd} 2>&1`
3
11
  unless $?.success?
4
12
  warn emptyness
5
13
  raise "rake failed with #{$?.exitstatus}"
6
14
  end
7
15
  end
8
16
 
9
- When /^rake task '(.*)' is invoked$/ do |task_name|
17
+ When /^rake task '(.*)' is invoked(| on JRuby)$/ do |task_name, on_jruby|
10
18
  @output ||= {}
11
19
  @result ||= {}
12
- @output[task_name] = `rake #{task_name} 2>&1`
20
+ rake_cmd = "rake #{task_name}"
21
+ rake_cmd = 'jruby -S ' << rake_cmd if on_jruby == ' on JRuby'
22
+ @output[task_name] = `#{rake_cmd} 2>&1`
13
23
  @result[task_name] = $?.success?
14
24
  end
15
25
 
@@ -21,6 +31,14 @@ Then /^rake task '(.*)' succeeded$/ do |task_name|
21
31
  end
22
32
  end
23
33
 
34
+ Then /^rake task '(.*)' should fail$/ do |task_name|
35
+ if @result.nil? || !@result.include?(task_name) then
36
+ raise "The task #{task_name} should be invoked first."
37
+ else
38
+ @result[task_name].should be_false
39
+ end
40
+ end
41
+
24
42
  Then /^output of rake task '(.*)' (contains|do not contain) \/(.*)\/$/ do |task_name, condition, regex|
25
43
  if condition == 'contains' then
26
44
  @output[task_name].should match(%r(#{regex}))
@@ -28,3 +46,7 @@ Then /^output of rake task '(.*)' (contains|do not contain) \/(.*)\/$/ do |task_
28
46
  @output[task_name].should_not match(%r(#{regex}))
29
47
  end
30
48
  end
49
+
50
+ Then /^output of rake task '(.*)' warns$/ do |task_name, warning|
51
+ @output[task_name].should include(warning)
52
+ end
@@ -12,6 +12,12 @@ end
12
12
 
13
13
  Then /^a gem for '(.*)' version '(.*)' platform '(.*)' do exist in '(.*)'$/ do |name, version, platform, folder|
14
14
  File.exist?(gem_file_platform(folder, name, version, platform)).should be_true
15
+
16
+ # unpack the Gem and check what's inside!
17
+ `gem unpack #{gem_file_platform(folder, name, version, platform)} --target tmp`
18
+ unpacked_gem_dir = unpacked_gem_dir_platform('tmp', name, version, platform)
19
+ File.exist?(unpacked_gem_dir).should be_true
20
+ Dir.glob(unpacked_gem_dir << "/lib/*.#{binary_extension(platform)}").should_not be_empty
15
21
  end
16
22
 
17
23
  Then /^gem for platform '(.*)' get generated$/ do |platform|
@@ -28,3 +34,9 @@ def gem_file_platform(folder, name, version, platform = nil)
28
34
  file << ".gem"
29
35
  file
30
36
  end
37
+
38
+ def unpacked_gem_dir_platform(folder, name, version, platform = nil)
39
+ file = "#{folder}/#{name}-#{version}"
40
+ file << "-" << (platform || Gem::Platform.new(RUBY_PLATFORM).to_s)
41
+ file
42
+ end