makefile之VPATH和vpath的使用

  来自阅读陈皓的《跟我一起写makefile》

  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.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预编译时头文件搜索路径

vpath关键字

。。。

  

原文地址:https://www.cnblogs.com/thammer/p/5533224.html