Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
tree: 14cdafaa35
Fetching contributors…

Cannot retrieve contributors at this time

file 233 lines (208 sloc) 7.681 kb
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233
require 'rake/clean'
require 'rake/gempackagetask'
require 'rake/rdoctask'
require 'rake/testtask'
begin
  require 'rake/extensiontask'
rescue LoadError
  abort "To build, please first gem install rake-compiler"
end

RbConfig = Config unless defined?(RbConfig)

NAME = "hpricot"
REV = (`#{ENV['GIT'] || "git"} rev-list HEAD`.split.length + 1).to_s
VERS = ENV['VERSION'] || "0.8" + (REV ? ".#{REV}" : "")
PKG = "#{NAME}-#{VERS}"
BIN = "*.{bundle,jar,so,o,obj,pdb,lib,def,exp,class,rbc}"
CLEAN.include ["#{BIN}", "ext/**/#{BIN}", "lib/**/#{BIN}", "test/**/#{BIN}",
               'ext/fast_xs/Makefile', 'ext/hpricot_scan/Makefile',
               '**/.*.sw?', '*.gem', '.config', 'pkg', 'lib/hpricot_scan.rb', 'lib/fast_xs.rb']
RDOC_OPTS = ['--quiet', '--title', 'The Hpricot Reference', '--main', 'README.md', '--inline-source']
PKG_FILES = %w(CHANGELOG COPYING README.md Rakefile) +
      Dir.glob("{bin,doc,test,extras}/**/*") +
      (Dir.glob("lib/**/*.rb") - %w(lib/hpricot_scan.rb lib/fast_xs.rb)) +
      Dir.glob("ext/**/*.{h,java,c,rb,rl}") +
      %w[ext/hpricot_scan/hpricot_scan.c ext/hpricot_scan/hpricot_css.c ext/hpricot_scan/HpricotScanService.java] # needed because they are generated later
RAGEL_C_CODE_GENERATION_STYLES = {
  "table_driven" => 'T0',
  "faster_table_driven" => 'T1',
  "flat_table_driven" => 'F0',
  "faster_flat_table_driven" => 'F1',
  "goto_driven" => 'G0',
  "faster_goto_driven" => 'G1',
  "really_fast goto_driven" => 'G2'
  # "n_way_split_really_fast_goto_driven" => 'P<N>'
}
DEFAULT_RAGEL_C_CODE_GENERATION = "really_fast goto_driven"
SPEC =
  Gem::Specification.new do |s|
    s.name = NAME
    s.version = VERS
    s.platform = Gem::Platform::RUBY
    s.has_rdoc = true
    s.rdoc_options += RDOC_OPTS
    s.extra_rdoc_files = ["README.md", "CHANGELOG", "COPYING"]
    s.summary = "a swift, liberal HTML parser with a fantastic library"
    s.description = s.summary
    s.author = "why the lucky stiff"
    s.email = 'why@ruby-lang.org'
    s.homepage = 'http://code.whytheluckystiff.net/hpricot/'
    s.rubyforge_project = 'hobix'
    s.files = PKG_FILES
    s.require_paths = ["lib"]
    s.extensions = FileList["ext/**/extconf.rb"].to_a
    s.bindir = "bin"
  end

# FAT cross-compile
# Pass RUBY_CC_VERSION=1.8.7:1.9.2 when packaging for 1.8+1.9 mswin32 binaries
%w(hpricot_scan fast_xs).each do |target|
  Rake::ExtensionTask.new(target, SPEC) do |ext|
    ext.lib_dir = File.join('lib', target) if ENV['RUBY_CC_VERSION']
    ext.cross_compile = true # enable cross compilation (requires cross compile toolchain)
    ext.cross_platform = 'i386-mswin32' # forces the Windows platform instead of the default one
  end

  # HACK around 1.9.2 cross .def file creation
  def_file = "tmp/i386-mswin32/#{target}/1.9.2/#{target}-i386-mingw32.def"
  directory File.dirname(def_file)
  file def_file => File.dirname(def_file) do |t|
    File.open(t.name, "w") do |f|
      f << "EXPORTS\nInit_#{target}\n"
    end
  end

  task File.join(File.dirname(def_file), "Makefile") => def_file
  # END HACK
  file "lib/#{target}.rb" do |t|
    File.open(t.name, "w") do |f|
      f.puts %{require "#{target}/\#{RUBY_VERSION.sub(/\\.\\d+$/, '')}/#{target}"}
    end
  end
end
file 'ext/hpricot_scan/extconf.rb' => :ragel

desc "set environment variables to build and/or test with debug options"
task :debug do
  ENV['CFLAGS'] ||= ""
  ENV['CFLAGS'] += " -g -DDEBUG"
end

desc "Does a full compile, test run"
if defined?(JRUBY_VERSION)
task :default => [:compile_java, :clean_fat_rb, :test]
else
task :default => [:compile, :clean_fat_rb, :test]
end

task :clean_fat_rb do
  rm_f "lib/hpricot_scan.rb"
  rm_f "lib/fast_xs.rb"
end

desc "Packages up Hpricot for all platforms."
task :package => [:clean]

desc "Run all the tests"
Rake::TestTask.new do |t|
    t.libs << "test"
    t.test_files = FileList['test/test_*.rb']
    t.verbose = true
