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.
Files changed (44) hide show
  1. checksums.yaml +7 -0
  2. data/Gemfile +8 -0
  3. data/History.txt +308 -0
  4. data/LICENSE.txt +20 -0
  5. data/README.rdoc +415 -0
  6. data/Rakefile +15 -0
  7. data/bin/rake-compiler +24 -0
  8. data/cucumber.yml +4 -0
  9. data/features/compile.feature +79 -0
  10. data/features/cross-compile.feature +23 -0
  11. data/features/cross-package-multi.feature +15 -0
  12. data/features/cross-package.feature +14 -0
  13. data/features/java-compile.feature +22 -0
  14. data/features/java-no-native-compile.feature +33 -0
  15. data/features/java-package.feature +24 -0
  16. data/features/package.feature +40 -0
  17. data/features/step_definitions/compilation.rb +70 -0
  18. data/features/step_definitions/cross_compilation.rb +27 -0
  19. data/features/step_definitions/execution.rb +52 -0
  20. data/features/step_definitions/folders.rb +32 -0
  21. data/features/step_definitions/gem.rb +46 -0
  22. data/features/step_definitions/java_compilation.rb +7 -0
  23. data/features/support/env.rb +10 -0
  24. data/features/support/file_template_helpers.rb +137 -0
  25. data/features/support/generator_helpers.rb +123 -0
  26. data/features/support/platform_extension_helpers.rb +27 -0
  27. data/lib/rake/baseextensiontask.rb +90 -0
  28. data/lib/rake/extensioncompiler.rb +53 -0
  29. data/lib/rake/extensiontask.rb +513 -0
  30. data/lib/rake/javaextensiontask.rb +226 -0
  31. data/spec/lib/rake/extensiontask_spec.rb +501 -0
  32. data/spec/lib/rake/javaextensiontask_spec.rb +182 -0
  33. data/spec/spec.opts +3 -0
  34. data/spec/spec_helper.rb +15 -0
  35. data/spec/support/capture_output_helper.rb +22 -0
  36. data/tasks/bin/cross-ruby.rake +213 -0
  37. data/tasks/bootstrap.rake +11 -0
  38. data/tasks/common.rake +10 -0
  39. data/tasks/cucumber.rake +23 -0
  40. data/tasks/gem.rake +52 -0
  41. data/tasks/news.rake +39 -0
  42. data/tasks/release.rake +26 -0
  43. data/tasks/rspec.rake +9 -0
  44. metadata +138 -0
