GMake サバイバルガイド
この GMake サバイバルガイドでは、まけふぁいる*1をささっと書いて楽をしたいけど、
どーやって書くのかわからないといった様な人たちに向けてこんな感じに書けば良いんじゃないかなーというのを書いていると思います。
あと、この記事のまけふぁいるのサンプルコードは便宜上 4 半角スペースでインデントしていますが、まけふぁいるのインデントは絶対にタブなので、実際にやって見る場合は注意してください。
最新のソースコードを実行したい!
Crystal のソースコードをコンパイルしてから実行するのは億劫ですよね。
% crystal build ./hoge.cr
% ./hoge
% crystal build ./hoge.cr
% ./hoge
% crystal build ./hoge.cr
% ./hoge
% crystal build ./hoge.cr
% ./hoge
何度も続けて行うなら、何とかして自動化してしまいたいもの。
まあ、cyrstal run ./hello.cr
とかすれば Crystal のソースコードから実行できるんですが、それは無視します。
以下のようなへろーわーるどなソースコードがあったとします:
# hello.cr puts "Hello, World!"
make
ってやるだけで、実行ファイルがなかったり古かったりしたらコンパイルして
とりあえず実行したい場合は私はまけふぁいるをこんな風に書きます:
.PHONY : run run: hello ./hello hello: hello.cr crystal build --release $^
.PHONY: run
というのは run
というシンボルはファイルじゃねーからよく覚えとけ!という意味を表明するために書いています。
これは省略可能です。
すぐ下の:
run: hello
./hello
こういうのをこの記事ではレシピ*2と呼びましょう。
レシピとはあるファイル○○を作るにはファイル△△が必要で、××するとできるというのをまけふぁいるの記述で書いたものです。
それをまけファイル用の記述で書くとこのようになります:
○○: △△ ××
先程のレシピに戻ると run
というファイルには hello
というものが必要で、run
を作るには ./hello
が必要で、 hello
コマンドを実行すればいいということが書いてあります。
しかし、run
というファイルは実際には作成されないので、何度も実行することが可能です。
そういえば、hello
はどうやって造られるのでしょう?
hello
のレシピはすぐ下にあります:
hello: hello.cr crystal build --release $^
hello
というファイルには hello.cr
というファイルが必要で、crystal build --release $^
を実行すればいいよね!ということが書いてあります。
$^
は必要なファイル──この場合では hello.cr
ですね──を参照する変数です。
作成するファイルを参照する変数は $@
なので、覚えておいてください。
とはいえ、この 2 つをもし忘れてもレシピは書けます。
hello: hello.cr
crystal build --release hello.cr
という風に書けばいいだけだからです。
替わりにめんどくさいというだけです。
たくさんのソースコードの中で、新しいのだけコンパイルしたい!!
おーけーべいべ!
まさにそのために make
は存在します。
例えば、ソースツリーに以下の LiveScript のソースコードがあったとします:
./routes.ls
./test/index.ls
./gulpfile.ls
./public/components/App.ls
./public/components/AddRoute.ls
./public/components/CounterRoute.ls
./public/store.ls
./public/action.ls
./server.ls
./config.ls
それに対して私の書いたまけふぁいるはこうです:
srcs = \ gulpfile.js \ routes.js \ server.js \ config.js \ test/index.js \ public/store.js \ public/action.js \ public/components/AddRoute.js \ public/components/App.js \ public/components/CounterRoute.js .PHONY : build build: $(srcs) gulpfile.js: gulpfile.ls lsc --debug --no-header -b -c $^ routes.js: routes.ls lsc --debug --no-header -b -c $^ server.js: server.ls lsc --debug --no-header -b -c $^ config.js: config.ls lsc --debug --no-header -b -c $^ test/index.js: test/index.ls lsc --debug --no-header -b -c $^ public/store.js: public/store.ls lsc --debug --no-header -b -c $^ public/action.js: public/action.ls lsc --debug --no-header -b -c $^ public/components/AddRoute.js: public/components/AddRoute.ls lsc --debug --no-header -b -c $^ public/components/App.js: public/components/App.ls lsc --debug --no-header -b -c $^ public/components/CounterRoute.js: public/components/CounterRoute.ls lsc --debug --no-header -b -c $^
これでもまだ力技を使っていますが、わかりやすいかもしれませんね。
test/index.ls
があるので、test
はこのように書けるかもしれません:
test: test/index.ls mocha $^ --compilers ls:livescript
まけふぁいるでは、変数も使えます。
srcs = \ gulpfile.js \ routes.js \ server.js \ config.js \ test/index.js \ public/store.js \ public/action.js \ public/components/AddRoute.js \ public/components/App.js \ public/components/CounterRoute.js
が、その例です。
これは、○○や△△、××で使用できます*3。
変数の値を参照するには $(src)
のように、$(
と )
で変数名を囲みます。
変数を使わない場合、build
はこのように、△△の部分が長くなってしまい、見るに絶えません。
build: gulpfile.js routes.js server.js config.js test/index.js public/store.js public/action.js public/components/AddRoute.js public/components/App.js public/components/CounterRoute.js
そういえば、build
には××の部分が存在しないことに気づいていると思います。
build
の××の部分は、既に△△のそれぞれの××が行っているので、必要ないのです。
(とはいえ、.o
を使って実行ファイルや .dll
、.so
を作成するような場合は必要です。)
今回は .ls
を .js
にトランスパイルするだけなので、××は書いていません。
えーん、あるファイル一つだけ make
したいよー
上の例で server.ls
だけをビルドしたいとしましょう。
この場合は以下のように打つだけです:
% make server.js
public/components/CounterRoute.ls
なら?
% make public/components/CounterRoute.js
ですね。
test/index.ls
なら?
% make test/index.js
ですね。
make CounterRoute.js
や make App.js
としないように気をつけてください。
それらは多分あなたが意図しているのとは違うファイルです。
そうそう、上の例で、make build
と打つ必要はありません。
make
と打つと、一番上のレシピ──この場合は build
──が実行されるからです。
いったんビルドしたのも全部ビルドしたいよ〜
make
にオプション -B
を付けてください。
% make -B