30
31

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

rakeのruleをもっと柔軟に使う

Posted at

rakeにはtaskやfile以外に、ruleという定義が使えます。簡単に言うとmakeのサフィックスルールで、こういうファイルだったら、こういうファイルにしますよ、という正しくルールを定義するためのものです。以下簡単に使い方。

rule '.o' => '.c' do |t|
  sh "gcc -o #{t.name} #{t.source}"
end

上記は「".o"で終わるタスク名(ファイル名じゃない!)が与えられ、そのタスク名の".o"を".c"に置き換えたものをソースファイルとし、そのソースファイルが存在するならタスクを実行する」という意味になります。実際に実行してみた方が分かりやすいですね。

$ ls src
hello.c
$ rake --rules src/hello.o # --rulesオプションをつけると実際どうやってruleが解決されているか分かる
Attempting Rule src/hello.o => src/hello.c
(src/hello.o => src/hello.c ... EXIST)
gcc -o src/hello.o src/hello.c
$ rake --rules src/world.o
Attempting Rule src/world.o => src/world.c
(src/world.o => src/world.c ... FAIL)
rake aborted!
Don't know how to build task 'src/world.o'

(See full trace by running task with --trace)

これ、パッと見ると、拡張子でしか定義できないように見えます。実は正規表現を与えることが出来るので、そうすれば自在にパターンを定義できます。

rule %r{^dist/.+\.o} => '%{^dist,src}X.c' do |t|
  sh "gcc -o #{t.name} #{t.source}"
end
$ rake --rules dist/hello.o
Attempting Rule dist/hello.o => src/hello.c
(dist/hello.o => src/hello.c ... EXIST)
gcc -o dist/hello.o src/hello.c

ちなみに変換方法に指定されている"%{^dist,src}X"はpathmapという仕組みで、"%X"だけ指定するとマッチしたタスク名をファイル名と見立て、「拡張子を取り除いた文字列」を意味し、"%{正規表現,置換文字列}X"とすると、「拡張子を取り除き、正規表現にマッチした文字列を置換文字列に置き換えた文字列」となります。ぐっちゃぐちゃですね。まあ上記の例を見ていただければと思います。

ちなみに変換方法にはProcのインスタンスを与えることが出来るので、そちらを与えると自由自在に変換できますね。

ちょっと前にruleについて調べていたら、なかなか融通効かないなーと思っていましたが、正規表現とProcを使えばやりたい放題でした。

30
31
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
30
31

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?