こんにちはRakefile

2007-12-20

噂のRakefileを使ってみた。 チュートリアルはRake RubyによるビルドツールRakeの覚え書き。興に乗ったので詳しく書いてみた。でバッチリ。 簡単なルールならホント簡単に(Rubyを知ってれば)書くことができた。

しかし、オブジェクトファイルをソースファイルとは別のディレクトリに吐き出そうとしたらあまり情報がなくて結構つまずいた。 http://onestepback.org/index.cgi/Tech/Rake/Tutorial/RakeTutorialAnotherCExample.red を見てできた。 rule ごとに lambda を書くのが面倒だと思ったので、それも関数に移動した:

require 'rake/clean'

CC = "gcc"
OBJDIR = './objs'

SRCS = FileList["**/*.c"]
OBJS = SRCS.collect {|item| File.join(OBJDIR, File.basename(item).ext('o'))}

task :default => "hello"

CLEAN.include(OBJS, OBJDIR)
CLOBBER.include("hello")

def find_source(srcs)
lambda do |objfile|
base = File.basename objfile, ".*"
srcs.find {|s| File.basename(s, ".*") == base}
end
end

file "hello" => [OBJDIR] + OBJS do |t|
sh "#{CC} -o #{t.name} #{OBJS.join(' ')}"
end

directory OBJDIR

rule '.o' => find_source(SRCS) do |t|
sh "#{CC} -o #{t.name} -c #{t.source}"
end

これはこれでいいんだけど、.o に対する .h の依存関係が書けてない。 ルールに対して後から依存関係を追加できればいいんだけどやりかたがわからんので、依存関係のハッシュを渡してプロシジャ側でやる:

def find_source(srcs, depends=nil)
lambda do |objfile|
base = File.basename objfile, ".*"
src = srcs.find {|s| File.basename(s, ".*") == base}

dep = depends[objfile] if depends
dep ? [src, dep] : src
end
end

depends = {
"#{OBJDIR}/message.o" => ["message.h"],
}

rule '.o' => find_source(SRCS, depends) do |t|
sh "#{CC} -o #{t.name} -c #{t.source}"
end