Class: Gem::Precompiler
- Inherits:
-
Object
- Object
- Gem::Precompiler
- Includes:
- FileUtils
- Defined in:
- lib/rubygems/precompiler.rb
Instance Method Summary collapse
-
#arch_string ⇒ Object
Private: Return a string that uniquely keys this machines ruby version and architecture.
-
#build_extensions(install_root) ⇒ Object
Private: Calls the code necessary to build all the extensions into a specified install root.
-
#compile ⇒ Object
Public: Compile.
-
#extract_files_into(dir) ⇒ Object
Private: Extracts the gem files into the specified path.
-
#gem_name ⇒ Object
Public: Returns the name of the gem.
-
#gem_require_paths ⇒ Object
Public: Returns the relative require-paths specified by the gem.
-
#gem_version ⇒ Object
Public: Returns the version string of the gem.
-
#has_extension? ⇒ Boolean
Public: Does the gem actually have any compiled extensions?.
-
#initialize(gemfile, opts = {}) ⇒ Precompiler
constructor
A new instance of Precompiler.
-
#output_path ⇒ Object
Public: The filename of the compiled bundle for this gem.
-
#targz_file(path, &block) ⇒ Object
Private: Yield a reference to a TarWriter that writes to the specified .tar.gz file.
-
#tempdir ⇒ Object
Private: Yield the path to a temporary directory that will get deleted when the block returns, unless debug option was used on the cli.
Constructor Details
#initialize(gemfile, opts = {}) ⇒ Precompiler
Returns a new instance of Precompiler.
13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
# File 'lib/rubygems/precompiler.rb', line 13 def initialize(gemfile, opts = {}) @installer = Gem::Installer.new(gemfile, opts.dup.merge(:unpack => true, :build_args => opts.fetch(:build_config,[]))) @spec = @installer.spec @target_dir = opts.fetch(:output, Dir.pwd) @target_dir = File.join(@target_dir, arch_string) if opts.fetch(:arch, false) @debug = opts.fetch(:debug, false) @options = opts # This writes out a build_info file that the extension builder will process to set the # build configuration. We use the write_build_info_file method which should work on ruby 2+ # on ruby < 1.9.3 we don't support setting of build options. 1.9.3 is EOL. # However most simple gems that do not require build time config will still work. return if opts.fetch(:build_config,[]).empty? if Gem::Installer.method_defined?(:write_build_info_file) @installer.write_build_info_file else puts("Older version of rubygems, rubygems-precompiled does not support build options on this rubygems release (pull req welcome)") puts("Try again without build configuration") exit(1) end end |
Instance Method Details
#arch_string ⇒ Object
Private: Return a string that uniquely keys this machines ruby version and architecture
Returns string
88 89 90 |
# File 'lib/rubygems/precompiler.rb', line 88 def arch_string "ruby-#{RUBY_VERSION}-p#{RUBY_PATCHLEVEL}/#{Gem::Platform.local.to_s}" end |
#build_extensions(install_root) ⇒ Object
Private: Calls the code necessary to build all the extensions into a specified install root
Returns a list of files beneath that root making up the build products of the extensions
105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 |
# File 'lib/rubygems/precompiler.rb', line 105 def build_extensions(install_root) if @spec.respond_to?(:extension_dir=) tempdir do |workroot| extract_files_into(workroot) # override the full_gem_path function so we can return # the directory we want. Otherwise by default the build process will # look for the gem installed in the usual place won't find it and will then # bail class <<@spec attr_accessor :workroot def full_gem_path return workroot end end @spec.workroot = workroot @spec.extension_dir = install_root @spec.installed_by_version = Gem::VERSION @spec.build_extensions Dir.glob(File.join(install_root, "**", "*")) end else extract_files_into(install_root) @installer.build_extensions dlext = RbConfig::CONFIG["DLEXT"] lib_dirs = gem_require_paths.join(',') Dir.glob("#{install_root}/{#{lib_dirs}}/**/*.#{dlext}") end end |
#compile ⇒ Object
Public: Compile
This compiles into a temporary file, then moves into place. Otherwise we potentially confuse the gem installer with partial files!
143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 |
# File 'lib/rubygems/precompiler.rb', line 143 def compile temp_output = Tempfile.new('partial-output') tempdir do |path| targz_file(temp_output) do |tar_writer| build_extensions(path).each do |product_path| next if File.directory?(product_path) product_path = Pathname.new(product_path) relative_path = product_path.relative_path_from(Pathname.new(path)) stat = File.stat(product_path) mode = stat.mode size = stat.size File.open(product_path, "r") do |source| tar_writer.add_file_simple(relative_path.to_s, mode, size) do |dest| dest.write source.read(1024*1024) until source.eof? end end end end end FileUtils.mkdir_p(@target_dir) FileUtils.mv(temp_output.path, output_path) end |
#extract_files_into(dir) ⇒ Object
Private: Extracts the gem files into the specified path
39 40 41 |
# File 'lib/rubygems/precompiler.rb', line 39 def extract_files_into(dir) @installer.unpack(dir) end |
#gem_name ⇒ Object
Public: Returns the name of the gem
Returns a string
46 47 48 |
# File 'lib/rubygems/precompiler.rb', line 46 def gem_name @spec.name end |
#gem_require_paths ⇒ Object
Public: Returns the relative require-paths specified by the gem
Returns an array of strings
60 61 62 |
# File 'lib/rubygems/precompiler.rb', line 60 def gem_require_paths @spec.require_paths end |
#gem_version ⇒ Object
Public: Returns the version string of the gem
Returns a Gem::Version
53 54 55 |
# File 'lib/rubygems/precompiler.rb', line 53 def gem_version @spec.version end |
#has_extension? ⇒ Boolean
Public: Does the gem actually have any compiled extensions?
Returns boolean - true if the gem has a c-extension that needs building
67 68 69 |
# File 'lib/rubygems/precompiler.rb', line 67 def has_extension? !@spec.extensions.empty? end |
#output_path ⇒ Object
Public: The filename of the compiled bundle for this gem
Returns a string
95 96 97 |
# File 'lib/rubygems/precompiler.rb', line 95 def output_path File.join(*[@target_dir, "#{gem_name}-#{gem_version.to_s}.tar.gz"].compact) end |
#targz_file(path, &block) ⇒ Object
Private: Yield a reference to a TarWriter that writes to the specified .tar.gz file
177 178 179 180 181 |
# File 'lib/rubygems/precompiler.rb', line 177 def targz_file(path, &block) Zlib::GzipWriter.open(path) do |tar_file_io| Gem::Package::TarWriter.new(tar_file_io, &block) end end |
#tempdir ⇒ Object
Private: Yield the path to a temporary directory that will get deleted when the block returns, unless debug option was used on the cli
74 75 76 77 78 79 80 81 82 83 |
# File 'lib/rubygems/precompiler.rb', line 74 def tempdir temp_dir = Dir.mktmpdir yield temp_dir ensure if @debug puts("\nLeaving #{temp_dir} in place") else rm_rf temp_dir end end |