@@ -0,0 +1,15 @@
1
+ #--
2
+ # Copyright (c) 2008 Luis Lavena
3
+ #
4
+ # This source code is released under the MIT License.
5
+ # See LICENSE file for details
6
+ #++
7
+
8
+ #
9
+ # NOTE: Keep this file clean.
10
+ # Add your customizations inside tasks directory.
11
+ # Thank You.
12
+ #
13
+
14
+ # load rakefile extensions (tasks)
15
+ Dir['tasks/*.rake'].sort.each { |f| load f }
@@ -0,0 +1,24 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ #--
4
+ # Copyright (c) 2008 Luis Lavena
5
+ #
6
+ # This source code is released under the MIT License.
7
+ # See LICENSE file for details
8
+ #++
9
+
10
+ begin
11
+ require 'rake'
12
+ rescue LoadError
13
+ require 'rubygems'
14
+ require 'rake'
15
+ end
16
+
17
+ # Initialize 'rake-compiler' application
18
+ Rake.application.init('rake-compiler')
19
+
20
+ # Load the already cooked tasks ;-)
21
+ load File.join(File.dirname(__FILE__), %w{.. tasks bin cross-ruby.rake})
22
+
23
+ # delegate control to Rake
24
+ Rake.application.top_level
@@ -0,0 +1,4 @@
1
+ default: --tags ~@java --format progress features
2
+ java: --tags @java --format progress features
3
+ all: --format progress features
4
+ autotest: --format progress features
@@ -0,0 +1,79 @@
1
+ Feature: Compile C code into Ruby extensions.
2
+
3
+ In order to automate compilation process.
4
+ As a Gem developer.
5
+ I want rake tasks compile source code for me.
6
+
7
+ Scenario: compile single extension
8
+ Given a safe project directory
9
+ And a extension named 'extension_one'
10
+ And 'tmp' folder is deleted
11
+ When rake task 'compile' is invoked
12
+ Then rake task 'compile' succeeded
13
+ And binary extension 'extension_one' do exist in 'lib'
14
+ And 'tmp' folder is created
15
+
16
+ Scenario: compile an extension with extra options
17
+ Given a safe project directory
18
+ And a extension named 'extension_one'
19
+ And 'tmp' folder is deleted
20
+ When rake task 'compile -- --with-opt-dir=/opt/local' is invoked
21
+ Then rake task 'compile -- --with-opt-dir=/opt/local' succeeded
22
+ And output of rake task 'compile -- --with-opt-dir=/opt/local' contains /with-opt-dir/
23
+
24
+ Scenario: not recompile unmodified extension
25
+ Given a safe project directory
26
+ And a extension named 'extension_one'
27
+ And I've already successfully executed rake task 'compile'
28
+ And not changed any file since
29
+ When rake task 'compile' is invoked
30
+ Then rake task 'compile' succeeded
31
+ And output of rake task 'compile' do not contain /gcc|cl/
32
+
33
+ Scenario: recompile extension when source is modified
34
+ Given a safe project directory
35
+ And a extension named 'extension_one'
36
+ And I've already successfully executed rake task 'compile'
37
+ When touching 'source.c' file of extension 'extension_one'
38
+ And rake task 'compile' is invoked
39
+ Then rake task 'compile' succeeded
40
+ And output of rake task 'compile' contains /extension_one/
41
+
42
+ Scenario: compile multiple extensions
43
+ Given a safe project directory
44
+ And a extension named 'extension_one'
45
+ And a extension named 'extension_two'
46
+ And 'tmp' folder is deleted
47
+ When rake task 'compile' is invoked
48
+ Then rake task 'compile' succeeded
49
+ And binary extension 'extension_one' do exist in 'lib'
50
+ And binary extension 'extension_two' do exist in 'lib'
51
+ And 'tmp' folder is created
52
+
53
+ Scenario: compile one extension instead of all present
54
+ Given a safe project directory
55
+ And a extension named 'extension_one'
56
+ And a extension named 'extension_two'
57
+ When rake task 'compile:extension_one' is invoked
58
+ Then rake task 'compile:extension_one' succeeded
59
+ And output of rake task 'compile:extension_one' do not contain /extension_two/
60
+ And binary extension 'extension_one' do exist in 'lib'
61
+ And binary extension 'extension_two' do not exist in 'lib'
62
+
63
+ Scenario: removing temporary files
64
+ Given a safe project directory
65
+ And a extension named 'extension_one'
66
+ And I've already successfully executed rake task 'compile'
67
+ When rake task 'clean' is invoked
68
+ Then rake task 'clean' succeeded
69
+ And binary extension 'extension_one' do exist in 'lib'
70
+ And no left over from 'extension_one' remains in 'tmp'
71
+
72
+ Scenario: clobbering binary and temporary files
73
+ Given a safe project directory
74
+ And a extension named 'extension_one'
75
+ And I've already successfully executed rake task 'compile'
76
+ When rake task 'clobber' is invoked
77
+ Then rake task 'clobber' succeeded
78
+ And binary extension 'extension_one' do not exist in 'lib'
79
+ And 'tmp' folder do not exist
@@ -0,0 +1,23 @@
1
+ Feature: Cross-compile C extensions
2
+
3
+ In order to avoid bitching from Windows users
4
+ As a Ruby developer on Linux
5
+ I want some rake tasks that take away the pain of compilation
6
+
7
+ Scenario: compile single extension
8
+ Given that all my source files are in place
9
+ And I'm running a POSIX operating system
10
+ And I've installed cross compile toolchain
11
+ When rake task 'cross compile' is invoked
12
+ Then rake task 'cross compile' succeeded
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.7:1.9.3:2.0.0' is invoked
20
+ Then rake task 'cross compile RUBY_CC_VERSION=1.8.7:1.9.3:2.0.0' 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
23
+ And binaries for platform 'i386-mingw32' version '2.0' get copied
@@ -0,0 +1,15 @@
1
+ Feature: Generate multiple Windows gems from Linux
2
+
3
+ In order to keep compatibility with versions of Ruby on Windows
4
+ As a Gem developer on Linux
5
+ I want to build binary gems for One-Click Installer (old and new versions)
6
+
7
+ Scenario: package multiple gems for Windows
8
+ Given that my gem source is all in place to target two platforms
9
+ And I'm running a POSIX operating system
10
+ And I've installed cross compile toolchain
11
+ And I've already successfully executed rake task 'cross compile'
12
+ When rake task 'cross native gem' is invoked
13
+ Then rake task 'cross native gem' succeeded
14
+ And gem for platform 'x86-mswin32-60' get generated
15
+ And gem for platform 'x86-mingw32' get generated
@@ -0,0 +1,14 @@
1
+ Feature: Generate Windows gems from Linux
2
+
3
+ In order to keep sanity in the Ruby world
4
+ As a Gem developer on Linux
5
+ I want more rake magic that turns monotony into joy.
6
+
7
+ Scenario: package a gem for Windows
8
+ Given that my gem source is all in place
9
+ And I'm running a POSIX operating system
10
+ And I've installed cross compile toolchain
11
+ And I've already successfully executed rake task 'cross compile'
12
+ When rake task 'cross native gem' is invoked
13
+ Then rake task 'cross native gem' succeeded
14
+ And gem for platform 'x86-mingw32' get generated
@@ -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
@@ -0,0 +1,40 @@
1
+ Feature: Distribute native extension with gems
2
+
3
+ In order to avoid compiler toolchain requirement during installation
4
+ As a Gem developer.
5
+ I want rake tasks generate platform specific gems for me
6
+
7
+ Scenario: generate pure ruby gem
8
+ Given a safe project directory
9
+ And a gem named 'my_project'
10
+ And a extension named 'extension_one'
11
+ And I've already successfully executed rake task 'compile'
12
+ And 'pkg' folder is deleted
13
+ When rake task 'gem' is invoked
14
+ Then rake task 'gem' succeeded
15
+ And 'pkg' folder is created
16
+ And ruby gem for 'my_project' version '0.1.0' do exist in 'pkg'
17
+
18
+ Scenario: generate native gem
19
+ Given a safe project directory
20
+ And a gem named 'my_project'
21
+ And a extension named 'extension_one'
22
+ And I've already successfully executed rake task 'compile'
23
+ And 'pkg' folder is deleted
24
+ When rake task 'native gem' is invoked
25
+ Then rake task 'native gem' succeeded
26
+ And 'pkg' folder is created
27
+ And ruby gem for 'my_project' version '0.1.0' do exist in 'pkg'
28
+ And binary gem for 'my_project' version '0.1.0' do exist in 'pkg'
29
+
30
+ Scenario: generate forced native gem
31
+ Given a safe project directory
32
+ And a gem named 'my_project'
33
+ And a extension 'extension_one' with forced platform 'universal-unknown'
34
+ And I've already successfully executed rake task 'compile'
35
+ And 'pkg' folder is deleted
36
+ When rake task 'native:universal-unknown gem' is invoked
37
+ Then rake task 'native:universal-unknown gem' succeeded
38
+ And 'pkg' folder is created
39
+ And ruby gem for 'my_project' version '0.1.0' do exist in 'pkg'
40
+ And a gem for 'my_project' version '0.1.0' platform 'universal-unknown' do exist in 'pkg'
@@ -0,0 +1,70 @@
1
+ Given /^a extension named '(.*)'$/ do |extension_name|
2
+ generate_extension_task_for extension_name
3
+ generate_source_code_for extension_name
4
+ end
5
+
6
+ Given /^a extension cross-compilable '(.*)'$/ do |extension_name|
7
+ generate_cross_compile_extension_task_for extension_name
8
+ generate_source_code_for extension_name
9
+ end
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
+
16
+ Given /^a extension '(.*)' multi cross\-compilable$/ do |extension_name|
17
+ generate_multi_cross_compile_extension_task_for extension_name
18
+ generate_source_code_for extension_name
19
+ end
20
+
21
+ Given /^a extension '(.*)' with forced platform '(.*)'$/ do |extension_name, forced_platform|
22
+ generate_extension_task_for extension_name, forced_platform
23
+ generate_source_code_for extension_name
24
+ end
25
+
26
+ Given /^that all my source files are in place$/ do
27
+ step "a safe project directory"
28
+ step "a extension cross-compilable 'extension_one'"
29
+ end
30
+
31
+ Given /^that all my Java source files are in place$/ do
32
+ step "a safe project directory"
33
+ step "a extension Java-compilable 'extension_one'"
34
+ end
35
+
36
+ Given /^that my gem source is all in place$/ do
37
+ step "a safe project directory"
38
+ step "a gem named 'gem_abc'"
39
+ step "a extension cross-compilable 'extension_one'"
40
+ end
41
+
42
+ Given /^that my JRuby gem source is all in place$/ do
43
+ step "a safe project directory"
44
+ step "a gem named 'gem_abc'"
45
+ step "a extension Java-compilable 'extension_one'"
46
+ end
47
+
48
+ Given /^that my gem source is all in place to target two platforms$/ do
49
+ step "a safe project directory"
50
+ step "a gem named 'gem_abc'"
51
+ step "a extension 'extension_one' multi cross-compilable"
52
+ end
53
+
54
+ Given /^not changed any file since$/ do
55
+ # don't do anything, that's the purpose of this step!
56
+ end
57
+
58
+ When /^touching '(.*)' file of extension '(.*)'$/ do |file, extension_name|
59
+ Kernel.sleep 1
60
+ FileUtils.touch "ext/#{extension_name}/#{file}"
61
+ end
62
+
63
+ Then /^binary extension '(.*)' (do|do not) exist in '(.*)'$/ do |extension_name, condition, folder|
64
+ ext_for_platform = File.join(folder, "#{extension_name}.#{RbConfig::CONFIG['DLEXT']}")
65
+ if condition == 'do'
66
+ File.exist?(ext_for_platform).should be_true
67
+ else
68
+ File.exist?(ext_for_platform).should be_false
69
+ end
70
+ end
@@ -0,0 +1,27 @@
1
+ # Naive way of looking into platforms, please include others like FreeBSD?
2
+ Given %r{^I'm running a POSIX operating system$} do
3
+ unless RbConfig::CONFIG['host_os'] =~ /linux|darwin/ then
4
+ raise Cucumber::Pending.new("You need a POSIX operating system, no cheating ;-)")
5
+ end
6
+ end
7
+
8
+ Given %r{^I've installed cross compile toolchain$} do
9
+ unless search_path(%w(i586-mingw32msvc-gcc i386-mingw32-gcc i686-w64-mingw32-gcc))
10
+ pending 'Cannot locate suitable compiler in the PATH.'
11
+ end
12
+ end
13
+
14
+ Then /^binaries for platform '(.*)' get generated$/ do |platform|
15
+ ext = binary_extension(platform)
16
+
17
+ ext_for_platform = Dir.glob("tmp/#{platform}/**/*.#{ext}")
18
+ ext_for_platform.should_not be_empty
19
+ end
20
+
21
+ Then /^binaries for platform '(.*)' version '(.*)' get copied$/ do |platform, version|
22
+ lib_path = "lib/#{version}"
23
+ ext = binary_extension(platform)
24
+
25
+ ext_for_platform = Dir.glob("#{lib_path}/*.#{ext}")
26
+ ext_for_platform.should_not be_empty
27
+ end
@@ -0,0 +1,52 @@
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`
11
+ unless $?.success?
12
+ warn emptyness
13
+ raise "rake failed with #{$?.exitstatus}"
14
+ end
15
+ end
16
+
17
+ When /^rake task '(.*)' is invoked(| on JRuby)$/ do |task_name, on_jruby|
18
+ @output ||= {}
19
+ @result ||= {}
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`
23
+ @result[task_name] = $?.success?
24
+ end
25
+
26
+ Then /^rake task '(.*)' succeeded$/ do |task_name|
27
+ if @result.nil? || !@result.include?(task_name) then
28
+ raise "The task #{task_name} should be invoked first."
29
+ else
30
+ @result[task_name].should be_true
31
+ end
32
+ end
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
+
42
+ Then /^output of rake task '(.*)' (contains|do not contain) \/(.*)\/$/ do |task_name, condition, regex|
43
+ if condition == 'contains' then
44
+ @output[task_name].should match(%r(#{regex}))
45
+ else
46
+ @output[task_name].should_not match(%r(#{regex}))
47
+ end
48
+ end
49
+
50
+ Then /^output of rake task '(.*)' warns$/ do |task_name, warning|
51
+ @output[task_name].should include(warning)
52
+ end