rake-compiler 0.6.0 → 0.7.0

Sign up to get free protection for your applications and to get access to all the features.
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