一.make中的路径搜索
VPATH变量和vpath关键字同时指定搜索路径。
实验1 VPATH 和 vpath 同时指定搜索路径
mhr@ubuntu:~/work/makefile1/18$ tree
.
├── inc
│ └── func.h
├── main.c
├── makefile
├── src1
│ └── func.c
└── src2
└── func.c
makefile
VPATH := src1
CFLAGS := -I incvpath %.c src2
vpath %.h incapp.out : func.o main.o@gcc -o $@ $^@echo "Target File ==> $@"%.o : %.c func.h@gcc $(CFLAGS) -o $@ -c $<
main.c
#include <stdio.h>
#include "func.h"int main()
{foo();return 0;
}
src1/func.c
#include <stdio.h>
#include "func.h"void foo()
{printf("void foo() : %s\n", "This file is from src1 ...");
}
src2/func.c
#include <stdio.h>
#include "func.h"void foo()
{printf("void foo() : %s\n", "This file is from src2 ...");
}
inc/func.h
#ifndef FUNC_H
#define FUNC_Hvoid foo();#endifmhr@ubuntu:~/work/makefile1/18$ make
Target File ==> app.out
mhr@ubuntu:~/work/makefile1/18$ ./app.out
void foo() : This file is from src2 ...
mhr@ubuntu:~/work/makefile1/18$
结果表明 当VPATH 和 vpath 同时指定搜索路径,优先选择 vpath 指定的所搜路径。
改1:
将 src/func.c 改为 src1/func.cpp 会发生什么?
├── inc
│ └── func.h
├── main.c
├── makefile
├── src1
│ └── func.cpp
└── src2
└── func.c
mhr@ubuntu:~/work/makefile1/18$ make
Target File ==> app.out
mhr@ubuntu:~/work/makefile1/18$
mhr@ubuntu:~/work/makefile1/18$ ./app.out
void foo() : This file is from src2 ...
mhr@ubuntu:~/work/makefile1/18$
实验结论:
- make首先在当前文件夹搜索需要的文件
- 如果失败:make优先在vpath指定的文件夹中搜索目标文件,当vpath搜索失败时,转而搜索VPATH执行的文件夹。
实验2:当使用vpath 对.c文件指定多个文件夹时
├── inc
│ └── func.h
├── main.c
├── makefile
├── src1
│ └── func.c
└── src2
└── func.c
makefile
CFLAGS := -I incvpath %.c src1
vpath %.c src2vpath %.h incapp.out : func.o main.o@gcc -o $@ $^@echo "Target File ==> $@"%.o : %.c func.h@gcc $(CFLAGS) -o $@ -c $<mhr@ubuntu:~/work/makefile1/18$ make
Target File ==> app.out
mhr@ubuntu:~/work/makefile1/18$ ./app.out
void foo() : This file is from src1 ...
mhr@ubuntu:~/work/makefile1/18$
结论:当makefile中链接两个vpath时,会选择第一个链接到的。
改1
├── inc
│ └── func.h
├── main.c
├── makefile
├── src1
│ └── func.cpp
└── src2
└── func.c
makefile
CFLAGS := -I incvpath %.c src1
vpath %.c src2vpath %.h incapp.out : func.o main.o@gcc -o $@ $^@echo "Target File ==> $@"%.o : %.c func.h@gcc $(CFLAGS) -o $@ -c $<mhr@ubuntu:~/work/makefile1/18$
mhr@ubuntu:~/work/makefile1/18$ make
Target File ==> app.out
mhr@ubuntu:~/work/makefile1/18$ ./app.out
void foo() : This file is from src2 ...
mhr@ubuntu:~/work/makefile1/18$
先搜索src1,没有搜索到。再去搜索src2。
改2
├── inc
│ └── func.h
├── main.c
├── makefile
├── src1
│ └── func.cpp
└── src2
└── func.cpp
makefile
CFLAGS := -I incvpath %.c src1
vpath %.c src2vpath %.h incapp.out : func.o main.o@gcc -o $@ $^@echo "Target File ==> $@"%.o : %.c func.h@gcc $(CFLAGS) -o $@ -c $<mhr@ubuntu:~/work/makefile1/18$ make
make: *** No rule to make target 'func.o', needed by 'app.out'. Stop.
mhr@ubuntu:~/work/makefile1/18$
因为 make 在当前路径,src1,src2中都找不到 func.c, 于是make 又发现因事规则中可以通过cpp文件生成.o文件,但是在makefile中 没有找到 哪个vpath关键字指明了有cpp文件,所以找不到文件报错。
实验结论:
- make首先在当前文件夹搜索需要的文件
- 如果失败:make以自上而下的顺序搜索vpath指定的文件夹,当找到目标文件,搜索结束。