[Rubygems-developers] [PATCH] Support extensions built with rake

Tilman Sauerbeck tilman at code-monkey.de
Sun Sep 25 04:11:23 EDT 2005


Tilman Sauerbeck <tilman at code-monkey.de> [2005-09-07 21:14]:

> [...]

Chad discussed my last patch with me on IRC, and I fixed the issues he
pointed out.

* if make (for extconf-based extensions) or rake fail building the
  extension, the gem install process is aborted.
* Always call the "extension" task for rake-based extensions.
  The "extension" task is supposed to build and install the extension,
  and clean up the build directory.

I also changed how results are passed from the extension builder classes
to the caller. If the extension builder raised an error, all of the log
entries (results) were lost.

Regards,
Tilman

-- 
learn to quote: http://www.netmeister.org/news/learn2quote.html
-------------- next part --------------
diff -aur rubygems-0.8.11.orig/lib/rubygems/installer.rb rubygems-0.8.11/lib/rubygems/installer.rb
--- rubygems-0.8.11.orig/lib/rubygems/installer.rb	2005-06-12 23:33:19.000000000 +0200
+++ rubygems-0.8.11/lib/rubygems/installer.rb	2005-09-25 09:45:37.000000000 +0200
@@ -284,29 +284,36 @@
       say "Building native extensions.  This could take a while..."
       start_dir = Dir.pwd
       dest_path = File.join(directory, spec.require_paths[0])
+      ran_rake = false # only run rake once
+
       spec.extensions.each do |extension|
-        Dir.chdir File.join(directory, File.dirname(extension))
-        results = ["#{Gem.ruby} #{File.basename(extension)} #{ARGV.join(" ")}"]
-        results << `#{Gem.ruby} #{File.basename(extension)} #{ARGV.join(" ")}`
-        if File.exist?('Makefile')
-          mf = File.read('Makefile')
-          mf = mf.gsub(/^RUBYARCHDIR\s*=\s*\$.*/, "RUBYARCHDIR = #{dest_path}")
-          mf = mf.gsub(/^RUBYLIBDIR\s*=\s*\$.*/, "RUBYLIBDIR = #{dest_path}")
-          File.open('Makefile', 'wb') {|f| f.print mf}
-          make_program = ENV['make']
-          unless make_program
-            make_program = (/mswin/ =~ RUBY_PLATFORM) ? 'nmake' : 'make'
-          end
-          results << "#{make_program}"
-          results << `#{make_program}`
-          results << "#{make_program} install"
-          results << `#{make_program} install`
-          say results.join("\n")
+        break if ran_rake
+        results = []
+
+        if extension.match(/extconf/)
+          builder = ExtExtConfBuilder
+		elsif extension.match(/rakefile/i)
+          builder = ExtRakeBuilder
+		  ran_rake = true
         else
-          File.open(File.join(Dir.pwd, 'gem_make.out'), 'wb') {|f| f.puts results.join("\n")}
-          raise "ERROR: Failed to build gem native extension.\nGem files will remain installed in #{directory} for inspection.\n  #{results.join('\n')}\n\nResults logged to #{File.join(Dir.pwd, 'gem_make.out')}"
+          builder = nil
+          results = ["No builder for extension '#{extension}'"]
+        end
+
+        begin
+          err = false
+          Dir.chdir File.join(directory, File.dirname(extension))
+          builder.build(extension, directory, dest_path, results)
+        rescue
+          err = true
         end
+
+        say results.join("\n")
         File.open('gem_make.out', 'wb') {|f| f.puts results.join("\n")}
+
+        if err
+          raise "ERROR: Failed to build gem native extension.\nGem files will remain installed in #{directory} for inspection.\n  #{results.join('\n')}\n\nResults logged to #{File.join(Dir.pwd, 'gem_make.out')}"
+		end
       end
       Dir.chdir start_dir
     end
@@ -535,4 +542,43 @@
 
   end  # class Uninstaller
 
+  class ExtExtConfBuilder
+    def self.build(extension, directory, dest_path, results)
+      results << "#{Gem.ruby} #{File.basename(extension)} #{ARGV.join(" ")}"
+      results << `#{Gem.ruby} #{File.basename(extension)} #{ARGV.join(" ")}`
+
+      raise unless File.exist?('Makefile')
+      mf = File.read('Makefile')
+      mf = mf.gsub(/^RUBYARCHDIR\s*=\s*\$.*/, "RUBYARCHDIR = #{dest_path}")
+      mf = mf.gsub(/^RUBYLIBDIR\s*=\s*\$.*/, "RUBYLIBDIR = #{dest_path}")
+      File.open('Makefile', 'wb') {|f| f.print mf}
+
+      make_program = ENV['make']
+      unless make_program
+        make_program = (/mswin/ =~ RUBY_PLATFORM) ? 'nmake' : 'make'
+      end
+
+      ['', 'install', 'clean'].each do |target|
+        results << "#{make_program} #{target}".strip
+        results << `#{make_program} #{target}`
+        raise unless $?.exitstatus.zero?
+      end
+
+	  results
+    end
+  end
+
+  class ExtRakeBuilder
+    def ExtRakeBuilder.build(ext, directory, dest_path, results)
+      make_program = ENV['rake'] || 'rake'
+      make_program += " RUBYARCHDIR=#{dest_path} RUBYLIBDIR=#{dest_path}"
+
+      results << "#{make_program} extension".strip
+      results << `#{make_program} extension`
+
+      raise unless $?.exitstatus.zero?
+
+      results
+    end
+  end
 end  # module Gem


More information about the Rubygems-developers mailing list