From 41f834449fc4323b2f995e8715aa5842d9fd9334 Mon Sep 17 00:00:00 2001 From: Lars Kanis Date: Sat, 30 Jan 2016 08:08:07 +0100 Subject: [PATCH] Change the fake mechanism to be compatible with bundler. The previous fake mechanism worked by hooking onto the "require 'rbconfig'" call. This is problematic because bundler internally requires rbconfig, but doesn't work corretly in a faked environment. It then fails to load gems that are also part of the standard library, like json and rdoc. This results in issues like https://github.com/rake-compiler/rake-compiler-dock/issues/8 The fake mechanism is now changed to hook onto the "require 'mkrb'" call, which is typically part of the extconf file, and it is where the faked platform values are actually needed. That way it is loaded after bundler/setup, so that the library paths are set according to the Gemfile.lock, to the native Linux libraries, before the fake environment is active. Please note, that the build directory of a given gem needs to be cleared, in order to get updated fake files. So do a "rm tmp pkg -rf". --- lib/rake/extensiontask.rb | 35 ++++++++++++++--------------------- 1 file changed, 14 insertions(+), 21 deletions(-) diff --git a/lib/rake/extensiontask.rb b/lib/rake/extensiontask.rb index 030af96..f914919 100644 --- a/lib/rake/extensiontask.rb +++ b/lib/rake/extensiontask.rb @@ -169,8 +169,8 @@ Java extension should be preferred. # now add the extconf script cmd << abs_extconf.relative_path_from(abs_tmp_path) - # rbconfig.rb will be present if we are cross compiling - if t.prerequisites.include?("#{tmp_path}/rbconfig.rb") then + # fake.rb will be present if we are cross compiling + if t.prerequisites.include?("#{tmp_path}/fake.rb") then options.push(*cross_config_options(platf)) end @@ -365,39 +365,30 @@ Java extension should be preferred. # define compilation tasks for cross platform! define_compile_tasks(for_platform, ruby_ver) - # chain fake.rb, rbconfig.rb and mkmf.rb to Makefile generation + # chain fake.rb and mkmf.rb to Makefile generation file "#{tmp_path}/Makefile" => ["#{tmp_path}/fake.rb", - "#{tmp_path}/rbconfig.rb", "#{tmp_path}/mkmf.rb"] - # copy the file from the cross-ruby location - file "#{tmp_path}/rbconfig.rb" => [rbconfig_file] do |t| + # copy the rbconfig from the cross-ruby location and + # genearte fake.rb for different ruby versions + file "#{tmp_path}/fake.rb" => [rbconfig_file] do |t| File.open(t.name, 'w') do |f| - f.write "require 'fake.rb'\n\n" + f.write fake_rb(for_platform, ruby_ver) f.write File.read(t.prerequisites.first) end end # copy mkmf from cross-ruby location file "#{tmp_path}/mkmf.rb" => [mkmf_file] do |t| - cp t.prerequisites.first, t.name - if ruby_ver < "1.9" && "1.9" <= RUBY_VERSION - File.open(t.name, 'r+t') do |f| - content = f.read + File.open(t.name, 'w') do |f| + content = File.read(t.prerequisites.first) + content.sub!(/^(require ')rbconfig(')$/, '\\1fake\\2') + if ruby_ver < "1.9" && "1.9" <= RUBY_VERSION content.sub!(/^( break )\*(defaults)$/, '\\1\\2.first') content.sub!(/^( return )\*(defaults)$/, '\\1\\2.first') content.sub!(/^( mfile\.)print( configuration\(srcprefix\))$/, '\\1puts\\2') - f.rewind - f.write content - f.truncate(f.tell) end - end - end - - # genearte fake.rb for different ruby versions - file "#{tmp_path}/fake.rb" do |t| - File.open(t.name, 'w') do |f| - f.write fake_rb(for_platform, ruby_ver) + f.write content end end @@ -495,8 +486,10 @@ Java extension should be preferred. # "cannot load such file -- win32/resolv" when it is required later on. # See also: https://github.com/tjschuck/rake-compiler-dev-box/issues/5 require 'resolv' + require 'rbconfig' class Object + remove_const :RbConfig remove_const :RUBY_PLATFORM remove_const :RUBY_VERSION remove_const :RUBY_DESCRIPTION if defined?(RUBY_DESCRIPTION) -- 2.5.0.windows.1