0

到目前为止,我有一个运行良好的 Makefile。虽然,随着它开始增长,每次重新编译所有源代码开始花费太长时间。这是工作版本的一个片段:

CC=$(CROSS_COMPILE)g++
CFLAGS=-Wall -I./include -pg -O2
VPATH=./src:./include

all: dotgazer.cpp dotgazer/Dot.cpp
    $(CC) $(CFLAGS) $^ -o dotgazer.out `pkg-config --libs opencv`

还有更多的依赖关系,但这两个足以说明问题所在。我正在尝试将每个cpp文件的编译阶段移至单独的目标。当涉及到顶级文件 ( dotgazer.cpp) 时,这不是问题,一般规则%.o: %.cpp可以正常工作。但我无法让第二个依赖项工作。这是它现在的样子:

CC=$(CROSS_COMPILE)g++
CFLAGS=-Wall -I./include -pg -O2
VPATH=./src:./include

all: dotgazer.o dotgazer/Dot.o
    $(CC) $(CFLAGS) $^ -o dotgazer.out `pkg-config --libs opencv`

%.o: %.cpp
    $(CC) -c $(CFLAGS) $^ -o $@

dotgazer/Dot.o: dotgazer/Dot.cpp
    $(CC) -c $(CFLAGS) $^ -o $@

我已经尝试过不同的Dot.o规则变体,但它们似乎都不起作用。我得到的错误是:

Fatal error: can't create dotgazer/Dot.o: No such file or directory

我该怎么做?我最喜欢将.o文件放在与它们的源相同的文件夹中。另外,我会感谢一般规则(如%.o: %.cpp),因为有很多源文件,我不希望 Makefile 变得过于臃肿。谢谢!

4

1 回答 1

2

我认为您Makefile的内容有点具体,因此容易出错。我建议看看我下面的例子,它比你的更通用。

我的示例利用了make的隐含规则目录。对于cpp-files 已经存在一个通用的隐式规则。那么为什么不应该使用它!?

参考手册描述如下:

编译 C++ 程序

no 由 n.cc、n.cpp 或 nC 自动生成,配方形式为$(CXX) $(CPPFLAGS) $(CXXFLAGS) -c

因此,如果您有%.o文件作为先决条件,例如规则中的dotgazer.out: $(OBJS) make上述隐式规则会自动应用于所有这些文件。CXX假设您已经为,CPPFLAGS和/或设置了有效值CXXFLAGS

此外,您通常不需要手动将源添加到变量中。大多数时候,构建可执行文件需要项目目录树中的所有源代码。如果不是这种情况,您应该考虑构建一个反映这一点的适当树。

由于find负责将源分配给CPPFILES我们也不需要设置VPATH。由于我们使用了find并且patsubst我们的Makefile. 这使得处理具有大量不同来源的真实项目更加顺畅。

当然你不需要allandclean规则。为了方便起见,我只是添加了这些。

CXX=$(CROSS_COMPILE)g++
CPPFLAGS=-I./include
CXXFLAGS=-Wall -pg -O2
LDLIBS=`pkg-config --libs opencv`

CPPFILES=$(shell find . -name "*.cpp")
OBJS=$(patsubst %.cpp, %.o, $(CPPFILES))

all: dotgazer.out
    @echo $(CPPFILES)
    @echo $(OBJS)

dotgazer.out: $(OBJS)
    $(CXX) $(CXXFLAGS) -o $@ $^ $(LDLIBS)

clean: 
    rm -f $(OBJS)
于 2013-07-27T11:42:20.223 回答