GNU Make中通配符目标的正确方法 [英] Proper method for wildcard targets in GNU Make
问题描述
我正在尝试编写一个Makefile,将源文件和目标文件分开,我似乎无法找出实现此目的的正确方法.我有两种可行的方法,但我希望有人可以指出实现此目的的正确"方法.
I am trying to write a Makefile with my source and object files separated and I can't seem to figure out the proper way to accomplish this. I have two methods that work but I'm hoping someone can point the "correct" way to do this is.
我的项目被分成一个src
和obj
文件夹,并且Makefile与这些文件位于同一级别.
My project is separated into a src
and obj
folder with the Makefile at the same level as these.
第一种方法使用通配符功能在src
中查找源文件,然后使用文本替换来确定相应的目标文件.
The first method uses the wildcard function to find the source files in src
then uses text replacement to determine the corresponding object files.
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)
这似乎可行,但是,每次我运行make prog
时,它都会重新编译所有目标文件. OBJ
变量必须在所有对象的前面带有src/
,否则我将获得没有规则可用于确定目标".从正面来看,我可以轻松地使用prog
目标中的patsubst指定目标文件.
This seems to work, however, every time I run make prog
it recompiles all the object files. The OBJ
variable has to have the src/
in front of all the objects or else I get the "no rule to make target". On the plus side, I can easily use the patsubst in the prog
target to specify the object files.
第二种方法类似,但是在OBJ
变量上使用vpath和文本替换:
The second method is similar but uses vpaths and text replacement on the OBJ
variable:
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)
这消除了对目标文件的重新编译,但是需要我为prog
目标添加另一个变量POJB
(因为没有基于baseir的对象,我不能仅对目标文件执行任何操作).
This eliminates the recompiling of object files, but requires me to add another variable POJB
for the prog
target (since I can't do any patsubst on just the object files without a basedir).
这两种方法都可以工作,并且每种方法都有优势,但是哪种方法是正确的"方法,如果没有,那么实现这种类型的建筑的正确方法是什么?
Both methods work and each has its advantages over the other but which one is the "correct" approach and if neither, what is the proper way to achieve this type of building?
推荐答案
您的第一个示例就差不多了:
Your first example is almost there:
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 $@
这篇关于GNU Make中通配符目标的正确方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!