From 2194cc181e3bc05847b061d6308a8e1b8e43f1b3 Mon Sep 17 00:00:00 2001 From: Stephen Augenstein Date: Wed, 6 Jul 2011 16:56:31 -0400 Subject: [PATCH] Start using rake-compiler and mini_portile to enable cross-compiled binary gems for windows --- .gitignore | 13 ++-- Rakefile | 97 +++++++++++++++++-------- ext/extconf.rb | 26 ------- ext/rubyaudio_ext/extconf.rb | 32 ++++++++ ext/{ => rubyaudio_ext}/ra_buffer.c | 0 ext/{ => rubyaudio_ext}/ra_buffer.h | 0 ext/{ => rubyaudio_ext}/ra_sound.c | 0 ext/{ => rubyaudio_ext}/ra_sound.h | 0 ext/{ => rubyaudio_ext}/ra_soundinfo.c | 0 ext/{ => rubyaudio_ext}/ra_soundinfo.h | 0 ext/{ => rubyaudio_ext}/rubyaudio_ext.c | 0 lib/ruby-audio.rb | 8 +- ruby-audio.gemspec | 40 ++++------ spec/spec_helper.rb | 1 - 14 files changed, 126 insertions(+), 91 deletions(-) delete mode 100644 ext/extconf.rb create mode 100644 ext/rubyaudio_ext/extconf.rb rename ext/{ => rubyaudio_ext}/ra_buffer.c (100%) rename ext/{ => rubyaudio_ext}/ra_buffer.h (100%) rename ext/{ => rubyaudio_ext}/ra_sound.c (100%) rename ext/{ => rubyaudio_ext}/ra_sound.h (100%) rename ext/{ => rubyaudio_ext}/ra_soundinfo.c (100%) rename ext/{ => rubyaudio_ext}/ra_soundinfo.h (100%) rename ext/{ => rubyaudio_ext}/rubyaudio_ext.c (100%) diff --git a/.gitignore b/.gitignore index 7471b70..baca1ba 100644 --- a/.gitignore +++ b/.gitignore @@ -1,8 +1,7 @@ -/pkg/* +pkg/* /rdoc/ -/ext/*.o -/ext/Makefile -/ext/*.bundle -/ext/*.so -/ext/*.dll -/ext/*.log +*.bundle +*.so +*.dll +/tmp +/ports \ No newline at end of file diff --git a/Rakefile b/Rakefile index 8f8a064..57c4af5 100644 --- a/Rakefile +++ b/Rakefile @@ -3,46 +3,79 @@ require 'rake' require 'rake/rdoctask' require 'rake/gempackagetask' require 'spec/rake/spectask' +require 'rake/extensiontask' +require 'rake/extensioncompiler' +require 'mini_portile' -spec = Gem::Specification.new do |s| - s.name = 'ruby-audio' - s.version = '1.4.0' - s.summary = 'ruby-audio wraps around libsndfile to provide simplified sound reading and writing support to ruby programs' - s.authors = ['Stephen Augenstein'] - s.email = 'perl.programmer@gmail.com' - s.homepage = 'http://github.com/warhammerkid/ruby-audio' - - s.platform = Gem::Platform::RUBY - s.rdoc_options << '--line-numbers' << '--main' << 'README.rdoc' - s.rdoc_options += FileList['ext/**/*.c', 'README.rdoc'] - s.files = FileList['README.rdoc', 'Rakefile', 'LICENSE', 'lib/**/*.rb', 'spec/**/*.{rb,opts,wav,mp3}', 'ext/extconf.rb', 'ext/*.{c,h}'] - s.extensions = ["ext/extconf.rb"] - s.test_files = Dir[*['spec/**/*_spec.rb']] - - s.requirements << 'libsndfile (http://www.mega-nerd.com/libsndfile/)' -end - -desc 'Default: Run the tests' +desc 'Default: run the specs.' task :default => :spec -# Rake gem & package routines -Rake::GemPackageTask.new(spec).define +# I don't want to depend on bundler, so we do it the bundler way without it +gemspec_path = 'ruby-audio.gemspec' +spec = begin + eval(File.read(File.join(File.dirname(__FILE__), gemspec_path)), TOPLEVEL_BINDING, gemspec_path) +rescue LoadError => e + original_line = e.backtrace.find { |line| line.include?(gemspec_path) } + msg = "There was a LoadError while evaluating #{gemspec_path}:\n #{e.message}" + msg << " from\n #{original_line}" if original_line + msg << "\n" + puts msg + exit +end -desc 'Generate a gemspec file' -task :gemspec do - File.open("#{spec.name}.gemspec", 'w') do |f| - f.write spec.to_ruby - end +$recipes = {} +LIBSNDFILE_VERSION = '1.0.24' +$recipes[:libsndfile] = MiniPortile.new "libsndfile", LIBSNDFILE_VERSION +$recipes[:libsndfile].files << "http://www.mega-nerd.com/libsndfile/files/libsndfile-#{LIBSNDFILE_VERSION}.tar.gz" +$recipes.each { |_, recipe| recipe.host = Rake::ExtensionCompiler.mingw_host } + +Spec::Rake::SpecTask.new do |t| + t.spec_opts = ['--options', 'spec/spec.opts'] end -desc "Generate documentation" +desc 'Generate documentation' Rake::RDocTask.new(:rdoc) do |rdoc| rdoc.rdoc_dir = 'rdoc' - rdoc.title = 'ruby-audio' - rdoc.options = spec.rdoc_options - rdoc.rdoc_files.include('lib/**/*.rb') + rdoc.title = spec.name + rdoc.options += spec.rdoc_options + rdoc.rdoc_files.include(*spec.extra_rdoc_files) + rdoc.rdoc_files.include("lib") end -Spec::Rake::SpecTask.new do |t| - t.spec_opts = ['--options', 'spec/spec.opts'] +Rake::GemPackageTask.new(spec) do |pkg| + pkg.need_zip = false + pkg.need_tar = false +end + +Rake::ExtensionTask.new('rubyaudio_ext', spec) do |ext| + if RUBY_PLATFORM =~ /mswin|mingw/ then + # No cross-compile on win, so compile extension to lib/1.[89] + RUBY_VERSION =~ /(\d+\.\d+)/ + ext.lib_dir = "lib/#{$1}" + else + ext.cross_compile = true + ext.cross_platform = 'x86-mingw32' + ext.cross_config_options << "--with-sndfile-dir=#{$recipes[:libsndfile].path}" + ext.cross_compiling do |gem_spec| + gem_spec.post_install_message = "You installed the binary version of this gem!" + end + end +end + +namespace :cross do + task :libsndfile do + recipe = $recipes[:libsndfile] + checkpoint = "ports/.#{recipe.name}-#{recipe.version}-#{recipe.host}.installed" + unless File.exist?(checkpoint) + recipe.cook + touch checkpoint + end + recipe.activate + end +end +task :cross => ["cross:libsndfile"] + +desc "Build gem packages" +task :gems do + sh "rake cross native gem RUBY_CC_VERSION=1.8.7:1.9.2" end \ No newline at end of file diff --git a/ext/extconf.rb b/ext/extconf.rb deleted file mode 100644 index 22817c9..0000000 --- a/ext/extconf.rb +++ /dev/null @@ -1,26 +0,0 @@ -require 'mkmf' - -dir_config('sndfile') - -# Mega-Nerd windows installer installs as libsndfile-1.dll -if RUBY_PLATFORM =~ /(mswin|mingw|cygwin)/ - sndfile_lib = 'sndfile-1' -else - sndfile_lib = 'sndfile' -end - -# libsndfile requirements -find_header 'sndfile.h', '/opt/local/include', '/usr/local/include', 'C:/Program Files/Mega-Nerd/libsndfile/include' -unless find_library sndfile_lib, 'sf_open', '/opt/local/lib', '/usr/local/lib', 'C:/Program Files/Mega-Nerd/libsndfile' - fail <<-EOM - Can't find libsndfile (http://www.mega-nerd.com/libsndfile/) - - Try passing --with-sndfile-dir or --with-sndfile-lib and --with-sndfile-include - options to extconf. - EOM -end - -# Check for format support -have_const('SF_FORMAT_OGG', 'sndfile.h') - -create_makefile 'rubyaudio_ext' \ No newline at end of file diff --git a/ext/rubyaudio_ext/extconf.rb b/ext/rubyaudio_ext/extconf.rb new file mode 100644 index 0000000..090236d --- /dev/null +++ b/ext/rubyaudio_ext/extconf.rb @@ -0,0 +1,32 @@ +require 'mkmf' + +$CFLAGS.gsub!("-arch i386", "") +$LDFLAGS.gsub!("-arch i386", "") + +dir_config('sndfile') + +# Mega-Nerd windows installer installs as libsndfile-1.dll +if RUBY_PLATFORM =~ /(mswin|mingw|cygwin)/ + sndfile_lib = 'sndfile-1' +else + sndfile_lib = 'sndfile' +end + +INCLUDE_DIRS = ['/opt/local/include', '/usr/local/include', 'C:/Program Files/Mega-Nerd/libsndfile/include', 'C:/Program Files (x86)/Mega-Nerd/libsndfile/include'] +LIB_DIRS = ['/opt/local/lib', '/usr/local/lib', 'C:/Program Files/Mega-Nerd/libsndfile', 'C:/Program Files (x86)/Mega-Nerd/libsndfile'] + +# libsndfile requirements +find_header 'sndfile.h', *INCLUDE_DIRS +unless ['sndfile-1', 'sndfile'].any? {|lib| find_library lib, 'sf_open', *LIB_DIRS} + fail <<-EOM + Can't find libsndfile (http://www.mega-nerd.com/libsndfile/) + + Try passing --with-sndfile-dir or --with-sndfile-lib and --with-sndfile-include + options to extconf. If there are spaces in the path on windows, it may not work. + EOM +end + +# Check for format support +have_const('SF_FORMAT_OGG', 'sndfile.h') + +create_makefile 'rubyaudio_ext' \ No newline at end of file diff --git a/ext/ra_buffer.c b/ext/rubyaudio_ext/ra_buffer.c similarity index 100% rename from ext/ra_buffer.c rename to ext/rubyaudio_ext/ra_buffer.c diff --git a/ext/ra_buffer.h b/ext/rubyaudio_ext/ra_buffer.h similarity index 100% rename from ext/ra_buffer.h rename to ext/rubyaudio_ext/ra_buffer.h diff --git a/ext/ra_sound.c b/ext/rubyaudio_ext/ra_sound.c similarity index 100% rename from ext/ra_sound.c rename to ext/rubyaudio_ext/ra_sound.c diff --git a/ext/ra_sound.h b/ext/rubyaudio_ext/ra_sound.h similarity index 100% rename from ext/ra_sound.h rename to ext/rubyaudio_ext/ra_sound.h diff --git a/ext/ra_soundinfo.c b/ext/rubyaudio_ext/ra_soundinfo.c similarity index 100% rename from ext/ra_soundinfo.c rename to ext/rubyaudio_ext/ra_soundinfo.c diff --git a/ext/ra_soundinfo.h b/ext/rubyaudio_ext/ra_soundinfo.h similarity index 100% rename from ext/ra_soundinfo.h rename to ext/rubyaudio_ext/ra_soundinfo.h diff --git a/ext/rubyaudio_ext.c b/ext/rubyaudio_ext/rubyaudio_ext.c similarity index 100% rename from ext/rubyaudio_ext.c rename to ext/rubyaudio_ext/rubyaudio_ext.c diff --git a/lib/ruby-audio.rb b/lib/ruby-audio.rb index 42c530b..710dd63 100644 --- a/lib/ruby-audio.rb +++ b/lib/ruby-audio.rb @@ -1,4 +1,10 @@ -require 'rubyaudio_ext' +begin + # Fat binaries for Windows + RUBY_VERSION =~ /(\d+.\d+)/ + require "#{$1}/rubyaudio_ext" +rescue LoadError + require "rubyaudio_ext" +end require 'ruby-audio/buffer' require 'ruby-audio/sound_info' require 'ruby-audio/sound' \ No newline at end of file diff --git a/ruby-audio.gemspec b/ruby-audio.gemspec index 42ee817..67a010c 100644 --- a/ruby-audio.gemspec +++ b/ruby-audio.gemspec @@ -1,30 +1,22 @@ # -*- encoding: utf-8 -*- Gem::Specification.new do |s| - s.name = %q{ruby-audio} - s.version = "1.4.0" + s.name = 'ruby-audio' + s.version = '1.5.0' + s.platform = Gem::Platform::RUBY + s.authors = ['Stephen Augenstein'] + s.email = ['perl.programmer@gmail.com'] + s.homepage = 'http://github.com/warhammerkid/ruby-audio' + s.summary = 'libsndfile wrapper for ruby' + s.description = 'ruby-audio wraps around libsndfile to provide simplified sound reading and writing support to ruby programs' - s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version= - s.authors = ["Stephen Augenstein"] - s.date = %q{2010-12-23} - s.email = %q{perl.programmer@gmail.com} - s.extensions = ["ext/extconf.rb"] - s.files = ["README.rdoc", "Rakefile", "LICENSE", "lib/ruby-audio/buffer.rb", "lib/ruby-audio/sound.rb", "lib/ruby-audio/sound_info.rb", "lib/ruby-audio.rb", "spec/buffer_spec.rb", "spec/sound_info_spec.rb", "spec/sound_spec.rb", "spec/spec_helper.rb", "spec/spec.opts", "spec/data/what.wav", "spec/data/what2.wav", "spec/data/what.mp3", "ext/extconf.rb", "ext/ra_buffer.c", "ext/ra_sound.c", "ext/ra_soundinfo.c", "ext/rubyaudio_ext.c", "ext/ra_buffer.h", "ext/ra_sound.h", "ext/ra_soundinfo.h"] - s.homepage = %q{http://github.com/warhammerkid/ruby-audio} - s.rdoc_options = ["--line-numbers", "--main", "README.rdoc", "ext/ra_buffer.c", "ext/ra_sound.c", "ext/ra_soundinfo.c", "ext/rubyaudio_ext.c", "README.rdoc"] - s.require_paths = ["lib"] - s.requirements = ["libsndfile (http://www.mega-nerd.com/libsndfile/)"] - s.rubygems_version = %q{1.3.7} - s.summary = %q{ruby-audio wraps around libsndfile to provide simplified sound reading and writing support to ruby programs} - s.test_files = ["spec/buffer_spec.rb", "spec/sound_info_spec.rb", "spec/sound_spec.rb"] + s.files = Dir['ruby-audio.gemspec', 'README.rdoc', 'LICENSE', 'Rakefile', 'lib/**/*.rb', 'spec/**/*.{rb,opts,wav,mp3}', 'ext/**/*.{c,h,rb}'] + s.test_files = Dir['spec/**/*_spec.rb'] + s.extensions = Dir["ext/**/extconf.rb"] - if s.respond_to? :specification_version then - current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION - s.specification_version = 3 + s.requirements << 'libsndfile (http://www.mega-nerd.com/libsndfile/)' - if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then - else - end - else - end -end + s.has_rdoc = true + s.extra_rdoc_files = Dir['README.rdoc', 'ext/**/*.c'] + s.rdoc_options = ['--line-numbers', '--main', 'README.rdoc'] +end \ No newline at end of file diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index afc53d4..a6151d0 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -7,6 +7,5 @@ end require 'spec/autorun' -$:.unshift(File.join(File.dirname(__FILE__), '..', 'ext')) $:.unshift(File.join(File.dirname(__FILE__), '..', 'lib')) require 'ruby-audio' \ No newline at end of file