Makefile - 文件夹中的依赖项文件“没有这样的文件或目录”

时间:2013-07-27 10:30:56

标签: build makefile dependencies

到目前为止,我有一个运行良好的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过于膨胀。谢谢!

1 个答案:

答案 0 :(得分:1)

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

我的例子充分利用了make隐含规则的措辞。对于cpp - 文件已存在通用隐式规则。那么为什么不使用它呢?

参考手册描述如下:

  

编译C ++程序

     

n.o是从n.cc,n.cpp或n.C自动生成的,其形式为$(CXX) $(CPPFLAGS) $(CXXFLAGS) -c

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

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

由于find负责将来源分配到CPPFILES,因此我们也不需要设置VPATH。由于我们使用findpatsubst,我们的Makefile只有一个明确的文件名。这使得在一个真正的项目上工作得更加顺畅。

当然,您不需要allclean规则。我刚刚添加了这些以方便起见。

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)