diff options
author | naruse <naruse@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2013-09-14 08:59:02 +0000 |
---|---|---|
committer | naruse <naruse@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2013-09-14 08:59:02 +0000 |
commit | 269503b544247b5b3e30dbe60a0bab4f2ca00e4e (patch) | |
tree | a6d0a3a9b34017c4c84d997152a3aaf3086e1ce1 /lib/rubygems/ext/builder.rb | |
parent | 2614d9ba2fb5ad171200cccc88f42fa659b527c6 (diff) | |
download | ruby-269503b544247b5b3e30dbe60a0bab4f2ca00e4e.tar.gz |
Revert r42938 "* lib/rubygems: Update to RubyGems 2.1.3"
It breaks build.
http://u64.rubyci.org/~chkbuild/ruby-trunk/log/20130913T200302Z.diff.html.gz
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@42941 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'lib/rubygems/ext/builder.rb')
-rw-r--r-- | lib/rubygems/ext/builder.rb | 120 |
1 files changed, 119 insertions, 1 deletions
diff --git a/lib/rubygems/ext/builder.rb b/lib/rubygems/ext/builder.rb index 79cae906ee..8c05723573 100644 --- a/lib/rubygems/ext/builder.rb +++ b/lib/rubygems/ext/builder.rb @@ -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 @@ -18,7 +33,7 @@ class Gem::Ext::Builder # try to find make program from Ruby configure arguments first RbConfig::CONFIG['configure_args'] =~ /with-make-prog\=(\w+)/ - make_program = $1 || ENV['MAKE'] || ENV['make'] + make_program = ENV['MAKE'] || ENV['make'] || $1 unless make_program then make_program = (/mswin/ =~ RUBY_PLATFORM) ? 'nmake' : 'make' end @@ -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 |