class Rake::ExtensionTask
def define_cross_platform_tasks_with_version(for_platform, ruby_ver)
def define_cross_platform_tasks_with_version(for_platform, ruby_ver) config_path = File.expand_path("~/.rake-compiler/config.yml") # warn the user about the need of configuration to use cross compilation. unless File.exist?(config_path) define_dummy_cross_platform_tasks return end rbconfig_file = Rake::CompilerConfig.new(config_path).find(ruby_ver, for_platform) unless rbconfig_file warn "no configuration section for specified version of Ruby (rbconfig-#{for_platform}-#{ruby_ver})" return end # tmp_path tmp_path = "#{@tmp_dir}/#{for_platform}/#{@name}/#{ruby_ver}" # lib_path lib_path = lib_dir # lib_binary_path lib_binary_path = "#{lib_path}/#{File.basename(binary(for_platform))}" # mkmf mkmf_file = File.expand_path(File.join(File.dirname(rbconfig_file), '..', 'mkmf.rb')) # define compilation tasks for cross platform! define_compile_tasks(for_platform, ruby_ver) # chain fake.rb and mkmf.rb to Makefile generation file "#{tmp_path}/Makefile" => ["#{tmp_path}/fake.rb", "#{tmp_path}/mkmf.rb"] # 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| # Keep the original RbConfig::CONFIG["ENABLE_SHARED"] to use # the same RubyGems extension directory. See also # Gem::BasicSpecificaion#extenions_dir and # Gem.extension_api_version. # # if RbConfig::CONFIG["ENABLE_SHARED"] == "no" # "extensions/x86_64-linux/2.5.0-static" # else # "extensions/x86_64-linux/2.5.0" # end f.puts("require 'rbconfig'") f.puts("original_enable_shared = RbConfig::CONFIG['ENABLE_SHARED']") f.puts(fake_rb(for_platform, ruby_ver)) f.puts("require #{t.prerequisites.first.dump}") f.puts("RbConfig::CONFIG['ENABLE_SHARED'] = original_enable_shared") end end # copy mkmf from cross-ruby location file "#{tmp_path}/mkmf.rb" => [mkmf_file] do |t| 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') end f.write content end end # now define native tasks for cross compiled files if @gem_spec && @gem_spec.platform == 'ruby' then define_native_tasks(for_platform, ruby_ver, @cross_compiling) end # create cross task task 'cross' do # clear compile dependencies Rake::Task['compile'].prerequisites.reject! { |t| !compiles_cross_platform.include?(t) } # chain the cross platform ones task 'compile' => ["compile:#{for_platform}"] # clear lib/binary dependencies and trigger cross platform ones # check if lib/binary is defined (damn bundle versus so versus dll) if Rake::Task.task_defined?(lib_binary_path) then Rake::Task[lib_binary_path].prerequisites.clear end # FIXME: targeting multiple platforms copies the file twice file lib_binary_path => ["copy:#{@name}:#{for_platform}:#{ruby_ver}"] # if everything for native task is in place if @gem_spec && @gem_spec.platform == 'ruby' then # double check: only cross platform native tasks should be here # FIXME: Sooo brittle Rake::Task['native'].prerequisites.reject! { |t| !natives_cross_platform.include?(t) } task 'native' => ["native:#{for_platform}"] end end end