class MkmfRakeBuilder attr_writer :project_dir, :rake_application, :rake_tasks, :rake_file_tasks, :dir_class, :file_extension, :extensions_to_build, :file_class def initialize @extconf_file = "extconf.mkmf.rb" end def build_default_task task(:extension => [ :compile, :install ]) do end task(:default => [ :extension ]) do end end def build_compile_task task :compile => @extensions_to_build.collect {|ext| ext.first} do end end def build_spec_task task :spec => [:compile, :install] do dir = @project_dir require expand_path("#{dir}/spec/spec_suite") end end def build_lib_task task :lib do directory "lib" end end def build_extension_compile_tasks @extensions_to_build.each do |data| build_extension_compile_task(data[1]) end end def build_install_task extension_paths = self.extension_paths task :install do extension_paths.each do |extension_path| library_path = library_path(extension_path) raise "Extension binary for #{extension_path} does not exist. Did you run rake compile?" unless library_path build_path = build_path(extension_path) raise "File #{build_path} does not exist" unless file_exists?(build_path) cp build_path, library_path(extension_path) end end extension_paths end def build_cleanup_task extension_paths = self.extension_paths task :cleanup do extension_paths.each do |extension_path| library_path = library_path(extension_path) rm library_path if library_path && file_exists?(library_path) build_file_path = build_path(extension_path) rm build_file_path if build_file_path && file_exists?(build_file_path) make_file_path = "#{build_dir(extension_path)}/Makefile" rm make_file_path if make_file_path && file_exists?(make_file_path) end end extension_paths end protected def extension_paths @extensions_to_build.collect {|data| data[1]} end def build_extension_compile_task(extension_path) extension_dir = "ext/#{extension_path}" extension = file_name(extension_path) extension_path = "#{extension_dir}/#{extension}.#{@file_extension}" desc "Builds the #{extension} extension" task extension.to_sym => ["#{extension_dir}/Makefile", extension_path ] file "#{extension_dir}/Makefile" => ["#{extension_dir}/#{@extconf_file}"] do extconf extension_dir end ext_files = FileList[ "#{extension_dir}/*.c", "#{extension_dir}/*.h", "#{extension_dir}/#{@extconf_file}", "#{extension_dir}/Makefile", "lib" ] file extension_path => ext_files do make extension_dir end end def extconf(dir) chdir(dir) do ruby @extconf_file end end def ruby(file) sh("ruby #{file}") end def make(makedir) chdir(makedir) do sh("make") end end def chdir(dir, &block) @dir_class.chdir(dir) do yield end end def desc(comment) @rake_application.last_comment = comment end def task(*args, &block) @rake_tasks.define_task(*args, &block) end def file(*args, &block) @rake_file_tasks.define_task(*args, &block) end def build_dir(relative_extension_path) "#{@project_dir}/ext/#{relative_extension_path}" end def build_path(relative_extension_path) basename = "#{build_dir(relative_extension_path)}/#{file_name(relative_extension_path)}" "#{basename}.#{@file_extension}" end def library_path(relative_extension_path) library_directory_path = "#{@project_dir}/lib/#{file_directory(relative_extension_path)}" binary_name = "#{file_name(relative_extension_path)}.#{@file_extension}" "#{library_directory_path}/#{binary_name}" end def expand_path(path) @file_class.expand_path path end def file_exists?(path) @file_class.exists? path end def file_name(path) @file_class.basename path end def file_directory(path) @file_class.dirname path end end