2008年2月9日 星期六

gmake remove intermediate file

通常在 windows 寫簡單的程式時, 我習慣用 nmake, 雖然功能少, 但還堪用, 省得還得另外張羅或設定.
這幾天想用 suffixes 讓 make 自動推論來避免寫重複的 rule, 譬如像這樣(這是簡化過的例子)

$ cat makefile
.SUFFIXES : .c .obj .exe
all: file.exe
.c.obj:
touch $*.obj
.obj.exe:
touch $*.exe

當新增加 file2.c 時, 我只要在 makefile 多加 file2.exe, 剩下的事 make 會自動搞定.

然而事情沒我想像得那麼順利: 如果 file.obj 不存在, nmake 就會叫不知道怎麼生 file.exe. 也就是說, nmake 只能自動推論實際存在檔案的規則. 實在是相當差啊. 之後我原本想一些招數 workaround, 後來受不了乾脆換用 gmake.

雖然 gmake 如預期完成工作. 但它竟然在工作完成後把 file.obj 砍了. 以下是在 FreeBSD 做的實驗:

$ gmake
touch file.obj
touch file.exe
rm file.obj
$ make # bsdmake
touch file.obj
touch file.exe

可以看到 bsdmake 跟 gmake 行為不同. 查 gmake 文件才知道這是 feature, 可以用 .SECONDARY 語法避免砍檔.
intermediate files ...... if make does create b in order to update something else, it deletes b later on after it is no longer needed.
...... You can prevent automatic deletion of an intermediate file by marking it as a secondary file. To do this, list it as a prerequisite of the special target .SECONDARY.