概念

此处的搜索路径是指依赖文件的搜索路径

在大型项目中往往需要根据模块来放置各个文件,如果每个以来文件前面都要加上xx/xx/xx/..来指明相对路径,那么将十分繁琐和易错,因此Makefile提供一种搜索路径的机制——当我们制定了路径之后,当make在当前路径没有找到依赖文件的时候,它会在搜索路径下面查找相应的依赖文件

通用搜索

使用VPATH变量,为全部依赖文件指定搜索路径

# 注意各目录间用冒号分隔
VPATH = src: include: ../headers
foo: foo.cc

此时make会按照指明的顺序进行搜索,一旦找到便进行替换,比如foo.cc在src文件中,那么规则将被替换为

foo: src/foo.cc

选择性搜索

使用vpath指令,为特定文件类型指定搜索路径

# 也可以写成vpath %.h include: ../headers
vpath %.h include
vpath %.h ../headers

此时make在查找.h结尾的文件时,会顺序查找指定的文件夹,方法和结果和通用搜索相似

搜索流程

在Makefile中,往往一个规则中的依赖文件,是另一个规则中的目标文件,比如*.o文件。当一个依赖文件在搜索路径中找到,这条路径信息根据不同的情况选择保留或者抛弃。

  1. 如果目标文件不存在当前目录中,make就会对它进行目录搜索
  2. 如果搜索成功,路径信息会暂时和目标文件关联
  3. 这个目标文件的所有依赖文件遵循上面两条规则进行搜索
  4. 完成以后,make要判断目标文件是否要重建——如果不需要重建,目标文件的路径信息将被保留,当它作为依赖文件被其它文件使用时,它的路径信息就是搜索到的路径信息;否则,目标文件的路径信息被舍弃,它将被重建在当前路劲下(默认),而不是搜索到的路径中,它作为依赖文件被其它文件使用时,它的路劲信息就不是搜索到的那个信息了

利用搜索路径写命令

VPATH = src:../headers
foo.o : foo.c defs.h hack.h
        cc -c $< -o $@

使用自动变量可以用上搜索路径时找到的信息,注意搜索路径信息被舍弃的情况

路径搜索与链接库

当库作为依赖文件时,书写规则和普通的依赖文件有些区别

foo : foo.c -lcurses
        cc $^ -o $@

当依赖文件中有”-lname”形式的字符出现时,make会搜索libname.so文件,如果没找到就会在当前路径、指定的搜索路径和系统的库路径中搜索libname.a,上面的命令最后可能会变成

cc foo.c /usr/lib/libcurses.a -o foo

该不该使用 VPATH 和 vpath

由于目标需要重建时,路径信息会被舍弃,往往我们需要把目标文件放置在非当前路径时会很困难,因为无法在命令中用到路径信息 > 当想接合VPATH和目标文件时,有下面两种思路

  1. 一种解决方法是把目标文件都生成在当前目录下
  2. 另一种解决方法是不使用VPATH查找目标文件,详见此处,此时可以使用vpath选择搜索*.c
# 不用VAPTH又想让目标文件和源文件分离时的方法
PROGS   = foo
OBJECTS = foo.o bar.o

#Makefile放在源文件目录中
OBJDIR = ../obj

#vpath %.c ./

$(OBJDIR)/%.o : %.c
	$(COMPILE.c) $< -o $@

OBJPROG = $(addprefix $(OBJDIR)/, $(PROGS))

all: $(OBJPROG)

$(OBJPROG): $(addprefix $(OBJDIR)/, $(OBJECTS))
	$(LINK.o) $^ $(LDLIBS) -o $@



Zhu

有问题欢迎发邮件交流