GNU Makefile 惊喜

GNU Makefile 惊喜

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

我想要遵循的逻辑是

  1. 首先我构建依赖项(通过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)

一切正常,除了一个例外:如果我运行 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
$

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

答案1

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

现在我将尝试记住我是如何在我的项目中解决这个问题的:

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

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

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

[接下来的一点我不太确定]

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

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

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

为干净的规则编写一个简单的 makefile,该文件对另一个 makefile 调用 make 以处理它无法执行的任何规则。

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

相关内容