# -*- ruby -*-

task :default => [:lib]


$srcDir = 'src'
$objDir = 'obj'

lib = 'libhouken.a'
houkenDir = 'houken'
sampleDir = 'sample'


#rule ".o" => [
#  proc {|tn| tn.sub(/\.o/, '.cpp').sub("#{$objDir}/", "#{$srcDir}/")}
#] do |t|
#  sh 'g++', '-g', '-c', '-o', t.name, t.source
#end
  

def makeDepend (srcFile)
  depFile = srcFile.sub("#{$srcDir}/", "#{$objDir}/").sub(/\.cpp$/, '.d')
  puts "makind #{depFile}"
  target = dep = nil
  open("| g++ -MM #{srcFile}") do |fd|
    target,dep = fd.read.gsub(/\\\s/, '').split(':', 2)
  end
  depends = dep.split(/\s+/)
  depends.delete('')
  target = $objDir + '/' + target
  open(depFile, 'w') do |out|
    a = ([target] + depends).join(',')
    out.puts a
  end
  file target => depends do
    sh 'g++', '-Wall', '-g', '-c', '-o', target, srcFile
  end
end


def readDepend (srcFile)
  depFile = srcFile.sub("#{$srcDir}/", "#{$objDir}/").sub(/\.cpp$/, '.d')
  begin
    open(depFile) do |fd|
      depends = fd.read.chomp.split(',')
      target = depends.shift
      file target => depends do
        sh 'g++', '-Wall', '-g', '-c', '-o', target, srcFile
      end
    end
    return true
  rescue Errno::ENOENT
    return false
  end
end



srcs = FileList["src/*.cpp"]
objs = srcs.ext('.o').map{|x| x.sub("#{$srcDir}/", "#{$objDir}/")}
deps = srcs.ext('.d').map{|x| x.sub("#{$srcDir}/", "#{$objDir}/")}


task :depend do
  srcs.each do |src|
    readDepend(src) or makeDepend(src)
  end
end

desc "create library libhouken.a"
task :lib => [:depend, lib]

file lib => objs do
  sh 'ar', 'rsc', lib, *objs
end

desc "create PEG parser generator 'houken/houken' executable"
task :houken do
  sh "(cd #{houkenDir}; rake)"
end

desc "create sample calculator 'sample/calc' executable"
task :sample do
  sh "(cd #{sampleDir}; rake)"
end


desc "do unittest"
task :unittest do
  sh '(cd unittest; rake)'
end

desc "do errortest"
task :errortest do
  sh '(cd errortest; rake)'
end

desc "cleanup library"
task :clean do
  FileUtils.rm_f(Dir["#{$objDir}/*.o"], :verbose => true)
  FileUtils.rm_f(Dir["#{$objDir}/*.d"], :verbose => true)
  FileUtils.rm_f(lib, :verbose => true)
end

desc "cleanup all"
task :allclean => :clean do
  sh '(cd unittest; rake clean)'
  sh "(cd #{houkenDir}; rake clean)"
  sh "(cd #{sampleDir}; rake clean)"
  sh '(cd errortest; rake clean)'
end
