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 CHANGED
@@ -1,12 +1,12 @@
1
1
  gem-compile
2
2
  ===========
3
- Create binary gems from gems with extensions.
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 RubyGem command plugin that adds 'complie' command.
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
@@ -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::RUBY
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
- path = File.expand_path File.join(gem_dir, path)
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
- dest_path = File.join gem_dir, spec.require_paths.first
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
- nil
136
+ raise results.last
121
137
  end
122
138
 
123
139
  begin
124
- Dir.chdir File.join(gem_dir, File.dirname(extension))
125
- results = builder.build(extension, gem_dir, dest_path, results)
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') { |f| f.puts results }
192
+ File.open('gem_make.out', 'wb') {|f| f.puts results }
133
193
 
134
- mesage = <<-EOF
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 = Dir.glob("#{dest_path}/**/*")
152
- basedir = File.join gem_dir, ""
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
- raise Gem::CommandLineError,
27
- "Please specify a gem name or file on the command line"
31
+ raise Gem::CommandLineError,
32
+ "Please specify a gem name or file on the command line"
28
33
  end
29
34
 
30
- Gem::Compiler.compile(gem, options[:platform])
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
 
@@ -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
- dest_path = File.join gem_dir, spec.require_paths.first
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
- nil
63
+ raise results.last
63
64
  end
64
65
 
65
66
  begin
66
- Dir.chdir File.join(gem_dir, File.dirname(extension))
67
- results = builder.build(extension, gem_dir, dest_path, results)
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') { |f| f.puts results }
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 = Dir.glob("#{dest_path}/**/*")
93
- basedir = File.join gem_dir, ""
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.2
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-03-31 00:00:00 +09:00
12
+ date: 2010-04-02 00:00:00 +09:00
13
13
  default_executable:
14
14
  dependencies: []
15
15