GNU Makefile 惊喜

pet*_*erh 3 make

我正在尝试使用 GNU make 构建一个简单的两阶段项目 Makefile。

我想遵循的逻辑是

  1. 首先我构造依赖项(by gcc -M
  2. 我在第二阶段构建中将生成的 .dep 文件包含到 Makefile 中。

我的项目的相关部分如下:

MAKEDEP:=$(CXX) $(CXXFLAGS) -M
ALL_SRCS:=$(ALL_OBJS:.o:.cc)
CXX_DEPS:=$(patsubst %.o,.%.dep,$(ALL_OBJS))

-include $(CXX_DEPS)

%.o: %.cc .%.dep
        $(CXX) $(CXXFLAGS) -c -o $@ $<

.%.dep: %.cc
        $(MAKEDEP) -o $@ $<

clean:
        $(RM) -vf $(ALL_OBJS) $(ALL_LIBS) $(ALL_APPS)

dep: $(CXX_DEPS)
Run Code Online (Sandbox Code Playgroud)

一切正常,只有一个例外:如果我运行 a make clean,它会重建依赖项!好像clean: dep存在一条线而不是一条简单的clean:线:

$ make clean
g++ -Wall -std=c++11 -M -o .file1.dep file1.cc
g++ -Wall -std=c++11 -M -o .file2.dep file2.cc
g++ -Wall -std=c++11 -M -o .file3.dep file3.cc
rm -vf file1.o file2.o file3.o app
$
Run Code Online (Sandbox Code Playgroud)

背景是什么?为什么需要在清理之前重建依赖项?我没有给出这样的依赖。

ctr*_*lor 5

因为您已经要求 make 包含这些文件,所以它会遵循规则来构建它们。

现在我会试着记住我是如何在我的项目中解决它的:

首先要意识到我们第一次并不关心额外的依赖关系,因为无论如何我们都必须构建目标文件。

然后,如果我们添加(或删除)依赖项,我们必须更改我们已经依赖的内容(.cc现有的或 之一.h)。

总之,我们不需要当前状态的完整依赖列表,前一个状态的依赖已经足够了。因此,我们可以在构建.deps 的同时构建s .o(这也更快,因为只CC需要一次传递)。

[下一点我不太确定]

现在我们需要引导依赖项:编写一个规则来创建一些虚拟(空).dep文件(每当 a.cc创建时(这可能很快))。

现在我们仍然需要创建这些虚拟.dep文件,然后清理它们。如果您避免递归 make,那么您就不需要 clean 来解决错误(只需要清理以节省磁盘空间)。

最后一步是添加一级递归(记住递归 make(通常)被认为是有害的http://lcgapp.cern.ch/project/architecture/recursive_make.pdf

为干净的规则编写一个简单的 makefile,为它不能执行的任何规则调用另一个 makefile。

您可能只需要这最后一步,但我不会删除答案的开头,因为它向您展示了如何改进 makefile。