lib/rake/extensiontask.rb in luislavena-rake-compiler-0.5.0 vs lib/rake/extensiontask.rb in luislavena-rake-compiler-0.6.0

- old
+ new

@@ -70,30 +70,33 @@ define_cross_platform_tasks(cross_platform) end end private - def define_compile_tasks(for_platform = nil) + def define_compile_tasks(for_platform = nil, ruby_ver = RUBY_VERSION) # platform usage platf = for_platform || platform + # lib_path + lib_path = lib_dir + # tmp_path - tmp_path = "#{@tmp_dir}/#{platf}/#{@name}" + tmp_path = "#{@tmp_dir}/#{platf}/#{@name}/#{ruby_ver}" # cleanup and clobbering CLEAN.include(tmp_path) - CLOBBER.include("#{@lib_dir}/#{binary(platf)}") + CLOBBER.include("#{lib_path}/#{binary(platf)}") CLOBBER.include("#{@tmp_dir}") # directories we need directory tmp_path directory lib_dir # copy binary from temporary location to final lib # tmp/extension_name/extension_name.{so,bundle} => lib/ - task "copy:#{@name}:#{platf}" => [lib_dir, "#{tmp_path}/#{binary(platf)}"] do - cp "#{tmp_path}/#{binary(platf)}", "#{@lib_dir}/#{binary(platf)}" + task "copy:#{@name}:#{platf}:#{ruby_ver}" => [lib_path, "#{tmp_path}/#{binary(platf)}"] do + cp "#{tmp_path}/#{binary(platf)}", "#{lib_path}/#{binary(platf)}" end # binary in temporary folder depends on makefile and source files # tmp/extension_name/extension_name.{so,bundle} file "#{tmp_path}/#{binary(platf)}" => ["#{tmp_path}/Makefile"] + source_files do @@ -145,30 +148,33 @@ desc "Compile #{@name}" task "compile:#{@name}" end # Allow segmented compilation by platform (open door for 'cross compile') - task "compile:#{@name}:#{platf}" => ["copy:#{@name}:#{platf}"] + 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_dir}/#{binary(platf)}" => ["copy:#{name}:#{platf}"] + file "#{lib_path}/#{binary(platf)}" => ["copy:#{name}:#{platf}:#{ruby_ver}"] task "compile:#{@name}" => ["compile:#{@name}:#{platf}"] task "compile" => ["compile:#{platf}"] end end - def define_native_tasks(for_platform = nil) + def define_native_tasks(for_platform = nil, ruby_ver = RUBY_VERSION) platf = for_platform || platform # tmp_path - tmp_path = "#{@tmp_dir}/#{platf}/#{@name}" + tmp_path = "#{@tmp_dir}/#{platf}/#{@name}/#{ruby_ver}" + # lib_path + lib_path = lib_dir + # create 'native:gem_name' and chain it to 'native' task unless Rake::Task.task_defined?("native:#{@gem_spec.name}:#{platf}") task "native:#{@gem_spec.name}:#{platf}" do |t| # FIXME: truly duplicate the Gem::Specification # workaround the lack of #dup for Gem::Specification @@ -179,41 +185,36 @@ # clear the extensions defined in the specs spec.extensions.clear # add the binaries that this task depends on - # ensure the files get properly copied to lib_dir - ext_files = t.prerequisites.map { |ext| "#{@lib_dir}/#{File.basename(ext)}" } - ext_files.each do |ext| - unless Rake::Task.task_defined?("#{@lib_dir}/#{File.basename(ext)}") then - # strip out path and .so/.bundle - file "#{@lib_dir}/#{File.basename(ext)}" => ["copy:#{File.basename(ext).ext('')}:#{platf}"] - end + ext_files = [] + + # go through native prerequisites and grab the real extension files from there + t.prerequisites.each do |ext| + ext_files << ext end # include the files in the gem specification spec.files += ext_files - # Make sure that the required ruby version matches the ruby version - # we've used for cross compiling: - target_version = RUBY_VERSION =~ /^1.8/ ? '1.8.6' : '1.9.0' - spec.required_ruby_version = "~> #{target_version}" - # Generate a package for this gem gem_package = Rake::GemPackageTask.new(spec) do |pkg| pkg.need_zip = false pkg.need_tar = false end - - # ensure the binaries are copied - task "#{gem_package.package_dir}/#{gem_package.gem_file}" => ["copy:#{@name}:#{platf}"] end end # add binaries to the dependency chain - task "native:#{@gem_spec.name}:#{platf}" => ["#{tmp_path}/#{binary(platf)}"] + task "native:#{@gem_spec.name}:#{platf}" => ["#{lib_path}/#{binary(platf)}"] + # ensure the extension get copied + unless Rake::Task.task_defined?("#{lib_path}/#{binary(platf)}") then + file "#{lib_path}/#{binary(platf)}" => ["copy:#{@name}:#{platf}:#{ruby_ver}"] + end + # Allow segmented packaging by platfrom (open door for 'cross compile') task "native:#{platf}" => ["native:#{@gem_spec.name}:#{platf}"] # Only add this extension to the compile chain if current # platform matches the indicated one. @@ -222,49 +223,87 @@ task "native" => ["native:#{platf}"] end end def define_cross_platform_tasks(for_platform) + if ruby_vers = ENV['RUBY_CC_VERSION'] + ruby_vers = ENV['RUBY_CC_VERSION'].split(File::PATH_SEPARATOR) + else + ruby_vers = [RUBY_VERSION] + end + + multi = (ruby_vers.size > 1) ? true : false + + ruby_vers.each do |version| + # save original lib_dir + orig_lib_dir = @lib_dir + + # tweak lib directory only when targeting multiple versions + if multi then + version =~ /(\d+.\d+)/ + @lib_dir = "#{@lib_dir}/#{$1}" + end + + define_cross_platform_tasks_with_version(for_platform, version) + + # restore lib_dir + @lib_dir = orig_lib_dir + end + end + + def define_cross_platform_tasks_with_version(for_platform, ruby_ver) config_path = File.expand_path("~/.rake-compiler/config.yml") - ruby_ver = ENV['RUBY_CC_VERSION'] || RUBY_VERSION # warn the user about the need of configuration to use cross compilation. unless File.exist?(config_path) warn "rake-compiler must be configured first to enable cross-compilation" return end config_file = YAML.load_file(config_path) # tmp_path - tmp_path = "#{@tmp_dir}/#{for_platform}/#{@name}" + tmp_path = "#{@tmp_dir}/#{for_platform}/#{@name}/#{ruby_ver}" + # lib_path + lib_path = lib_dir + unless rbconfig_file = config_file["rbconfig-#{ruby_ver}"] then warn "no configuration section for specified version of Ruby (rbconfig-#{ruby_ver})" return end + # mkmf + mkmf_file = File.expand_path(File.join(File.dirname(rbconfig_file), '..', 'mkmf.rb')) + # define compilation tasks for cross platfrom! - define_compile_tasks(for_platform) + define_compile_tasks(for_platform, ruby_ver) - # chain fake.rb and rbconfig.rb to Makefile generation - file "#{tmp_path}/Makefile" => ["#{tmp_path}/fake.rb", "#{tmp_path}/rbconfig.rb"] + # chain fake.rb, rbconfig.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| cp t.prerequisites.first, t.name end + # copy mkmf from cross-ruby location + file "#{tmp_path}/mkmf.rb" => [mkmf_file] do |t| + cp t.prerequisites.first, t.name + 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(ruby_ver) end end # now define native tasks for cross compiled files - define_native_tasks(for_platform) if @gem_spec && @gem_spec.platform == 'ruby' + define_native_tasks(for_platform, ruby_ver) if @gem_spec && @gem_spec.platform == 'ruby' # create cross task task 'cross' do # clear compile dependencies Rake::Task['compile'].prerequisites.reject! { |t| !compiles_cross_platform.include?(t) } @@ -272,15 +311,15 @@ # 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_dir}/#{binary(for_platform)}") then - Rake::Task["#{@lib_dir}/#{binary(for_platform)}"].prerequisites.clear + if Rake::Task.task_defined?("#{lib_path}/#{binary(for_platform)}") then + Rake::Task["#{lib_path}/#{binary(for_platform)}"].prerequisites.clear end # FIXME: targeting multiple platforms copies the file twice - file "#{@lib_dir}/#{binary(for_platform)}" => ["copy:#{@name}:#{for_platform}"] + file "#{lib_path}/#{binary(for_platform)}" => ["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