gem-compile 0.0.2 → 0.0.3
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +5 -5
- data/bin/gem-compile +72 -13
- data/lib/rubygems/commands/compile_command.rb +19 -4
- data/lib/rubygems/compiler.rb +55 -11
- metadata +2 -2
data/README.md
CHANGED
@@ -1,12 +1,12 @@
|
|
1
1
|
gem-compile
|
2
2
|
===========
|
3
|
-
|
3
|
+
A RubyGems command plugin that creates pre-compiled binary gems from gems with extensions.
|
4
4
|
|
5
5
|
|
6
6
|
## Overview
|
7
7
|
|
8
|
-
gem-compile is a
|
9
|
-
It creates binary gems from gems with extensions.
|
8
|
+
gem-compile is a RubyGems command plugin that adds 'compile' command.
|
9
|
+
It creates pre-compiled binary gems from gems with extensions.
|
10
10
|
|
11
11
|
|
12
12
|
## Installation
|
@@ -30,10 +30,10 @@ It creates binary gems from gems with extensions.
|
|
30
30
|
## Example
|
31
31
|
|
32
32
|
$ gem compile msgpack-0.3.4.gem
|
33
|
-
With above command line, msgpack-0.3.4-x86-mingw32.gem file will be created on MinGW environment.
|
33
|
+
With above command line, **msgpack-0.3.4-x86-mingw32.gem** file will be created on MinGW environment.
|
34
34
|
|
35
35
|
$ gem compile --platform mswin32 msgpack-0.3.4.gem
|
36
|
-
With above command line, msgpack-0.3.4-x86-mswin32.gem file will be created.
|
36
|
+
With above command line, **msgpack-0.3.4-x86-mswin32.gem** file will be created.
|
37
37
|
|
38
38
|
|
39
39
|
## License
|
data/bin/gem-compile
CHANGED
@@ -33,12 +33,15 @@ if ARGV.include?('--')
|
|
33
33
|
end
|
34
34
|
|
35
35
|
config = {
|
36
|
-
:platform => nil
|
36
|
+
:platform => nil,
|
37
|
+
:fat => nil,
|
37
38
|
}
|
38
39
|
|
39
40
|
op = OptionParser.new
|
40
41
|
op.on('-p', '--platform PLATFORM',
|
41
42
|
'Output platform name') {|s| config[:platform] = s }
|
43
|
+
op.on('-f', '--fat VERSION:RUBY,...',
|
44
|
+
'Create fat binary (e.g. --fat 1.8:ruby,1.9:ruby19)') {|s| config[:fat] = s }
|
42
45
|
|
43
46
|
op.banner += " GEMFILE -- --build-flags"
|
44
47
|
|
@@ -53,11 +56,13 @@ end
|
|
53
56
|
require 'rubygems/format'
|
54
57
|
require 'rubygems/ext'
|
55
58
|
require 'rubygems/builder'
|
59
|
+
require 'shellwords'
|
56
60
|
|
57
61
|
Gem::Command.build_args = build_args if build_args
|
58
62
|
|
59
63
|
gem = args.first
|
60
|
-
platform = config[:platform] || Gem::Platform::
|
64
|
+
platform = config[:platform] || Gem::Platform::CURRENT
|
65
|
+
fat = config[:fat]
|
61
66
|
|
62
67
|
|
63
68
|
gem_dir = "#{File.basename(gem)}.build"
|
@@ -82,10 +87,21 @@ if spec.platform != Gem::Platform::RUBY
|
|
82
87
|
exit 1
|
83
88
|
end
|
84
89
|
|
90
|
+
fat_commands = {}
|
91
|
+
if fat
|
92
|
+
fat.split(',').each do |ver_cmd|
|
93
|
+
ver, cmd = ver_cmd.split(':', 2)
|
94
|
+
unless ver =~ /^\d+\.\d+$/
|
95
|
+
puts "Invalid version string #{ver.dump}"
|
96
|
+
exit 1
|
97
|
+
end
|
98
|
+
fat_commands[ver] = cmd
|
99
|
+
end
|
100
|
+
end
|
85
101
|
|
86
102
|
format.file_entries.each do |entry, file_data|
|
87
103
|
path = entry['path'].untaint
|
88
|
-
|
104
|
+
path = File.expand_path File.join(gem_dir, path)
|
89
105
|
|
90
106
|
FileUtils.rm_rf(path) if File.exists?(path)
|
91
107
|
FileUtils.mkdir_p File.dirname(path)
|
@@ -101,7 +117,7 @@ end
|
|
101
117
|
|
102
118
|
ran_rake = false
|
103
119
|
start_dir = Dir.pwd
|
104
|
-
|
120
|
+
built_paths = []
|
105
121
|
|
106
122
|
spec.extensions.each do |extension|
|
107
123
|
break if ran_rake
|
@@ -117,22 +133,66 @@ spec.extensions.each do |extension|
|
|
117
133
|
Gem::Ext::RakeBuilder
|
118
134
|
else
|
119
135
|
results = ["No builder for extension '#{extension}'"]
|
120
|
-
|
136
|
+
raise results.last
|
121
137
|
end
|
122
138
|
|
123
139
|
begin
|
124
|
-
|
125
|
-
|
140
|
+
dest_path = File.join(gem_dir, File.dirname(extension))
|
141
|
+
extension = File.expand_path(extension)
|
142
|
+
Dir.chdir dest_path
|
143
|
+
|
144
|
+
if fat_commands.empty?
|
145
|
+
results = builder.build(extension, gem_dir, dest_path, results)
|
146
|
+
|
147
|
+
built_paths.concat Dir.glob("#{dest_path}/**/*")
|
148
|
+
|
149
|
+
else
|
150
|
+
ext_files = []
|
151
|
+
|
152
|
+
fat_commands.each_pair do |version, command|
|
153
|
+
version_path = File.join(dest_path, version)
|
154
|
+
|
155
|
+
script = <<-EOF
|
156
|
+
require 'rubygems/ext'
|
157
|
+
puts #{builder}.build(#{extension.dump},#{gem_dir.dump},#{version_path.dump}, [])
|
158
|
+
EOF
|
159
|
+
|
160
|
+
result = `#{command} -e #{Shellwords.escape script}`
|
161
|
+
results << result
|
162
|
+
if $? != 0
|
163
|
+
raise result
|
164
|
+
end
|
165
|
+
|
166
|
+
paths = Dir.glob("#{version_path}/**/*")
|
167
|
+
files = paths.map {|path| path[File.join(version_path,'').length..-1] }
|
168
|
+
ext_files.concat files
|
169
|
+
|
170
|
+
built_paths.concat paths
|
171
|
+
end
|
172
|
+
|
173
|
+
ext_files.uniq.each do |ext_name|
|
174
|
+
ext_basename = ext_name.sub(/\.[^\.]*$/, '')
|
175
|
+
rb_path = File.join(dest_path, "#{ext_basename}.rb")
|
176
|
+
File.open(rb_path, "w") do |f|
|
177
|
+
f.write <<-EOF
|
178
|
+
require File.join File.dirname(__FILE__), RUBY_VERSION.match(/\\d+\\.\\d+/)[0], #{ext_basename.dump}
|
179
|
+
EOF
|
180
|
+
end
|
181
|
+
|
182
|
+
built_paths << rb_path
|
183
|
+
end
|
184
|
+
|
185
|
+
end
|
126
186
|
|
127
187
|
puts results.join("\n")
|
128
188
|
|
129
189
|
rescue => ex
|
130
190
|
results = results.join "\n"
|
131
191
|
|
132
|
-
File.open('gem_make.out', 'wb') {
|
192
|
+
File.open('gem_make.out', 'wb') {|f| f.puts results }
|
133
193
|
|
134
|
-
|
135
|
-
ERROR: Failed to build gem native extension.
|
194
|
+
message = <<-EOF
|
195
|
+
ERROR: Failed to build gem native extension.
|
136
196
|
|
137
197
|
#{results}
|
138
198
|
|
@@ -148,9 +208,8 @@ end
|
|
148
208
|
|
149
209
|
spec.extensions = []
|
150
210
|
|
151
|
-
built_files =
|
152
|
-
|
153
|
-
built_files.each {|path| path.slice!(0, basedir.length) }
|
211
|
+
built_files = built_paths.map {|path| path[File.join(gem_dir,'').length..-1] }
|
212
|
+
built_files.reject! {|path| path =~ /\.o$/ } # FIXME
|
154
213
|
|
155
214
|
spec.files = (spec.files + built_files).sort.uniq
|
156
215
|
spec.platform = platform if platform
|
@@ -4,11 +4,16 @@ require 'rubygems/compiler'
|
|
4
4
|
class Gem::Commands::CompileCommand < Gem::Command
|
5
5
|
def initialize
|
6
6
|
super 'compile', 'Create binary gems from gems with extensions',
|
7
|
-
:platform => Gem::Platform::CURRENT
|
7
|
+
:platform => Gem::Platform::CURRENT,
|
8
|
+
:fat => ""
|
8
9
|
|
9
10
|
add_option('-p', '--platform PLATFORM', 'Output platform name') do |value, options|
|
10
11
|
options[:platform] = value
|
11
12
|
end
|
13
|
+
|
14
|
+
add_option('-f', '--fat VERSION:RUBY,...', 'Create fat binary (e.g. --fat 1.8:ruby,1.9:ruby19)') do |value, options|
|
15
|
+
options[:fat] = value
|
16
|
+
end
|
12
17
|
end
|
13
18
|
|
14
19
|
def arguments # :nodoc:
|
@@ -23,11 +28,21 @@ class Gem::Commands::CompileCommand < Gem::Command
|
|
23
28
|
gem = options[:args].shift
|
24
29
|
|
25
30
|
unless gem then
|
26
|
-
|
27
|
-
|
31
|
+
raise Gem::CommandLineError,
|
32
|
+
"Please specify a gem name or file on the command line"
|
28
33
|
end
|
29
34
|
|
30
|
-
|
35
|
+
fat_commands = {}
|
36
|
+
options[:fat].split(',').each do |ver_cmd|
|
37
|
+
ver, cmd = ver_cmd.split(':', 2)
|
38
|
+
unless ver =~ /^\d+\.\d+$/ then
|
39
|
+
raise Gem::CommandLineError,
|
40
|
+
"Invalid version string #{ver.dump}"
|
41
|
+
end
|
42
|
+
fat_commands[ver] = cmd
|
43
|
+
end
|
44
|
+
|
45
|
+
Gem::Compiler.compile(gem, options[:platform], fat_commands)
|
31
46
|
end
|
32
47
|
end
|
33
48
|
|
data/lib/rubygems/compiler.rb
CHANGED
@@ -4,12 +4,13 @@ require 'rubygems/builder'
|
|
4
4
|
require 'rubygems/exceptions'
|
5
5
|
require 'rubygems/user_interaction'
|
6
6
|
require 'fileutils'
|
7
|
+
require 'shellwords'
|
7
8
|
|
8
9
|
class Gem::Compiler
|
9
10
|
|
10
11
|
extend Gem::UserInteraction
|
11
12
|
|
12
|
-
def self.compile(gem, platform = Gem::Platform::CURRENT)
|
13
|
+
def self.compile(gem, platform = Gem::Platform::CURRENT, fat_commands = {})
|
13
14
|
gem_dir = "#{File.basename(gem)}.build"
|
14
15
|
gem_dir = File.expand_path(gem_dir)
|
15
16
|
|
@@ -43,7 +44,7 @@ class Gem::Compiler
|
|
43
44
|
|
44
45
|
ran_rake = false
|
45
46
|
start_dir = Dir.pwd
|
46
|
-
|
47
|
+
built_paths = []
|
47
48
|
|
48
49
|
spec.extensions.each do |extension|
|
49
50
|
break if ran_rake
|
@@ -59,29 +60,73 @@ class Gem::Compiler
|
|
59
60
|
Gem::Ext::RakeBuilder
|
60
61
|
else
|
61
62
|
results = ["No builder for extension '#{extension}'"]
|
62
|
-
|
63
|
+
raise results.last
|
63
64
|
end
|
64
65
|
|
65
66
|
begin
|
66
|
-
|
67
|
-
|
67
|
+
dest_path = File.join(gem_dir, File.dirname(extension))
|
68
|
+
Dir.chdir dest_path
|
69
|
+
|
70
|
+
if fat_commands.empty?
|
71
|
+
results = builder.build(extension, gem_dir, dest_path, results)
|
72
|
+
|
73
|
+
built_paths.concat Dir.glob("#{dest_path}/**/*")
|
74
|
+
|
75
|
+
else
|
76
|
+
ext_files = []
|
77
|
+
|
78
|
+
fat_commands.each_pair do |version, command|
|
79
|
+
version_path = File.join(dest_path, version)
|
80
|
+
|
81
|
+
script = <<-EOF
|
82
|
+
require "rubygems/ext"; puts #{builder}.build(#{extension.dump},#{gem_dir.dump},#{version_path.dump}, [])
|
83
|
+
EOF
|
84
|
+
script.strip!
|
85
|
+
|
86
|
+
result = `#{command} -e '#{script}'`
|
87
|
+
results << result
|
88
|
+
if $? != 0
|
89
|
+
raise result
|
90
|
+
end
|
91
|
+
|
92
|
+
paths = Dir.glob("#{version_path}/**/*")
|
93
|
+
files = paths.map {|path| path[File.join(version_path,'').length..-1] }
|
94
|
+
ext_files.concat files
|
95
|
+
|
96
|
+
built_paths.concat paths
|
97
|
+
|
98
|
+
FileUtils.rm Dir.glob("**/*.o") # FIXME
|
99
|
+
end
|
100
|
+
|
101
|
+
ext_files.uniq.each do |ext_name|
|
102
|
+
ext_basename = ext_name.sub(/\.[^\.]*$/, '')
|
103
|
+
rb_path = File.join(dest_path, "#{ext_basename}.rb")
|
104
|
+
File.open(rb_path, "w") do |f|
|
105
|
+
f.write <<-EOF
|
106
|
+
require File.join File.dirname(__FILE__), RUBY_VERSION.match(/\\d+\\.\\d+/)[0], #{ext_basename.dump}
|
107
|
+
EOF
|
108
|
+
end
|
109
|
+
built_paths << rb_path
|
110
|
+
end
|
111
|
+
|
112
|
+
end
|
68
113
|
|
69
114
|
say results.join("\n") if Gem.configuration.really_verbose
|
70
115
|
|
71
116
|
rescue => ex
|
72
117
|
results = results.join "\n"
|
73
118
|
|
74
|
-
File.open('gem_make.out', 'wb') {
|
119
|
+
File.open('gem_make.out', 'wb') {|f| f.puts results }
|
75
120
|
|
76
121
|
message = <<-EOF
|
77
|
-
ERROR: Failed to build gem native extension.
|
122
|
+
ERROR: Failed to build gem native extension.
|
78
123
|
|
79
124
|
#{results}
|
80
125
|
|
81
126
|
Results logged to #{File.join(Dir.pwd, 'gem_make.out')}
|
82
127
|
EOF
|
83
128
|
|
84
|
-
raise Gem::Exception, message
|
129
|
+
raise Gem::Exception, message
|
85
130
|
ensure
|
86
131
|
Dir.chdir start_dir
|
87
132
|
end
|
@@ -89,9 +134,8 @@ raise Gem::Exception, message
|
|
89
134
|
|
90
135
|
spec.extensions = []
|
91
136
|
|
92
|
-
built_files =
|
93
|
-
|
94
|
-
built_files.each {|path| path.slice!(0, basedir.length) }
|
137
|
+
built_files = built_paths.map {|path| path[File.join(gem_dir,'').length..-1] }
|
138
|
+
built_files.reject! {|path| path =~ /\.o$/ } # FIXME
|
95
139
|
|
96
140
|
spec.files = (spec.files + built_files).sort.uniq
|
97
141
|
spec.platform = platform if platform
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: gem-compile
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- FURUHASHI Sadayuki
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2010-
|
12
|
+
date: 2010-04-02 00:00:00 +09:00
|
13
13
|
default_executable:
|
14
14
|
dependencies: []
|
15
15
|
|