1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

* lib/rubygems: Import RubyGems from master as of commit 523551c

* test/rubygems:  ditto.


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@42257 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
drbrain 2013-07-30 22:10:21 +00:00
parent d82e5cc4cc
commit 310d77d4b0
14 changed files with 311 additions and 212 deletions

View file

@ -4,8 +4,23 @@
# See LICENSE.txt for permissions.
#++
require 'rubygems/user_interaction'
require 'thread'
class Gem::Ext::Builder
include Gem::UserInteraction
##
# The builder shells-out to run various commands after changing the
# directory. This means multiple installations cannot be allowed to build
# extensions in parallel as they may change each other's directories leading
# to broken extensions or failed installations.
CHDIR_MUTEX = Mutex.new # :nodoc:
attr_accessor :build_args # :nodoc:
def self.class_name
name =~ /Ext::(.*)Builder/
$1.downcase
@ -63,5 +78,108 @@ class Gem::Ext::Builder
end
end
##
# Creates a new extension builder for +spec+ using the given +build_args+.
# The gem for +spec+ is unpacked in +gem_dir+.
def initialize spec, build_args
@spec = spec
@build_args = build_args
@gem_dir = spec.gem_dir
@ran_rake = nil
end
##
# Chooses the extension builder class for +extension+
def builder_for extension # :nodoc:
case extension
when /extconf/ then
Gem::Ext::ExtConfBuilder
when /configure/ then
Gem::Ext::ConfigureBuilder
when /rakefile/i, /mkrf_conf/i then
@ran_rake = true
Gem::Ext::RakeBuilder
when /CMakeLists.txt/ then
Gem::Ext::CmakeBuilder
else
extension_dir = File.join @gem_dir, File.dirname(extension)
message = "No builder for extension '#{extension}'"
build_error extension_dir, message
end
end
##
# Logs the build +output+ in +build_dir+, then raises ExtensionBuildError.
def build_error build_dir, output, backtrace = nil # :nodoc:
gem_make_out = File.join build_dir, 'gem_make.out'
open gem_make_out, 'wb' do |io| io.puts output end
message = <<-EOF
ERROR: Failed to build gem native extension.
#{output}
Gem files will remain installed in #{@gem_dir} for inspection.
Results logged to #{gem_make_out}
EOF
raise Gem::Installer::ExtensionBuildError, message, backtrace
end
def build_extension extension, dest_path # :nodoc:
results = []
extension ||= '' # I wish I knew why this line existed
extension_dir = File.join @gem_dir, File.dirname(extension)
builder = builder_for extension
begin
FileUtils.mkdir_p dest_path
CHDIR_MUTEX.synchronize do
Dir.chdir extension_dir do
results = builder.build(extension, @gem_dir, dest_path,
results, @build_args)
say results.join("\n") if Gem.configuration.really_verbose
end
end
rescue
build_error extension_dir, results.join("\n"), $@
end
end
##
# Builds extensions. Valid types of extensions are extconf.rb files,
# configure scripts and rakefiles or mkrf_conf files.
def build_extensions
return if @spec.extensions.empty?
if @build_args.empty?
say "Building native extensions. This could take a while..."
else
say "Building native extensions with: '#{@build_args.join ' '}'"
say "This could take a while..."
end
dest_path = File.join @gem_dir, @spec.require_paths.first
@ran_rake = false # only run rake once
@spec.extensions.each do |extension|
break if @ran_rake
build_extension extension, dest_path
end
end
end