○[オレオレN6] PD m4(その27)
もう読んでる方も嫌になってきたであろう連載27回目だが、誰も読んでないので書いてるオレがウンザリする以外何も問題は生じないので世界は救われた。
ところで27という数字といえば27クラブすなわち我が永遠のアイドルJim Morrisonがパリ郊外のアパート内のバスタブで薬物のオーバードーズでThe Endとなった年齢やな、もう終わりにしてえ。
前回/usr/pkg/share/aclocal-1.16/init.m4の
13 m4_define([AC_PROG_CC],
14 m4_defn([AC_PROG_CC])
15 [_AM_PROG_CC_C_O
16 ])
でコケてるといったけど、トレース真面目に読んだらその一行前の
9 # This macro actually does too much. Some checks are only needed if
10 # your package does certain things. But this isn't really a big deal.
11
12 dnl Redefine AC_PROG_CC to automatically invoke _AM_PROG_CC_C_O.
でコケてたわ、いや先頭にdnlあったのでコメント行継続しとると思ったのだけど一行空行挟んでるんだがこれでも継続になるんかな。
実際にトレース読むと13行目でAC_PROG_CCを再定義する前にautoconf.m4f中のAC_PROG_CCが12行目で評価されとるなこれ。
m4trace:/usr/pkg/share/aclocal-1.16/init.m4:12: -1- id 1: AC_PROG_CC ...
m4trace:/usr/pkg/share/aclocal-1.16/init.m4:12: -1- id 1: AC_PROG_CC -> ???
m4trace:/usr/pkg/share/aclocal-1.16/init.m4:12: -1- id 1: AC_PROG_CC -> [_m4_defun_pro([AC_PROG_CC])AC_LANG_PUSH(C)dnl
(以下略)
ところがGNU m4ではdnl以降無視されてるのだよな、やっぱコメント行継続してるようだな。
m4debug: input read from /usr/pkg/share/aclocal-1.16/init.m4
m4trace:/usr/pkg/share/aclocal-1.16/init.m4:12: -1- id 1: dnl ...
m4trace:/usr/pkg/share/aclocal-1.16/init.m4:12: -1- id 1: dnl -> ???
m4trace:/usr/pkg/share/aclocal-1.16/init.m4:12: -1- id 1: dnl
m4trace:/usr/pkg/share/aclocal-1.16/init.m4:13: -1- id 2: m4_define ...
m4trace:/usr/pkg/share/aclocal-1.16/init.m4:14: -2- id 3: m4_defn ...
m4trace:/usr/pkg/share/aclocal-1.16/init.m4:14: -2- id 3: m4_defn([AC_PROG_CC]) -> ???
m4trace:/usr/pkg/share/aclocal-1.16/init.m4:14: -2- id 3: m4_defn(...) -> [m4_if([1], [0], [[m4_defn]],
はい、12行目はdnl以降なにもトレースに出てこず13行目以降のAC_PROG_CCの再定義に突入してるよね。
いやほんとm4とかろくに書いたことねえのでさっぱり判らんが。
とりあえず最小ケース的なものを作ってみる。
$ cat >unko.m4
# comment
dnl AC_PROG_CC
^D
まずはGNU m4
$ gm4 -DAC_PROG_CC=unko -g --debug=V test.m4
m4debug: input read from test.m4
# comment
m4trace:test.m4:3: -1- id 1: dnl ...
m4trace:test.m4:3: -1- id 1: dnl -> ???
m4trace:test.m4:3: -1- id 1: dnl
m4debug:test.m4:4: input exhausted
そしてオレオレPD m4
$ m4 -DAC_PROG_CC=unko -g --debug=V test.m4
# comment
m4trace:test.m4:3: -1- id 1: dnl ...
m4trace:test.m4:3: -1- id 1: dnl -> ???
m4trace:test.m4:3: -1- id 1: dnl -> `'
うーんGNU m4と同じ挙動で(トレース出力が微妙に違うのはもうしゃーない)コメント行継続で問題なさげである。
ところが-Dオプションでなく--reload-stateからAC_PROG_CCを読み込むと
$ m4 -g --reload-state=/usr/pkg/share/autoconf/autoconf/autoconf.m4f test.m4
# comment
m4: test.m4 at line 4: indir: undefined macro .
dnl _m4_divert_raw(10000)$
とバグるのだ。
ここではたと気づく、前回まるで動かなかった原因のautoconf.m4fって-Pオプションつまりm4_プリフィクスつきでシリアライズされてるはずなので、dnlでなくm4_dnlじゃねえと動かねえんじゃないっすかね。
しかしながらautoconf.m4fの中身を検証すると
2914 F3,3
2915 dnldnl
2916 T17,245
とこっちはm4_プリフィクス無しなのだ、なんじゃこりゃ何故にm4_プリフィクス有り無しが混在するのコレ(卒倒)。
つーか*.m4fにビルトインは
F[文字数1],[文字数2]
[文字列1][文字列2]
という形式でシリアライズされる、実際にさわりだけ出力すると
# This is a frozen state file generated by m4
V1
F7,7
includeinclude
F8,8
sincludesinclude
…
として記録され、-Pありなら
# This is a frozen state file generated by m4
V1
F10,7
m4_includeinclude
F11,8
m4_sincludesinclude
…
になるんだから-Pのフラグとか関係なしに[文字列2]の名を持つビルトインを[文字列1]の名前でハッシュテーブルに記録してけばいいだけか。
そもそも真面目にinfo読んだら-Pは-R指定時は無効とあるじゃねえのよ。
とりあえずこの修正を取り込んだらだいぶ先に進むようになったっぽいのだが
/usr/pkg/share/aclocal-1.16/make.m4:42: the top level
autom4te: error: /usr/src/external/bsd/m4/usr.bin/m4 failed with exit status: 1
aclocal: error: /usr/pkg/bin/autom4te failed with exit status: 1
autoreconf: error: aclocal failed with exit status: 1
と出てまたまた止まりよる、今度はなんですかね…もうお腹一杯なのでまた後日。