From 073faa1573bb78bff9686cc66b09cda6fb07bf7a Mon Sep 17 00:00:00 2001 From: Aaron Stone Date: Tue, 30 Dec 2014 11:41:54 -0800 Subject: [PATCH] Add rake tasks for files added to spec.files by a cross_compile block Resolves #98 --- lib/rake/extensiontask.rb | 46 ++++++++++++++++------------- spec/lib/rake/extensiontask_spec.rb | 30 +++++++++++++++++++ 2 files changed, 55 insertions(+), 21 deletions(-) diff --git a/lib/rake/extensiontask.rb b/lib/rake/extensiontask.rb index cb1a114..6ddca82 100755 --- a/lib/rake/extensiontask.rb +++ b/lib/rake/extensiontask.rb @@ -87,6 +87,26 @@ def cross_config_options(for_platform=nil) end private + # copy other gem files to staging directory + def define_staging_file_tasks(files, lib_path, stage_path, platf, ruby_ver) + files.each do |gem_file| + # ignore directories and the binary extension + next if File.directory?(gem_file) || gem_file == "#{lib_path}/#{binary(platf)}" + stage_file = "#{stage_path}/#{gem_file}" + + # copy each file from base to stage directory + unless Rake::Task.task_defined?(stage_file) then + directory File.dirname(stage_file) + file stage_file => [File.dirname(stage_file), gem_file] do + cp gem_file, stage_file + end + end + + # append each file to the copy task + task "copy:#{@name}:#{platf}:#{ruby_ver}" => [stage_file] + end + end + def define_compile_tasks(for_platform = nil, ruby_ver = RUBY_VERSION) # platform usage platf = for_platform || platform @@ -120,24 +140,7 @@ def define_compile_tasks(for_platform = nil, ruby_ver = RUBY_VERSION) end # copy other gem files to staging directory - if @gem_spec - @gem_spec.files.each do |gem_file| - # ignore directories and the binary extension - next if File.directory?(gem_file) || gem_file == "#{lib_path}/#{binary(platf)}" - stage_file = "#{stage_path}/#{gem_file}" - - # copy each file from base to stage directory - unless Rake::Task.task_defined?(stage_file) then - directory File.dirname(stage_file) - file stage_file => [File.dirname(stage_file), gem_file] do - cp gem_file, stage_file - end - end - - # append each file to the copy task - task "copy:#{@name}:#{platf}:#{ruby_ver}" => [stage_file] - end - end + 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} @@ -253,9 +256,7 @@ def define_native_tasks(for_platform = nil, ruby_ver = RUBY_VERSION, callback = spec.files += ext_files # expose gem specification for customization - if callback - callback.call(spec) - end + callback.call(spec) if callback # Generate a package for this gem pkg = Gem::PackageTask.new(spec) do |pkg| @@ -266,6 +267,9 @@ def define_native_tasks(for_platform = nil, ruby_ver = RUBY_VERSION, callback = pkg.package_files.clear end + # copy other gem files to staging directory if added by the callback + define_staging_file_tasks(spec.files, lib_path, stage_path, platf, ruby_ver) + # Copy from staging directory to gem package directory. # This is derived from the code of Gem::PackageTask # but uses stage_path as source directory. diff --git a/spec/lib/rake/extensiontask_spec.rb b/spec/lib/rake/extensiontask_spec.rb index aa593fe..575846a 100644 --- a/spec/lib/rake/extensiontask_spec.rb +++ b/spec/lib/rake/extensiontask_spec.rb @@ -338,6 +338,36 @@ }.should_not raise_error end + it 'should generate additional rake tasks if files are added when cross compiling' do + config = mock(Hash) + config.stub!(:[]).and_return('/rubies/1.9.1/rbconfig.rb') + YAML.stub!(:load_file).and_return(config) + + # Use a real spec instead of a mock because define_native_tasks dups and + # calls methods on Gem::Specification, which is more than mock can do. + spec = Gem::Specification.new do |s| + s.name = 'my_gem' + s.platform = Gem::Platform::RUBY + end + + # Gem::PackageTask calls Rake::PackageTask which sets Gem.configuration.verbose, + # which initializes Gem::ConfigFile, + # which gets mad if it cannot find `sysconfdir`/gemrc + Gem.stub_chain(:configuration, :verbose=).and_return(true) + + ENV['RUBY_CC_VERSION'] = '1.9.1' + Rake::ExtensionTask.new('extension_one', spec) do |ext| + ext.cross_compile = true + ext.cross_platform = 'universal-unknown' + ext.cross_compiling do |gem_spec| + gem_spec.files << 'somedir/somefile' + end + end + Rake::Task['native:my_gem:universal-unknown'].execute + Rake::Task.should have_defined("tmp/universal-unknown/stage/somedir") + Rake::Task.should have_defined("tmp/universal-unknown/stage/somedir/somefile") + end + it 'should allow usage of RUBY_CC_VERSION to indicate a different version of ruby' do config = mock(Hash) config.should_receive(:[]).with("rbconfig-i386-mingw32-1.9.1").and_return('/rubies/1.9.1/rbconfig.rb')