來自閱讀陳皓的《跟我一起寫makefile》
在一些大的工程中,有大量的源文件,我們通常的做法是把這許多的源文件分類,並存放在不同的目錄中。所以,當 make 需要去找尋文件的依賴關系時,你可以在文件前加上路徑,但最好的方法是把一個路徑告訴 make,讓 make 在自動去找。Makefile 文件中的特殊變量“VPATH”就是完成這個功能的,如果沒有指明這個變量,make 只會在當前的目錄中去找尋依賴文件和目標文件。如果定義了這個變量,那么,make就會在當當前目錄找不到的情況下,到所指定的目錄中去找尋文件了。
VPATH = dir1 : dir2
上面的的定義指定兩個目錄,“dir1”和“dir2”,make 會按照這個順序進行搜索。目錄由“冒號”分隔。(當然,當前目錄永遠是最高優先搜索的地方)
怎么使用呢?
假設有以下工程,目錄數為:
./ ├── bardir │ ├── bar.c │ └── bar.h ├── command.h ├── foodir │ ├── foo.c │ └── foo.h ├── main.c ├── Makefile └── README.md
main.c中調用了bar.c foo.c中的函數,最直白的makefile
OBJS = main.o foodir/foo.o bardir/bar.o CINCLUDES = -I./foodir -I./bardir CFLAGS = -Wall TARGET = test $(TARGET):$(OBJS) $(CC) $(CFLAGS) $^ -o $@ $(CINCLUDES) .PHONY:clean clean: rm $(OBJS) $(TARGET)
查看目錄樹
./ ├── bardir │ ├── bar.c │ ├── bar.h │ └── bar.o ├── command.h ├── foodir │ ├── foo.c │ ├── foo.h │ └── foo.o ├── main.c ├── main.o ├── Makefile ├── README.md └── test
如果模塊目錄比較深,那么OBJS后面會跟一大堆,這時VPATH變量起到作用了,改進后的makefile
VPATH = ./foodir:./bardir
OBJS = foo.o bar.o main.o
CINCLUDES = -I./foodir -I./bardir
CFLAGS = -Wall $(CINCLUDES)
TARGET = test
$(TARGET):$(OBJS)
$(CC) $(CFLAGS) $^ -o $@
.PHONY:clean
clean:
@-rm -f $(TARGET) $(OBJS)
再查看目錄樹:
./ ├── bardir │ ├── bar.c │ └── bar.h ├── bar.o ├── command.h ├── foodir │ ├── foo.c │ └── foo.h ├── foo.o ├── main.c ├── main.o ├── Makefile ├── README.md └── test
對比上一次可以看到子目錄下生成的.o文件現在生成在Makefile這一級目錄了。需要注意的是:通過VPATH告知文件搜尋路徑是告知的make,這利於它隱式推導時的文件搜索,而不是告知的gcc,所以還是得通過-I指定gcc預編譯時頭文件搜索路徑。
。。。