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.
- checksums.yaml +7 -0
- data/Gemfile +8 -0
- data/History.txt +308 -0
- data/LICENSE.txt +20 -0
- data/README.rdoc +415 -0
- data/Rakefile +15 -0
- data/bin/rake-compiler +24 -0
- data/cucumber.yml +4 -0
- data/features/compile.feature +79 -0
- data/features/cross-compile.feature +23 -0
- data/features/cross-package-multi.feature +15 -0
- data/features/cross-package.feature +14 -0
- data/features/java-compile.feature +22 -0
- data/features/java-no-native-compile.feature +33 -0
- data/features/java-package.feature +24 -0
- data/features/package.feature +40 -0
- data/features/step_definitions/compilation.rb +70 -0
- data/features/step_definitions/cross_compilation.rb +27 -0
- data/features/step_definitions/execution.rb +52 -0
- data/features/step_definitions/folders.rb +32 -0
- data/features/step_definitions/gem.rb +46 -0
- data/features/step_definitions/java_compilation.rb +7 -0
- data/features/support/env.rb +10 -0
- data/features/support/file_template_helpers.rb +137 -0
- data/features/support/generator_helpers.rb +123 -0
- data/features/support/platform_extension_helpers.rb +27 -0
- data/lib/rake/baseextensiontask.rb +90 -0
- data/lib/rake/extensioncompiler.rb +53 -0
- data/lib/rake/extensiontask.rb +513 -0
- data/lib/rake/javaextensiontask.rb +226 -0
- data/spec/lib/rake/extensiontask_spec.rb +501 -0
- data/spec/lib/rake/javaextensiontask_spec.rb +182 -0
- data/spec/spec.opts +3 -0
- data/spec/spec_helper.rb +15 -0
- data/spec/support/capture_output_helper.rb +22 -0
- data/tasks/bin/cross-ruby.rake +213 -0
- data/tasks/bootstrap.rake +11 -0
- data/tasks/common.rake +10 -0
- data/tasks/cucumber.rake +23 -0
- data/tasks/gem.rake +52 -0
- data/tasks/news.rake +39 -0
- data/tasks/release.rake +26 -0
- data/tasks/rspec.rake +9 -0
- 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,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
|