class Rake::ExtensionTask

def define_compile_tasks(for_platform = nil, ruby_ver = RUBY_VERSION)

def define_compile_tasks(for_platform = nil, ruby_ver = RUBY_VERSION)
  # platform usage
  platf = for_platform || platform
  binary_path = binary(platf)
  binary_base_name = File.basename(binary_path)
  # lib_path
  lib_path = lib_dir
  # lib_binary_path
  lib_binary_path = "#{lib_path}/#{binary_base_name}"
  # tmp_path
  tmp_path = "#{@tmp_dir}/#{platf}/#{@name}/#{ruby_ver}"
  stage_path = "#{@tmp_dir}/#{platf}/stage"
  siteconf_path = "#{tmp_path}/.rake-compiler-siteconf.rb"
  tmp_binary_path = "#{tmp_path}/#{binary_path}"
  tmp_binary_dir_path = File.dirname(tmp_binary_path)
  stage_binary_path = "#{stage_path}/#{lib_binary_path}"
  stage_binary_dir_path = File.dirname(stage_binary_path)
  # cleanup and clobbering
  CLEAN.include(tmp_path)
  CLEAN.include(stage_path)
  CLOBBER.include(lib_binary_path)
  CLOBBER.include("#{@tmp_dir}")
  # directories we need
  directory tmp_path
  directory tmp_binary_dir_path
  directory lib_path
  directory stage_binary_dir_path
  directory File.dirname(siteconf_path)
  # Set paths for "make install" destinations
  file siteconf_path => File.dirname(siteconf_path) do
    File.open(siteconf_path, "w") do |siteconf|
      siteconf.puts "require 'rbconfig'"
      siteconf.puts "require 'mkmf'"
      siteconf.puts "dest_path = mkintpath(#{File.expand_path(lib_path).dump})"
      %w[sitearchdir sitelibdir].each do |dir|
        siteconf.puts "RbConfig::MAKEFILE_CONFIG['#{dir}'] = dest_path"
        siteconf.puts "RbConfig::CONFIG['#{dir}'] = dest_path"
      end
    end
  end
  # copy binary from temporary location to final lib
  # tmp/extension_name/extension_name.{so,bundle} => lib/
  task "copy:#{@name}:#{platf}:#{ruby_ver}" => [lib_path, tmp_binary_path, "#{tmp_path}/Makefile"] do
    # install in lib for native platform only
    unless for_platform
      sh "#{make} install target_prefix=", chdir: tmp_path
    end
  end
  # copy binary from temporary location to staging directory
  task "copy:#{@name}:#{platf}:#{ruby_ver}" => [stage_binary_dir_path, tmp_binary_path] do
    cp tmp_binary_path, stage_binary_path
  end
  # copy other gem files to staging directory
  define_staging_file_tasks(@gem_spec.files, lib_path, stage_path, platf, ruby_ver) if @gem_spec
  # binary in temporary folder depends on makefile and source files
  # tmp/extension_name/extension_name.{so,bundle}
  file tmp_binary_path => [tmp_binary_dir_path, "#{tmp_path}/Makefile"] + source_files do
    jruby_compile_msg = <<-EOF
iling a native C extension on JRuby. This is discouraged and a
 extension should be preferred.
    EOF
    warn_once(jruby_compile_msg) if defined?(JRUBY_VERSION)
    chdir tmp_path do
      sh make
      if binary_path != binary_base_name
        cp binary_base_name, binary_path
      end
    end
  end
  # makefile depends of tmp_dir and config_script
  # tmp/extension_name/Makefile
  file "#{tmp_path}/Makefile" => [tmp_path, extconf, siteconf_path] do |t|
    options = @config_options.dup
    # include current directory
    include_dirs = ['.'].concat(@config_includes).uniq.join(File::PATH_SEPARATOR)
    cmd = [Gem.ruby, "-I#{include_dirs}", "-r#{File.basename(siteconf_path)}"]
    # build a relative path to extconf script
    abs_tmp_path = (Pathname.new(Dir.pwd) + tmp_path).realpath
    abs_extconf = (Pathname.new(Dir.pwd) + extconf).realpath
    # now add the extconf script
    cmd << abs_extconf.relative_path_from(abs_tmp_path)
    # 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
    # add options to command
    cmd.push(*options)
    # add any extra command line options
    unless extra_options.empty?
      cmd.push(*extra_options)
    end
    chdir tmp_path do
      # FIXME: Rake is broken for multiple arguments system() calls.
      # Add current directory to the search path of Ruby
      sh cmd.join(' ')
    end
  end
  # compile tasks
  unless Rake::Task.task_defined?('compile') then
    desc "Compile all the extensions"
    task "compile"
  end
  # compile:name
  unless Rake::Task.task_defined?("compile:#{@name}") then
    desc "Compile #{@name}"
    task "compile:#{@name}"
  end
  # Allow segmented compilation by platform (open door for 'cross compile')
  task "compile:#{@name}:#{platf}" => ["copy:#{@name}:#{platf}:#{ruby_ver}"]
  task "compile:#{platf}" => ["compile:#{@name}:#{platf}"]
  # Only add this extension to the compile chain if current
  # platform matches the indicated one.
  if platf == RUBY_PLATFORM then
    # ensure file is always copied
    file lib_binary_path => ["copy:#{name}:#{platf}:#{ruby_ver}"]
    task "compile:#{@name}" => ["compile:#{@name}:#{platf}"]
    task "compile" => ["compile:#{platf}"]
  end
end