rake-compiler 0.3.0 → 0.5.0
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.
- data/History.txt +62 -9
- data/Rakefile +1 -1
- data/features/cross-package-multi.feature +15 -0
- data/features/step_definitions/compilation.rb +11 -0
- data/features/step_definitions/cross_compilation.rb +17 -7
- data/features/step_definitions/gem.rb +2 -1
- data/features/support/{file_templates.rb → file_template_helpers.rb} +36 -22
- data/features/support/generator_helpers.rb +96 -0
- data/lib/rake/extensioncompiler.rb +53 -0
- data/lib/rake/extensiontask.rb +102 -35
- data/spec/lib/rake/extensiontask_spec.rb +86 -43
- data/spec/spec_helper.rb +6 -0
- data/spec/support/capture_output_helper.rb +22 -0
- data/tasks/bin/cross-ruby.rake +34 -14
- data/tasks/common.rake +3 -0
- data/tasks/cucumber.rake +2 -1
- data/tasks/gem.rake +7 -9
- data/tasks/news.rake +82 -0
- data/tasks/rdoc.rake +13 -7
- data/tasks/rdoc_publish.rake +44 -0
- data/tasks/release.rake +2 -7
- data/tasks/rspec.rake +10 -9
- metadata +16 -7
- data/features/support/generators.rb +0 -77
data/History.txt
CHANGED
|
@@ -1,32 +1,85 @@
|
|
|
1
|
-
=== 0.
|
|
1
|
+
=== 0.5.0 / 2009-04-25
|
|
2
|
+
|
|
3
|
+
* Enhancements
|
|
4
|
+
* Allow generation of multiple gems for Windows (EXPERIMENTAL)
|
|
5
|
+
This allows build gems for both VC6 and MinGW builts of Ruby
|
|
6
|
+
(Thanks to Jonathan Stott for the suggestion)
|
|
7
|
+
|
|
8
|
+
Rake::ExtensionTask.new('my_extension', GEM_SPEC) do |ext|
|
|
9
|
+
ext.cross_compile = true
|
|
10
|
+
ext.cross_platform = ['i386-mswin32', 'i386-mingw32']
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
=== 0.4.1 / 2009-04-09
|
|
14
|
+
|
|
15
|
+
* Enhancements
|
|
16
|
+
* Target specific versions of Ruby when generating binaries.
|
|
17
|
+
This avoids installing a 1.8.x binary gem in 1.9.x and viceversa.
|
|
18
|
+
(Thanks to Aaron Patterson for the patches)
|
|
19
|
+
|
|
20
|
+
* Bugfixes
|
|
21
|
+
* No longer raises error if rake-compiler configuration is missing.
|
|
22
|
+
Not all users of a project would have it installed.
|
|
23
|
+
(Thanks to Aaron Patterson for the patch)
|
|
24
|
+
|
|
25
|
+
=== 0.4.0 / 2009-04-03
|
|
26
|
+
|
|
27
|
+
* Enhancements
|
|
28
|
+
* Bended the convention for extension folder.
|
|
29
|
+
Defining <tt>ext_dir</tt> for custom extension location.
|
|
30
|
+
|
|
31
|
+
Rake::ExtensionTask.new('my_extension') do |ext|
|
|
32
|
+
ext.ext_dir = 'custom/location' # look into custom/location
|
|
33
|
+
end # instead of ext/my_extension
|
|
2
34
|
|
|
3
|
-
*
|
|
35
|
+
* Better detection of mingw target across Linux/OSX.
|
|
36
|
+
Exposed it as Rake::ExtensionCompiler
|
|
37
|
+
* Display list of available tasks when calling rake-compiler script
|
|
38
|
+
* Track Ruby full versioning (x.y.z).
|
|
39
|
+
This will help the compilation of extensions targetting 1.8.6/7 and 1.9.1
|
|
4
40
|
|
|
41
|
+
* Bugfixes
|
|
42
|
+
* Better output of Rake development tasks (Thanks to Luis Parravicini).
|
|
43
|
+
* Proper usage of Gem::Platform for native gems (Thanks to Dirkjan Bussink).
|
|
44
|
+
* Don't use autoload for YAML (present problems with Ruby 1.9.1).
|
|
45
|
+
|
|
46
|
+
=== 0.3.1 / 2009-01-09
|
|
47
|
+
|
|
48
|
+
* Enhancements
|
|
49
|
+
* Download cross-ruby source code using HTTP instead of FTP.
|
|
50
|
+
* Disabled Tcl/Tk extension building on cross-ruby (helps with 1.9).
|
|
51
|
+
|
|
52
|
+
* Bugfixes
|
|
53
|
+
* Workaround bug introduced by lack of Gem::Specification cloning. Fixes DM LH #757.
|
|
54
|
+
* Use proper binary extension on OSX (reported by Dirkjan Bussink).
|
|
55
|
+
* Ensure lib/binary task is defined prior clear of requisites.
|
|
56
|
+
|
|
57
|
+
=== 0.3.0 / 2008-12-07
|
|
58
|
+
|
|
59
|
+
* New features
|
|
5
60
|
* Let you specify the Ruby version used for cross compilation instead
|
|
6
61
|
of default one.
|
|
7
62
|
|
|
8
63
|
rake cross compile RUBY_CC_VERSION=1.8
|
|
9
64
|
|
|
10
|
-
*
|
|
11
|
-
|
|
65
|
+
* Enhancements
|
|
12
66
|
* Properly update rake-compiler configuration when new version is installed.
|
|
13
67
|
* Automated release process to RubyForge, yay!
|
|
14
68
|
|
|
15
|
-
*
|
|
16
|
-
|
|
69
|
+
* Bugfixes
|
|
17
70
|
* Corrected documentation to reflect the available options
|
|
18
71
|
|
|
19
72
|
=== 0.2.1 / 2008-11-30
|
|
20
73
|
|
|
21
|
-
*
|
|
74
|
+
* New features
|
|
22
75
|
|
|
23
76
|
* Allow cross compilation (cross compile) using mingw32 on Linux or OSX.
|
|
24
77
|
* Allow packaging of gems for Windows on Linux or OSX.
|
|
25
78
|
|
|
26
|
-
*
|
|
79
|
+
* Enhancements
|
|
27
80
|
|
|
28
81
|
* Made generation of extensions safe and target folders per-platform
|
|
29
82
|
|
|
30
|
-
*
|
|
83
|
+
* Bugfixes
|
|
31
84
|
|
|
32
85
|
* Ensure binaries for the specific platform are copied before packaging.
|
data/Rakefile
CHANGED
|
@@ -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' get generated
|
|
15
|
+
And gem for platform 'x86-mingw32' 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 '(.*)' multi cross\-compilable$/ do |extension_name|
|
|
12
|
+
generate_multi_cross_compile_extension_task_for extension_name
|
|
13
|
+
generate_source_code_for extension_name
|
|
14
|
+
end
|
|
15
|
+
|
|
11
16
|
Given /^a extension '(.*)' with forced platform '(.*)'$/ do |extension_name, forced_platform|
|
|
12
17
|
generate_extension_task_for extension_name, forced_platform
|
|
13
18
|
generate_source_code_for extension_name
|
|
@@ -24,6 +29,12 @@ Given /^that my gem source is all in place$/ do
|
|
|
24
29
|
Given "a extension cross-compilable 'extension_one'"
|
|
25
30
|
end
|
|
26
31
|
|
|
32
|
+
Given /^that my gem source is all in place to target two platforms$/ do
|
|
33
|
+
Given "a safe project directory"
|
|
34
|
+
Given "a gem named 'gem_abc'"
|
|
35
|
+
Given "a extension 'extension_one' multi cross-compilable"
|
|
36
|
+
end
|
|
37
|
+
|
|
27
38
|
Given /^not changed any file since$/ do
|
|
28
39
|
# don't do anything, that's the purpose of this step!
|
|
29
40
|
end
|
|
@@ -6,16 +6,26 @@ Given %r{^I'm running a POSIX operating system$} do
|
|
|
6
6
|
end
|
|
7
7
|
|
|
8
8
|
Given %r{^I've installed cross compile toolchain$} do
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
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
|
|
14
15
|
end
|
|
15
|
-
raise "Cannot locate '#{compiler}' in the PATH." unless
|
|
16
|
+
raise "Cannot locate '#{compiler}' in the PATH." unless compiler
|
|
16
17
|
end
|
|
17
18
|
|
|
18
19
|
Then /^binaries for platform '(.*)' get generated$/ do |platform|
|
|
19
|
-
|
|
20
|
+
ext = case platform
|
|
21
|
+
when /darwin/
|
|
22
|
+
'bundle'
|
|
23
|
+
when /mingw|mswin|linux/
|
|
24
|
+
'so'
|
|
25
|
+
else
|
|
26
|
+
RbConfig::CONFIG['DLEXT']
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
ext_for_platform = Dir.glob("tmp/#{platform}/**/*.#{ext}")
|
|
20
30
|
ext_for_platform.should_not be_empty
|
|
21
31
|
end
|
|
@@ -24,6 +24,7 @@ end
|
|
|
24
24
|
|
|
25
25
|
def gem_file_platform(folder, name, version, platform = nil)
|
|
26
26
|
file = "#{folder}/#{name}-#{version}"
|
|
27
|
-
file << "-" << (platform || Gem::Platform.
|
|
27
|
+
file << "-" << (platform || Gem::Platform.new(RUBY_PLATFORM).to_s)
|
|
28
28
|
file << ".gem"
|
|
29
|
+
file
|
|
29
30
|
end
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
module FileTemplateHelpers
|
|
2
|
+
def template_rakefile
|
|
3
|
+
<<-EOF
|
|
3
4
|
# add rake-compiler lib dir to the LOAD_PATH
|
|
4
5
|
$LOAD_PATH.unshift File.expand_path(File.join(File.dirname(__FILE__), '../..', 'lib'))
|
|
5
6
|
|
|
@@ -9,10 +10,10 @@ require 'rake'
|
|
|
9
10
|
# load rakefile extensions (tasks)
|
|
10
11
|
Dir['tasks/*.rake'].each { |f| import f }
|
|
11
12
|
EOF
|
|
12
|
-
end
|
|
13
|
+
end
|
|
13
14
|
|
|
14
|
-
def template_rake_gemspec(gem_name)
|
|
15
|
-
<<-EOF
|
|
15
|
+
def template_rake_gemspec(gem_name)
|
|
16
|
+
<<-EOF
|
|
16
17
|
require 'rake/gempackagetask'
|
|
17
18
|
SPEC = Gem::Specification.new do |s|
|
|
18
19
|
s.name = "#{gem_name}"
|
|
@@ -37,52 +38,65 @@ gem_package = Rake::GemPackageTask.new(SPEC) do |pkg|
|
|
|
37
38
|
pkg.need_tar = false
|
|
38
39
|
end
|
|
39
40
|
EOF
|
|
40
|
-
end
|
|
41
|
+
end
|
|
41
42
|
|
|
42
|
-
def template_rake_extension(extension_name, gem_spec = nil)
|
|
43
|
-
<<-EOF
|
|
43
|
+
def template_rake_extension(extension_name, gem_spec = nil)
|
|
44
|
+
<<-EOF
|
|
44
45
|
require 'rake/extensiontask'
|
|
45
46
|
Rake::ExtensionTask.new("#{extension_name}"#{', SPEC' if gem_spec})
|
|
46
47
|
EOF
|
|
47
|
-
end
|
|
48
|
+
end
|
|
48
49
|
|
|
49
|
-
def template_rake_extension_with_platform(extension_name, platform)
|
|
50
|
-
<<-EOF
|
|
50
|
+
def template_rake_extension_with_platform(extension_name, platform)
|
|
51
|
+
<<-EOF
|
|
51
52
|
require 'rake/extensiontask'
|
|
52
53
|
Rake::ExtensionTask.new("#{extension_name}", SPEC) do |ext|
|
|
53
54
|
ext.platform = "#{platform}"
|
|
54
55
|
end
|
|
55
56
|
EOF
|
|
56
|
-
end
|
|
57
|
+
end
|
|
57
58
|
|
|
58
|
-
def template_rake_extension_cross_compile(extension_name, gem_spec = nil)
|
|
59
|
-
<<-EOF
|
|
59
|
+
def template_rake_extension_cross_compile(extension_name, gem_spec = nil)
|
|
60
|
+
<<-EOF
|
|
60
61
|
require 'rake/extensiontask'
|
|
61
62
|
Rake::ExtensionTask.new("#{extension_name}"#{', SPEC' if gem_spec}) do |ext|
|
|
62
63
|
ext.cross_compile = true
|
|
63
64
|
end
|
|
64
65
|
EOF
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def template_rake_extension_multi_cross_compile(extension_name)
|
|
69
|
+
<<-EOF
|
|
70
|
+
require 'rake/extensiontask'
|
|
71
|
+
Rake::ExtensionTask.new("#{extension_name}", SPEC) do |ext|
|
|
72
|
+
ext.cross_compile = true
|
|
73
|
+
ext.cross_platform = ['i386-mswin32', 'i386-mingw32']
|
|
65
74
|
end
|
|
75
|
+
EOF
|
|
76
|
+
end
|
|
66
77
|
|
|
67
|
-
def template_extconf(extension_name)
|
|
68
|
-
<<-EOF
|
|
78
|
+
def template_extconf(extension_name)
|
|
79
|
+
<<-EOF
|
|
69
80
|
require 'mkmf'
|
|
70
81
|
create_makefile("#{extension_name}")
|
|
71
82
|
EOF
|
|
72
|
-
end
|
|
83
|
+
end
|
|
73
84
|
|
|
74
|
-
def template_source_c(extension_name)
|
|
75
|
-
<<-EOF
|
|
85
|
+
def template_source_c(extension_name)
|
|
86
|
+
<<-EOF
|
|
76
87
|
#include "source.h"
|
|
77
88
|
void Init_#{extension_name}()
|
|
78
89
|
{
|
|
79
90
|
printf("source.c of extension #{extension_name}\\n");
|
|
80
91
|
}
|
|
81
92
|
EOF
|
|
82
|
-
end
|
|
93
|
+
end
|
|
83
94
|
|
|
84
|
-
def template_source_h
|
|
85
|
-
<<-EOF
|
|
95
|
+
def template_source_h
|
|
96
|
+
<<-EOF
|
|
86
97
|
#include "ruby.h"
|
|
87
98
|
EOF
|
|
99
|
+
end
|
|
88
100
|
end
|
|
101
|
+
|
|
102
|
+
World(FileTemplateHelpers)
|
|
@@ -0,0 +1,96 @@
|
|
|
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_multi_cross_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_multi_cross_compile(extension_name)
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
def generate_source_code_for(extension_name)
|
|
79
|
+
# source C file
|
|
80
|
+
File.open("ext/#{extension_name}/source.c", 'w') do |c|
|
|
81
|
+
c.puts template_source_c(extension_name)
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
# header H file
|
|
85
|
+
File.open("ext/#{extension_name}/source.h", 'w') do |h|
|
|
86
|
+
h.puts template_source_h
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
# extconf.rb file
|
|
90
|
+
File.open("ext/#{extension_name}/extconf.rb", 'w') do |ext|
|
|
91
|
+
ext.puts template_extconf(extension_name)
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
World(GeneratorHelpers)
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
|
|
3
|
+
module Rake
|
|
4
|
+
|
|
5
|
+
#
|
|
6
|
+
# HACK: Lousy API design, sue me. At least works ;-)
|
|
7
|
+
#
|
|
8
|
+
# Define a series of helpers to aid in search and usage of MinGW (GCC) Compiler
|
|
9
|
+
# by gem developer/creators.
|
|
10
|
+
#
|
|
11
|
+
module ExtensionCompiler
|
|
12
|
+
# return the host portion from the installed MinGW
|
|
13
|
+
def self.mingw_host
|
|
14
|
+
return @mingw_host if @mingw_host
|
|
15
|
+
|
|
16
|
+
# the mingw_gcc_executable is helpful here
|
|
17
|
+
if target = mingw_gcc_executable then
|
|
18
|
+
# we only care for the filename
|
|
19
|
+
target = File.basename(target)
|
|
20
|
+
|
|
21
|
+
# now strip the extension (if present)
|
|
22
|
+
target.sub!(File.extname(target), '')
|
|
23
|
+
|
|
24
|
+
# get rid of '-gcc' portion too ;-)
|
|
25
|
+
target.sub!('-gcc', '')
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
raise "No MinGW tools or unknown setup platform?" unless target
|
|
29
|
+
|
|
30
|
+
@mingw_host = target
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
# return the first compiler found that includes both mingw and gcc conditions
|
|
34
|
+
# (this assumes you have one installed)
|
|
35
|
+
def self.mingw_gcc_executable
|
|
36
|
+
return @mingw_gcc_executable if @mingw_gcc_executable
|
|
37
|
+
|
|
38
|
+
# grab the paths defined in the environment
|
|
39
|
+
paths = ENV['PATH'].split(File::PATH_SEPARATOR)
|
|
40
|
+
|
|
41
|
+
# the pattern to look into (captures *nix and windows executables)
|
|
42
|
+
pattern = "*mingw*gcc{,.*}"
|
|
43
|
+
|
|
44
|
+
@mingw_gcc_executable = paths.find do |path|
|
|
45
|
+
# cleanup paths before globbing
|
|
46
|
+
gcc = Dir.glob("#{File.expand_path(path)}/#{pattern}").first
|
|
47
|
+
break gcc if gcc
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
@mingw_gcc_executable
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|