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,32 @@
1
+ Given /^a safe project directory$/ do
2
+ # step back to ROOT
3
+ Dir.chdir ROOT_PATH
4
+ tmp_name = "project.#{Process.pid}"
5
+ @safe_dir = File.join(ROOT_PATH, 'tmp', tmp_name)
6
+ FileUtils.rm_rf @safe_dir
7
+ FileUtils.mkdir_p @safe_dir
8
+ Dir.chdir @safe_dir
9
+
10
+ generate_scaffold_structure
11
+ end
12
+
13
+ Given /^'(.*)' folder (exist|is deleted)$/ do |folder, condition|
14
+ case condition
15
+ when 'exist'
16
+ raise "Folder #{folder} do not exist" unless File.exist?(folder) && File.directory?(folder)
17
+ when 'is deleted'
18
+ FileUtils.rm_rf folder
19
+ end
20
+ end
21
+
22
+ Then /^'(.*)' folder is created$/ do |folder|
23
+ File.directory?(folder).should be_true
24
+ end
25
+
26
+ Then /^'(.*)' folder do not exist$/ do |folder|
27
+ File.directory?(folder).should_not be_true
28
+ end
29
+
30
+ Then /^no left over from '(.*)' remains in '(.*)'$/ do |name, folder|
31
+ Dir.glob("#{folder}/**/#{name}/#{RUBY_VERSION}").should be_empty
32
+ end
@@ -0,0 +1,46 @@
1
+ Given /^a gem named '(.*)'$/ do |gem_name|
2
+ generate_gem_task gem_name
3
+ end
4
+
5
+ Then /^ruby gem for '(.*)' version '(.*)' do exist in '(.*)'$/ do |name, version, folder|
6
+ File.exist?(gem_file(folder, name, version)).should be_true
7
+ end
8
+
9
+ Then /^binary gem for '(.*)' version '(.*)' do exist in '(.*)'$/ do |name, version, folder|
10
+ File.exist?(gem_file_platform(folder, name, version)).should be_true
11
+ end
12
+
13
+ Then /^a gem for '(.*)' version '(.*)' platform '(.*)' do exist in '(.*)'$/ do |name, version, platform, folder|
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
+
21
+ files = Dir.glob("#{unpacked_gem_dir}/lib/*.#{binary_extension(platform)}")
22
+ files << Dir.glob("#{unpacked_gem_dir}/lib/*/*.#{binary_extension(platform)}")
23
+
24
+ files.flatten.uniq.should_not be_empty
25
+ end
26
+
27
+ Then /^gem for platform '(.*)' get generated$/ do |platform|
28
+ step "a gem for 'gem_abc' version '0.1.0' platform '#{platform}' do exist in 'pkg'"
29
+ end
30
+
31
+ def gem_file(folder, name, version)
32
+ "#{folder}/#{name}-#{version}.gem"
33
+ end
34
+
35
+ def gem_file_platform(folder, name, version, platform = nil)
36
+ file = "#{folder}/#{name}-#{version}"
37
+ file << "-" << (platform || Gem::Platform.new(RUBY_PLATFORM).to_s)
38
+ file << ".gem"
39
+ file
40
+ end
41
+
42
+ def unpacked_gem_dir_platform(folder, name, version, platform = nil)
43
+ file = "#{folder}/#{name}-#{version}"
44
+ file << "-" << (platform || Gem::Platform.new(RUBY_PLATFORM).to_s)
45
+ file
46
+ end
@@ -0,0 +1,7 @@
1
+ Given %r{^I've installed the Java Development Kit$} do
2
+ pending('Cannot locate suitable Java compiler (the Java Development Kit) in the PATH.') unless search_path(%w(javac javac.exe))
3
+ end
4
+
5
+ Given %r{^I've installed JRuby$} do
6
+ pending('Cannot locate a JRuby installation in the PATH.') unless search_path(%w(jruby jruby.exe jruby.bat))
7
+ end
@@ -0,0 +1,10 @@
1
+ require 'cucumber'
2
+ require 'rspec'
3
+ require 'fileutils'
4
+ require 'rbconfig'
5
+
6
+ ROOT_PATH = File.expand_path(File.join(File.dirname(__FILE__), '../..'))
7
+
8
+ # get rid of Bundler environment polution
9
+ defined?(Bundler) and
10
+ ENV.delete("RUBYOPT")
@@ -0,0 +1,137 @@
1
+ module FileTemplateHelpers
2
+ def template_rakefile
3
+ <<-EOF
4
+ # add rake-compiler lib dir to the LOAD_PATH
5
+ $LOAD_PATH.unshift File.expand_path(File.join(File.dirname(__FILE__), '../..', 'lib'))
6
+
7
+ require 'rubygems'
8
+ require 'rake'
9
+
10
+ # load rakefile extensions (tasks)
11
+ Dir['tasks/*.rake'].each { |f| import f }
12
+ EOF
13
+ end
14
+
15
+ def template_rake_gemspec(gem_name)
16
+ <<-EOF
17
+ require 'rubygems/package_task'
18
+ SPEC = Gem::Specification.new do |s|
19
+ s.name = "#{gem_name}"
20
+ s.version = "0.1.0"
21
+ s.summary = "#{gem_name} test gem for rake-compiler"
22
+ s.description = "#{gem_name} is a fake gem for testing under rake-compiler"
23
+
24
+ s.files = FileList["ext/**/*.{rb,c,h}", "Rakefile", "tasks/*.rake", "lib/**/*.rb"]
25
+
26
+ s.extensions = FileList["ext/**/extconf.rb"]
27
+
28
+ s.homepage = 'http://github.com/luislavena/rake-compiler'
29
+ s.rubyforge_project = 'TODO'
30
+
31
+ s.authors = ["Luis Lavena"]
32
+ s.email = ["luislavena@gmail.com"]
33
+ end
34
+
35
+ Gem::PackageTask.new(SPEC) do |pkg|
36
+ pkg.need_zip = false
37
+ pkg.need_tar = false
38
+ end
39
+ EOF
40
+ end
41
+
42
+ def template_rake_extension(extension_name, gem_spec = nil)
43
+ <<-EOF
44
+ require 'rake/extensiontask'
45
+ Rake::ExtensionTask.new("#{extension_name}"#{', SPEC' if gem_spec})
46
+ EOF
47
+ end
48
+
49
+ def template_rake_extension_with_platform(extension_name, platform)
50
+ <<-EOF
51
+ require 'rake/extensiontask'
52
+ Rake::ExtensionTask.new("#{extension_name}", SPEC) do |ext|
53
+ ext.platform = "#{platform}"
54
+ end
55
+ EOF
56
+ end
57
+
58
+ def template_rake_extension_cross_compile(extension_name, gem_spec = nil)
59
+ <<-EOF
60
+ require 'rake/extensiontask'
61
+ Rake::ExtensionTask.new("#{extension_name}"#{', SPEC' if gem_spec}) do |ext|
62
+ ext.cross_compile = true
63
+ end
64
+ EOF
65
+ end
66
+
67
+ def template_rake_extension_multi_cross_compile(extension_name)
68
+ <<-EOF
69
+ require 'rake/extensiontask'
70
+ Rake::ExtensionTask.new("#{extension_name}", SPEC) do |ext|
71
+ ext.cross_compile = true
72
+ ext.cross_platform = ['i386-mswin32-60', 'i386-mingw32']
73
+ end
74
+ EOF
75
+ end
76
+
77
+ def template_rake_extension_java_compile(extension_name, gem_spec = nil)
78
+ <<-EOF
79
+ require 'rake/javaextensiontask'
80
+ Rake::JavaExtensionTask.new("#{extension_name}"#{', SPEC' if gem_spec}) do |ext|
81
+ # nothing
82
+ end
83
+ EOF
84
+ end
85
+
86
+ def template_extconf(extension_name)
87
+ <<-EOF
88
+ require 'mkmf'
89
+ create_makefile("#{extension_name}")
90
+ EOF
91
+ end
92
+
93
+ def template_source_c(extension_name)
94
+ <<-EOF
95
+ #include "source.h"
96
+ void Init_#{extension_name}()
97
+ {
98
+ printf("source.c of extension #{extension_name}\\n");
99
+ }
100
+ EOF
101
+ end
102
+
103
+ def template_source_h
104
+ <<-EOF
105
+ #include "ruby.h"
106
+ EOF
107
+ end
108
+
109
+ def template_source_java(extension_name)
110
+ <<-EOF
111
+ import org.jruby.Ruby;
112
+ import org.jruby.runtime.load.BasicLibraryService;
113
+
114
+ public class #{camelize(extension_name)}Service implements BasicLibraryService {
115
+ public boolean basicLoad(final Ruby runtime) throws java.io.IOException {
116
+ HelloWorldPrinter hwp = new HelloWorldPrinter();
117
+ hwp.tellTheWorld();
118
+ return true;
119
+ }
120
+
121
+ private class HelloWorldPrinter {
122
+ void tellTheWorld() throws java.io.IOException {
123
+ System.out.println("#{camelize(extension_name)}Service.java of extension #{extension_name}\\n");
124
+ }
125
+ }
126
+ }
127
+
128
+ EOF
129
+ end
130
+
131
+ def camelize(str)
132
+ str.gsub(/(^|_)(.)/) { $2.upcase }
133
+ end
134
+
135
+ end
136
+
137
+ World(FileTemplateHelpers)
@@ -0,0 +1,123 @@
1
+ module GeneratorHelpers
2
+ def generate_scaffold_structure
3
+ # create folder structure
4
+ FileUtils.mkdir_p "lib"
5
+ FileUtils.mkdir_p "tasks"
6
+ FileUtils.mkdir_p "tmp"
7
+
8
+ # create Rakefile loader
9
+ File.open("Rakefile", 'w') do |rakefile|
10
+ rakefile.puts template_rakefile.strip
11
+ end
12
+ end
13
+
14
+ def generate_gem_task(gem_name)
15
+ # create generic gem task
16
+ File.open("tasks/gem.rake", 'w') do |gem_rake|
17
+ gem_rake.puts template_rake_gemspec(gem_name)
18
+ end
19
+ end
20
+
21
+ def generate_extension_task_for(extension_name, platform = nil)
22
+ # create folder structure
23
+ FileUtils.mkdir_p "ext/#{extension_name}"
24
+
25
+ return if File.exist?("tasks/#{extension_name}.rake")
26
+
27
+ # Building a gem?
28
+ if File.exist?("tasks/gem.rake") then
29
+ File.open("tasks/gem.rake", 'a+') do |ext_in_gem|
30
+ if platform
31
+ ext_in_gem.puts template_rake_extension_with_platform(extension_name, platform)
32
+ else
33
+ ext_in_gem.puts template_rake_extension(extension_name, true)
34
+ end
35
+ end
36
+ else
37
+ # create specific extension rakefile
38
+ File.open("tasks/#{extension_name}.rake", 'w') do |ext_rake|
39
+ ext_rake.puts template_rake_extension(extension_name)
40
+ end
41
+ end
42
+ end
43
+
44
+ def generate_cross_compile_extension_task_for(extension_name)
45
+ # create folder structure
46
+ FileUtils.mkdir_p "ext/#{extension_name}"
47
+
48
+ return if File.exist?("tasks/#{extension_name}.rake")
49
+
50
+ # create specific extension rakefile
51
+ # Building a gem?
52
+ if File.exist?("tasks/gem.rake") then
53
+ File.open("tasks/gem.rake", 'a+') do |ext_in_gem|
54
+ ext_in_gem.puts template_rake_extension_cross_compile(extension_name, true)
55
+ end
56
+ else
57
+ File.open("tasks/#{extension_name}.rake", 'w') do |ext_rake|
58
+ ext_rake.puts template_rake_extension_cross_compile(extension_name)
59
+ end
60
+ end
61
+ end
62
+
63
+ def generate_java_compile_extension_task_for(extension_name)
64
+ # create folder structure
65
+ FileUtils.mkdir_p "ext/#{extension_name}"
66
+
67
+ return if File.exist?("tasks/#{extension_name}.rake")
68
+
69
+ # create specific extension rakefile
70
+ # Building a gem?
71
+ if File.exist?("tasks/gem.rake") then
72
+ File.open("tasks/gem.rake", 'a+') do |ext_in_gem|
73
+ ext_in_gem.puts template_rake_extension_java_compile(extension_name, true)
74
+ end
75
+ else
76
+ File.open("tasks/#{extension_name}.rake", 'w') do |ext_rake|
77
+ ext_rake.puts template_rake_extension_java_compile(extension_name)
78
+ end
79
+ end
80
+ end
81
+
82
+ def generate_multi_cross_compile_extension_task_for(extension_name)
83
+ # create folder structure
84
+ FileUtils.mkdir_p "ext/#{extension_name}"
85
+
86
+ return if File.exist?("tasks/#{extension_name}.rake")
87
+
88
+ # create specific extension rakefile
89
+ # Building a gem?
90
+ if File.exist?("tasks/gem.rake") then
91
+ File.open("tasks/gem.rake", 'a+') do |ext_in_gem|
92
+ ext_in_gem.puts template_rake_extension_multi_cross_compile(extension_name)
93
+ end
94
+ end
95
+ end
96
+
97
+ def generate_source_code_for(extension_name)
98
+ # source C file
99
+ File.open("ext/#{extension_name}/source.c", 'w') do |c|
100
+ c.puts template_source_c(extension_name)
101
+ end
102
+
103
+ # header H file
104
+ File.open("ext/#{extension_name}/source.h", 'w') do |h|
105
+ h.puts template_source_h
106
+ end
107
+
108
+ # extconf.rb file
109
+ File.open("ext/#{extension_name}/extconf.rb", 'w') do |ext|
110
+ ext.puts template_extconf(extension_name)
111
+ end
112
+ end
113
+
114
+ def generate_java_source_code_for(extension_name)
115
+ # source .java file
116
+ File.open("ext/#{extension_name}/#{camelize(extension_name)}Service.java", 'w') do |c|
117
+ c.puts template_source_java(extension_name)
118
+ end
119
+ end
120
+
121
+ end
122
+
123
+ World(GeneratorHelpers)
@@ -0,0 +1,27 @@
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
+ when /java/
9
+ 'jar'
10
+ else
11
+ RbConfig::CONFIG['DLEXT']
12
+ end
13
+ end
14
+
15
+ def search_path(binaries)
16
+ paths = ENV['PATH'].split(File::PATH_SEPARATOR)
17
+ binary = binaries.find do |bin_file|
18
+ paths.find do |path|
19
+ bin = File.join(path, bin_file)
20
+ File.exist?(bin) && File.executable?(bin)
21
+ end
22
+ end
23
+ binary
24
+ end
25
+ end
26
+
27
+ World(PlatformExtensionHelpers)
@@ -0,0 +1,90 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'rake'
4
+ require 'rake/clean'
5
+ require 'rake/tasklib'
6
+ require 'rbconfig'
7
+
8
+ begin
9
+ require 'psych'
10
+ rescue LoadError
11
+ end
12
+
13
+ require 'yaml'
14
+ require 'pathname'
15
+
16
+ module Rake
17
+ class BaseExtensionTask < TaskLib
18
+
19
+ attr_accessor :name
20
+ attr_accessor :gem_spec
21
+ attr_accessor :tmp_dir
22
+ attr_accessor :ext_dir
23
+ attr_accessor :lib_dir
24
+ attr_accessor :platform
25
+ attr_accessor :config_options
26
+ attr_accessor :source_pattern
27
+ attr_accessor :extra_options
28
+
29
+ def platform
30
+ @platform ||= RUBY_PLATFORM
31
+ end
32
+
33
+ def initialize(name = nil, gem_spec = nil)
34
+ init(name, gem_spec)
35
+ yield self if block_given?
36
+ define
37
+ end
38
+
39
+ def init(name = nil, gem_spec = nil)
40
+ @name = name
41
+ @gem_spec = gem_spec
42
+ @tmp_dir = 'tmp'
43
+ @ext_dir = "ext/#{@name}"
44
+ @lib_dir = 'lib'
45
+ @config_options = []
46
+ @extra_options = ARGV.select { |i| i =~ /\A--?/ }
47
+ end
48
+
49
+ def define
50
+ fail "Extension name must be provided." if @name.nil?
51
+
52
+ define_compile_tasks
53
+ end
54
+
55
+ private
56
+
57
+ def define_compile_tasks
58
+ raise NotImplementedError
59
+ end
60
+
61
+ def binary(platform = nil)
62
+ ext = case platform
63
+ when /darwin/
64
+ 'bundle'
65
+ when /mingw|mswin|linux/
66
+ 'so'
67
+ when /java/
68
+ 'jar'
69
+ else
70
+ RbConfig::CONFIG['DLEXT']
71
+ end
72
+ "#{@name}.#{ext}"
73
+ end
74
+
75
+ def source_files
76
+ FileList["#{@ext_dir}/#{@source_pattern}"]
77
+ end
78
+
79
+ def warn_once(message)
80
+ @@already_warned ||= false
81
+ return if @@already_warned
82
+ @@already_warned = true
83
+ warn message
84
+ end
85
+
86
+ def windows?
87
+ Rake.application.windows?
88
+ end
89
+ end
90
+ end