GNU Make中通配符目标的正确方法

nhm*_*ood 19 makefile wildcard gnu-make target

我试图编写一个Makefile与我的源文件和目标文件分开,我似乎无法找到实现这一目标的正确方法.我有两种方法可行,但我希望有人可以指出"正确"的方法来做到这一点.

我的项目被分成一个srcobj文件夹,Makefile与这些文件处于同一级别.

第一种方法使用通配符函数查找源文件,src然后使用文本替换来确定相应的目标文件.

SRC = $(wildcard src/*.cpp)
OBJ = $(SRC:.cpp=.o)

prog: $(OBJ)
       $(CC) $(CFLAGS) $(LDFLAGS) $(LIBS) -o prog $(patsubst src/,obj/,$(OBJ))

%.o: %.cpp
     $(CC) $(CFLAGS) -c $< -o $(COMPILE)/$(@F)  
Run Code Online (Sandbox Code Playgroud)

这似乎有效,但是,每次运行make prog它都会重新编译所有目标文件.该OBJ变量必须具有src/的所有对象的前面,否则我得到了"没有规则,使目标".从好的方面来说,我可以轻松地使用prog 目标中的patsubst 来指定目标文件.

第二种方法类似,但在OBJ变量上使用vpath和文本替换:

 vpath = %.cpp src
 vpath = %.o obj

 SRC = $(wildcard src/*.cpp)
 OBJ = $(subst src/,,$(SRC:.cpp=.o))
 POBJ = $(patsubst src/,obj/$(SRC:.cpp=.o))

 prog: $(OBJ)
       $(CC) $(CFLAGS) $(LDFLAGS) $(LIBS) -o prog $(POBJ)

 %.o: %.cpp
     $(CC) $(CFLAGS) -c $< -o $(COMPILE)/$(@F)  
Run Code Online (Sandbox Code Playgroud)

这消除了重新编译目标文件,但需要我POJBprog目标添加另一个变量(因为我不能在没有基础的目标文件上做任何patsubst).

这两种方法都有效,每种方法都有其优势,但其中一种是"正确的"方法,如果不是,那么实现这种建筑的正确方法是什么?

per*_*eal 22

你的第一个例子几乎就在那里:

SRC = $(wildcard src/*.cpp)
OBJ = $(patsubst src/%.cpp, obj/%.o, $(SRC))

prog: $(OBJ)
  $(CC) $(CFLAGS) $(LDFLAGS) $(LIBS) $(OBJ) -o prog 

obj/%.o: src/%.cpp
  $(CC) $(CFLAGS) -c $< -o $@
Run Code Online (Sandbox Code Playgroud)

  • `SRC = $(wildcard src/**/*.cpp)`用于源代码,位于`src`的子目录中 (4认同)