Rakefileでg++コンパイルするとき、ヘッダファイルの依存関係をインポートしてみる
Rakefileは便利なのでg++コンパイルでMakefileの代替になればと思い、いろいろ模索中です。
ひとまず、簡単なメイクは作れるようになってきたところです。
で、問題が1つ浮上。
これまでMakefileでやっていたヘッダファイルの依存関係を定義していましたが、Rakefileでどう記述すればよいかわかりません。
ネットをいろいろ漁ってみたのですが、なかなか解が見つからず。。
とりあえず、自力で考えてなんとなくうまくいったっぽいRakefileをメモします。
あまり、Rakefileのドキュメント見ずに書いたのでちょっぴり不安ですが。。
CXX = "g++" CFLAGS = "-O2 -Wall -I./" LIBS = "-lm" TARGET = "run.x" srcs = FileList["*.cpp"] objs = srcs.ext('o') deps = srcs.ext('d') task :default => :all task :all => TARGET require 'rake/clean' CLEAN.include objs CLEAN.include deps CLOBBER.include TARGET task :clean_all => :clobber file TARGET => objs do |t| sh "#{CXX} -o #{t.name} #{t.prerequisites.join(' ')} #{LIBS}" end rule '.o' => ['%n.cpp', "%n.d"] do |t| sh "#{CXX} #{CFLAGS} -c #{t.source}" end srcs.each do |src| dep = src.sub(/\.(c|cpp)$/,".d") file dep => src do |t| tmp = `#{CXX} -MM #{CFLAGS} #{src}` obj,arg = tmp.gsub(/\\\n /,"").split(":") str = "file " + obj.inspect + " => [" + arg.split(' ').map{|m| m.inspect }.join(",") + "]" File.open(t.name,"w") {|f| f.write str} end import dep end
肝となるのは、以下の記述です。
srcs.each do |src| dep = src.sub(/\.(c|cpp)$/,".d") file dep => src do |t| tmp = `#{CXX} -MM #{CFLAGS} #{src}` obj,arg = tmp.gsub(/\\\n /,"").split(":") str = "file " + obj.inspect + " => [" + arg.split(' ').map{|m| m.inspect }.join(",") + "]" File.open(t.name,"w") {|f| f.write str} end import dep end
処理の流れは、
- "g++ -MM"で依存関係データを取得
- それを、"file obj => [srcs]"の形式に置換
- その文字列を、".d"ファイルに書き込む
- 最後に"import"で".d"をインポートする
そして、".o"を生成するruleに"%n.d"を追加。
eachを使って処理できるのがrubyっぽいかも。
あっているのかなぁ。自信なし。