[プログラミング] Rake を使ってみる
Rake という新しいオモチャに手を出している今日この頃.Rake というのは make っぽい機能を提供してくれる Ruby のモジュールです.
make と比べると,make が文字列しか扱えないのに対して,Rake は Ruby の上で動くので,もう文字列,配列,ハッシュなどを慣れ親しんだ Ruby の機能でいろいろ操作できます.便利.
もう 1 個の利点といえば... cp や rm といったコマンドの名前が環境ごとに異なるということを考えなくともよいということでしょうか.書き手は FileUtils の関数を使って Rakefile (make でいう Makefile です) を書いておけば,あとは Ruby が吸収してくれるので楽です (コンパイラやリンカはコマンドが存在しないとダメですが...).
さて,Rake の使い方はいでさく氏のサイトに詳しく書いてあるのでそちらを参照するとして (私もそこで学びました),一通りの使い方が分かったところでさぁ書いてみようと,まずは以下の Rakefile を作りました.
TARGET = "test"
# Rake は最初に default と名づけられたタスクを実行する
task :default => TARGET
SRCS = FileList[ "test.cc", "test2.c" ]
OBJS = SRCS.ext('o')
# OBJS をリンクして実行ファイルを作る
file TARGET => OBJS do |t|
sh "g++ -o #{t.name} #{t.prerequisites.join(' ')}"
end
# .o のファイルは .cc や .c から作られるということを教える.
# ファイル名を明示せずとも,Rake が自動的にこのルールを適宜当てはめてくれる.
rule ".o" => ".cc" do |t|
sh "g++ -c -o #{t.name} #{t.source}"
end
rule ".o" => ".c" do |t|
sh "gcc -c -o #{t.name} #{t.source}"
end
これを test.cc と test2.c のあるディレクトリで実行すると,次のようにちゃんとビルドが実行できます.
$ rake (in /home/hoge) g++ -c -o test.o test.cc gcc -c -o test2.o test2.c g++ -o test.exe test.o test2.o $
うまく動きました.test.cc だけ touch してから再実行すると,make と同様にちゃんと test.cc だけ再コンパイルしてくれます.
ここで,ソースコードは全て ./src に,オブジェクトファイルは全て ./objs に分けたい場合は,rule ".o" => ".cc" が使えない(マッチしない)ので,Rakefile を次のように書く必要があるみたいです.
TARGET = "test"
task :default => TARGET
OBJ_DIR = "objs"
SRCS = FileList[ "src/test.cc", "src/test2.c" ]
directory OBJ_DIR
file TARGET => OBJS do |t|
sh "g++ -o #{t.name} #{t.prerequisites.join(' ')}"
end
# SRCS の各要素に対して 1 個ずつファイルタスクを作る
SRCS.each do |src|
obj = src.sub( %r{^src/(.*)\.(cc|c)}, OBJ_DIR+'/\1.o' )
file obj => [OBJ_DIR, src] do
sh "g++ -c -o #{obj} #{src}"
end
end
コンパイル前にオブジェクトファイル用のディレクトリを作ってもらわないといけないので,directory タスクを付け加えています.
最初は下のように書いてみたりもしましたが,Rake を実行時に objs/test.o の作り方が分からんと言われてしまいました.
TARGET = "test"
task :default => TARGET
# ソースは src ディレクトリ
SRCS = FileList[ "src/test.cc", "src/test2.c" ]
# 中間ファイルは objs ディレクトリ
OBJS = SRCS.sub(/^src\//, 'objs/').ext('o')
file TARGET => OBJS do |t|
sh "g++ -o #{t.name} #{t.prerequisites.join(' ')}"
end
rule ".o" => ".cc" do |t|
sh "g++ -c -o #{t.name} #{t.source}"
end
rule ".o" => ".c" do |t|
sh "g++ -c -o #{t.name} #{t.source}"
end
それにしても,Rake 面白いですね.
トラックバック
トラックバック URI: https://www.pakunet.jp/hoge/trackback/2007110801
トラックバックはありません.