Rakefileでg++コンパイルするとき、.oファイルを別ディレクトリにする

g++コンパイルするとき、".o"ファイルがソースと同じディレクトリにあるのがあまり好きではありません。
そこで、.objdirというディレクトリを作成し、そこに".o"や".mf"を置くようにしたいと思います。

CXX = "g++"

CFLAGS = "-O2 -Wall"
LIBS   = "-lm"

TARGET = "run.x"
OBJDIR = ".objdir"

srcs = FileList["*.cpp", "*.c"]
objs = srcs.pathmap("#{OBJDIR}/%n.o")

task :default => :all

# clean
require 'rake/clean'
CLEAN.include objs
CLOBBER.include TARGET,OBJDIR
desc "Clean all."
task :clean_all => :clobber

directory OBJDIR

desc "Build all."
task :all => TARGET

file TARGET => objs do |t|
  sh "#{CXX} -o #{t.name} #{t.prerequisites.join(' ')} #{LIBS}"
end

# build
srcs.each do |src|
  obj = src.pathmap("#{OBJDIR}/%n.o")
  file obj => [src,OBJDIR] do
    sh "#{CXX} #{CFLAGS} -o #{obj} -c #{src}"
  end
end

# generate dependency information
require 'rake/loaders/makefile'
srcs.each do |src|
  dep = src.pathmap("#{OBJDIR}/%f.mf")
  file dep => [src,OBJDIR] do |t|
#    sh "#{CXX} -MM #{CFLAGS} #{src} > #{dep}"
    sh "#{CXX} -MM #{CFLAGS} #{src} | sed -e 's/\\(.*\\)\\.o:/#{OBJDIR}\\/\\1.o:/g' > #{dep}"
  end
  import dep
  CLEAN.include dep
end

たぶん、できました。
今回は、ruleは使いませんでした。おそらくpathmapを駆使することでruleで同様のことができると思われますが、よくわかりませんでした。
Rakefileでは、動的タスク生成が可能なのでなんとかなってしまうところがありがたいです。

おまけ

一部sedを使っていますが、外部コマンドを使わないでやってみると、

# sh "#{CXX} -MM #{CFLAGS} #{src} | sed -e 's/\\(.*\\)\\.o:/#{OBJDIR}/\\/\\1.o:/g' > #{dep}"
 sh "#{CXX} -MM #{CFLAGS} #{src} > #{dep}"
 ruby %{-i -pe '$_.sub!(/(.*).o:/,"#{OBJDIR}/\\\\1.o:")' #{dep}}

"\"が4つも繋がっちゃいました。