blackwinter-rake-compiler 0.9.2

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