自動生成依賴

在為一個程式編寫的makefile 檔中,常常需要寫許多僅僅是說明一些OBJ 檔依靠頭檔 的規則。例如,如果‘main.c’通過一條#include語句使用‘defs.h’,您需要寫入下的規則:

main.o: defs.h

您需要這條規則讓make 知道如果‘defs.h’一旦改變必須重新構造‘main.o’。由此您可以 明白對於一個較大的程式您需要在makefile檔中寫很多這樣的規則。而且一旦添加或去掉一 條#include語句您必須十分小心地更改makefile檔。 為避免這種煩惱,現代C編譯器根據原程式中的#include語句可以為您編寫這些規則。 如果需要使用這種功能,通常可在編譯根源程式時加入‘-M’開關,例如,下面的命令:

cc -M main.c

產生如下輸出:

main.o : main.c defs.h

這樣您就不必再親自寫這些規則,編譯器可以為您完成這些工作。

我們推薦使用自動生成依賴的習慣是把makefile檔和根源程式檔一一對應起來。如,對 每一個根源程式檔‘name.c’有一名為‘name.d’的makefile 檔和它對應,該makefile 檔中列出 了名為‘name.o’的OBJ檔所依賴的檔。這種方式的優點是僅在根源程式檔改變的情況下才有 必要重新掃描生成新的依賴。 這裏有一個根據C語言根源程式‘name.c’生成名為‘name.d’依賴檔的格式規則:

%.d: %.c
    set -e; $(CC) -M $(CPPFLAGS) $< \
    | sed 's/\($*\)\.o[ :]*/\1.o $@ : /g' > $@; \
    [ -s $@ ] || rm -f $@

set命令作用主要是顯示系统中已經存在的shell變量,以及設置shell變量的新變量值。‘-e’開關是告訴shell 如果$(CC)命令運行失敗(非零狀態退出)立即退出。正常情況下,shell 退出時帶有最後一個命令在管道中的狀態(sed),因此make不能注意到編譯器產生的非零狀態。sed用法sed's/regularexpression/replacement/g'用replacement替換符合regularexpression的字串。 命令Sed 的作用是翻譯(例如):

main.o : main.c defs.h

到:

main.o main.d : main.c defs.h

這使每一個‘.d’檔和與之對應的‘.o’檔依靠相同的根源程式檔和頭檔,據此,Make 可以知道 如果任一個根源程式檔和頭檔發生變化,則必須重新構造依賴檔。 一旦您定義了重新構造‘.d’檔的規則,您可以使用使用include命令直接將它們讀入,例如:

include *.d

results matching ""

    No results matching ""