# -*- ruby -*-

#
# Rakefile for Houken unittest
#

require 'fileutils'

task :default => [:tester, :run]


$parserDir = '..'
$parserSrcDir = $parserDir + '/src'
$machdepUnixDir = $parserDir + '/machdep/unix'
$objDir = 'obj'

$ldflags = ['-static', '-L/usr/local/lib', '-lcppunit']
$cppflags = ["-g", "-I#{$parserSrcDir}", "-I."]
target = 'tester.exe'

srcs = FileList["#{$parserSrcDir}/*.cpp"] + FileList['*.cpp']
srcs.include($machdepUnixDir + '/sysDep.cpp')
objs = srcs.ext('.o').map{|f| $objDir + '/' + File.basename(f)}
deps = srcs.ext('.d').map{|f| $objDir + '/' + File.basename(f)}


def makeDepend (srcFile)
  depFile = $objDir + '/' + File.basename(srcFile).sub(/\.cpp$/, '.d')
  puts "makind #{depFile} ..."
  target = dep = nil
  open("| g++ -MM -I#{$parserSrcDir} -I#{$machdepUnixDir} -I. #{$cppflags.join(' ')} #{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', '-I', $machdepUnixDir, '-I.', '-c', '-o', target, *($cppflags + [srcFile])
  end
end


def readDepend (srcFile)
  depFile = $objDir + '/' + File.basename(srcFile).sub(/\.cpp$/, '.d')
  begin
    open(depFile) do |fd|
      depends = fd.read.chomp.split(',')
      target = depends.shift
      file target => depends do
        sh 'g++', '-Wall', '-I', $machdepUnixDir, '-c', '-o', target, *($cppflags + [srcFile])
      end
    end
    return true
  rescue Errno::ENOENT
    return false
  end
end


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


desc "build tester"
task :tester => [:depend, target]

file target => objs do
  sh 'g++', '-o', target, *(objs.to_a + $ldflags)
end


desc "run tester"
task :run => target do
  sh './' + target
end


desc "cleanup unittest binaries"
task :clean do
  FileUtils.rm_f(Dir[target + '*'], :verbose => true)
  FileUtils.rm_f(Dir[$objDir + '/*.o'], :verbose => true)
  FileUtils.rm_f(Dir[$objDir + '/*.d'], :verbose => true)
end
