2012-12-25 21 views
17

我想写一个Makefile与我的源文件和目标文件分开,我似乎无法找出正确的方法来完成此操作。我有两种方法可行,但我希望有人能指出“正确”的方式来做到这一点。在GNU制造通配符目标的正确方法制造

我的项目被分隔成一个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) 

这似乎但是上班,我每次运行make prog一次重新编译所有的目标文件。 OBJ变量必须在所有对象前面有src/,否则我会得到“无法生成目标”的规则。另外,我可以轻松使用prog目标中的patsubst来指定目标文件。

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

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) 

这消除了目标文件的重新编译,但需要我再添变数POJBprog目标(因为我不能对没有basedir的对象文件做任何patsubst)。

这两种方法都有效,每种方法都有其优点,但哪一种方法是“正确”方法,如果两种方法都没有,那么实现这种类型建筑的正确方法是什么?

回答

19

你的第一个例子是几乎没有:

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 [email protected] 
+1

'SRC = $(通配符的src/**/* CPP)'源代码坐在'src'的子目录 – checksum