gem-compile 0.0.2 → 0.0.3

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/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