ラベル 開発ツール の投稿を表示しています。 すべての投稿を表示
ラベル 開発ツール の投稿を表示しています。 すべての投稿を表示

2007年4月15日日曜日

make if関数

 makeのマニュアルとしてはGNU make 日本語訳(Coop編)をいつも使っているのだが、Linux2.6のカーネルのmakeファイルを覗いていたらそこに書いていない構文があった。

KBUILD_OUTPUT := $(shell cd $(KBUILD_OUTPUT) && /bin/pwd) $(if $(KBUILD_OUTPUT),, \       $(error output directory "$(saved-output)" does not exist))

 2行目の$(if ~, ~,)が書いていなかった。上記の日本語訳は1998年5月のGNU Make Version 3.77のものでかなり古いので、英語の方のマニュアルを見てみた。構文は下記のようになって特に難しいことはない。

$(if condition,then-part[,else-part])

 makeにはもうひとつifeq構文もあって(ifeqは3.77のマニュアルにも書いてある)、そっちはmakefile conditionalsを、一方ifは functional contextを判定するものという違いがあるということらしい。この記述だけだとよくわからないが、実行してみないとわからないもの(先のカーネルでは、shellでの実行結果)は、ifの方を使わなければならないということなのだろう。とりあえず、違いがあるということは覚えておこうと思う。

■ 参考資料

GNU `make' Manual(英語)
GNU make 日本語訳(Coop編)

2007年4月7日土曜日

M4 括弧つきマクロ

autoconfのm4ライブラリをちょっとのぞいていたら、よくわからないところがあった。
以下は/usr/share/autoconf/m4sugar/m4sugar.m4よりの抜粋。

# m4_include_unique(FILE)
# -----------------------
# Declare that the FILE was loading; and warn if it has already
# been included.
m4_define([m4_include_unique],
[m4_ifdef([m4_include($1)],
    [m4_warn([syntax], [file `$1' included several times])])dnl
m4_define([m4_include($1)])])

# m4_include(FILE)
# ----------------
# As the builtin include, but warns against multiple inclusions.
m4_define([m4_include],
[m4_include_unique([$1])dnl
m4_builtin([include], [$1])])
m4_include_uniqueとm4_includeという二つのマクロを定義している。m4_include_uniqueは複数回includeされているかチェックを行い、m4_includeはm4_include_uniqueで複数includeのチェックしてからincludeを行う。
m4_include_unique内の2行目と4行目に[m4_include($1)]という記述がある。[]はリテラル文字であり、これら2行は要はm4_include($1)という名前のマクロの存在チェックと定義を行っている。
m4のマニュアルによるとマクロ名に使えるのは、アルファベット、数字、_(アンダースコア) を自由に並べたもののうち、先頭の文字が数字でないものとなっており、"()"は許されていない。普通"("以下は引数とみなされる。

どんな動作なのかその部分だけ抜き出して、テストしてみた。
user@local:~/m4test$ less test2.m4
define(`m4_include_unique', `ifdef(`m4_include($1)', `already defined',
    `not defined
    define(`m4_include($1)', `include $1')')')
m4_include_unique(`aaa')
m4_include(aaa)
m4_include_unique(`aaa')
ifdef(`m4_include(aaa)', `already defined', `not defined')
このマクロの実行結果は以下のようになる。
user@local:~/m4test$ m4 test2.m4

not defined

m4_include(aaa)
already defined
already defined
結果からするとdefineやif_defの引数内ではクォートすれば、"()"つきのマクロ名の定義は可能であるようだ。
しかし、定義した後でもm4_include(aaa)がそのまま出力されていることから、マクロとして展開できていない。通常通りm4_includeがマクロ名、aaaが引数と解釈されている。
フラグとしてのみ使うので、展開できないマクロ名を使っているのだと思われる。

■ 参考資料

GNU macro processor: GNU macro processor