来自阅读陈皓的
VPATH变量
在一些大的工程中,有大量的源文件,我们通常的做法是把这许多的源文件分类,并存放在不同的目录中。所以,当 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.oCINCLUDES = -I./foodir -I./bardirCFLAGS = -WallTARGET = test$(TARGET):$(OBJS) $(CC) $(CFLAGS) $^ -o $@ $(CINCLUDES) .PHONY:cleanclean: 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预编译时头文件搜索路径。
vpath关键字
。。。