end

Rake::RDocTask.new do |rdoc|
    rdoc.rdoc_dir = 'doc/rdoc'
    rdoc.options += RDOC_OPTS
    rdoc.main = "README.md"
    rdoc.rdoc_files.add ['README.md', 'CHANGELOG', 'COPYING', 'lib/**/*.rb']
end

Rake::GemPackageTask.new(SPEC) do |p|
    p.need_tar = true
    p.gem_spec = SPEC
end

### Win32 Packages ###
Win32Spec = SPEC.dup
Win32Spec.platform = 'i386-mswin32'
Win32Spec.files = PKG_FILES + %w(hpricot_scan fast_xs).map do |t|
  unless ENV['RUBY_CC_VERSION']
    file "lib/#{t}/1.8/#{t}.so" do
      abort "ERROR while packaging: re-run for fat win32 gems:\nrake #{ARGV.join(' ')} RUBY_CC_VERSION=1.8.7:1.9.2"
    end
  end
  ["lib/#{t}.rb", "lib/#{t}/1.8/#{t}.so", "lib/#{t}/1.9/#{t}.so"]
end.flatten
Win32Spec.extensions = []

Rake::GemPackageTask.new(Win32Spec) do |p|
  p.need_tar = false
  p.gem_spec = Win32Spec
end

JRubySpec = SPEC.dup
JRubySpec.platform = 'java'
JRubySpec.files = PKG_FILES + ["lib/hpricot_scan.jar", "lib/fast_xs.jar"]
JRubySpec.extensions = []

Rake::GemPackageTask.new(JRubySpec) do |p|
  p.need_tar = false
  p.gem_spec = JRubySpec
end

desc "Determines the Ragel version and displays it on the console along with the location of the Ragel binary."
task :ragel_version do
  @ragel_v = `ragel -v`[/(version )(\S*)/,2].to_f
  puts "Using ragel version: #{@ragel_v}, location: #{`which ragel`}"
  @ragel_v
end

desc "Generates the C scanner code with Ragel."
task :ragel => [:ragel_version] do
  if @ragel_v >= 6.1
    @ragel_c_code_generation_style = RAGEL_C_CODE_GENERATION_STYLES[DEFAULT_RAGEL_C_CODE_GENERATION]
    Dir.chdir("ext/hpricot_scan") do
      sh %{ragel hpricot_scan.rl -#{@ragel_c_code_generation_style} -o hpricot_scan.c}
      sh %{ragel hpricot_css.rl -#{@ragel_c_code_generation_style} -o hpricot_css.c}
    end
  else
    STDERR.puts "Ragel 6.1 or greater is required."
    exit(1)
  end
end

# Java only supports the table-driven code
# generation style at this point.
desc "Generates the Java scanner code using the Ragel table-driven code generation style."
task :ragel_java => [:ragel_version] do
  if @ragel_v >= 6.1
    puts "compiling with ragel version #{@ragel_v}"
    Dir.chdir("ext/hpricot_scan") do
      sh %{ragel -J -o HpricotCss.java hpricot_css.java.rl}
      sh %{ragel -J -o HpricotScanService.java hpricot_scan.java.rl}
    end
  else
    STDERR.puts "Ragel 6.1 or greater is required."
    exit(1)
  end
end

### JRuby Compile ###

def java_classpath_arg # myriad of ways to discover JRuby classpath
  begin
    cpath = Java::java.lang.System.getProperty('java.class.path').split(File::PATH_SEPARATOR)
    cpath += Java::java.lang.System.getProperty('sun.boot.class.path').split(File::PATH_SEPARATOR)
    jruby_cpath = cpath.compact.join(File::PATH_SEPARATOR)
  rescue => e
  end
  unless jruby_cpath
    jruby_cpath = ENV['JRUBY_PARENT_CLASSPATH'] || ENV['JRUBY_HOME'] &&
      FileList["#{ENV['JRUBY_HOME']}/lib/*.jar"].join(File::PATH_SEPARATOR)
  end
  unless jruby_cpath || ENV['CLASSPATH'] =~ /jruby/
    abort %{WARNING: No JRuby classpath has been set up.
Define JRUBY_HOME=/path/to/jruby on the command line or in the environment}
  end
  "-cp \"#{jruby_cpath}\""
end

def compile_java(filenames, jarname)
  sh %{javac -source 1.5 -target 1.5 #{java_classpath_arg} #{filenames.join(" ")}}
  sh %{jar cf #{jarname} *.class}
end

task :hpricot_scan_java => [:ragel_java] do
  Dir.chdir "ext/hpricot_scan" do
    compile_java(["HpricotScanService.java", "HpricotCss.java"], "hpricot_scan.jar")
  end
end

task :fast_xs_java do
  Dir.chdir "ext/fast_xs" do
    compile_java(["FastXsService.java"], "fast_xs.jar")
  end
end

%w(hpricot_scan fast_xs).each do |ext|
  file "lib/#{ext}.jar" => "#{ext}_java" do |t|
    mv "ext/#{ext}/#{ext}.jar", "lib"
  end
  task :compile_java => "lib/#{ext}.jar"
end
Something went wrong with that request. Please try again.