Scoping of implicit rules + Scoping of .SCANNER rules
OMake のお話。
% ワイルドカードの付いているルールは .SCANNER ルールも含め、global scope では無い! つまり、関数内で % を使ったルールを書いた場合、それは関数内でしか有効にならない! これを知らなかったので、% ワイルドカードのついた .SCANNER ルールを関数内で書いても効いて欲しい場所で効いていなかった!! export を使って外に出してやる必要がある! しかし名前が無いので引数無しの export だから他の名前も露出しちゃう。あららら。
詳しくは、 http://omake.metaprl.org/manual/omake-doc.html#section:implicit-scoping
例:
BYTE_ENABLED=true InstallRules() = .SCANNER: scan-ocaml-%: I_know_the_scanner I_know_the_scanner: println(I know the scanner) echo x > $@ .DEFAULT: test InstallRules() test: test.cmo ocamlc -o $@ $< .PHONY: clean clean: rm -f $(filter-proper-targets $(ls R, .))
この例は OCaml の依存解析をする前に、 I_know_the_scanner というファイルが必要である、と宣言している*つもり*。実際には I_know_the_scanner ではなくて、例えば CamlP4 のモジュールであるとか、ocamlfind であるとか、コンパイルに必要なツールの名前が来る。 さて、ここでは、% を使っているので、ルールはビルド時には有効ではない。omake test とすると普通に test.ml (空ファイルでもなんでもいい) をコンパイルして終わり。 I_know_the_scanner は作られない。
... InstallRules() = .SCANNER: scan-ocaml-%: I_know_the_scanner export ... InstallRules() ...
.SCANNER のルールの後に export を書くと、ルールが外にも有効になり、 I_know_the_scanner が作成される。もし、 InstallRules() が他の関数内で使われる場合は、さらに呼び出したところで export が必要になる:
... public.InstallRules() = .SCANNER: scan-ocaml-%: I_know_the_scanner export F() = InstallRules() export F() ...