Makefile操作序列

Makefile操作序列,makefile,Makefile,我试图找出如何实现生成依赖项的Makefile代码 depend: .depend .depend: $(SRCS) rm -f ./.depend $(CC) $(CFLAGS) -MM $^ > ./.depend; include .depend 但是,我必须修改它,以便在每次运行make时重新生成.depend。我试图通过创建一个调用rm-f./.dependent的虚假目标来实现这一点,但是,不管我如何安排,它总是在.dependent之后

我试图找出如何实现生成依赖项的Makefile代码

depend: .depend

.depend: $(SRCS)
        rm -f ./.depend
        $(CC) $(CFLAGS) -MM $^ >  ./.depend;

include .depend

但是,我必须修改它,以便在每次运行make时重新生成.depend。我试图通过创建一个调用
rm-f./.dependent
的虚假目标来实现这一点,但是,不管我如何安排,它总是在
.dependent
之后和
之前运行。另一方面,如果我能让
.dependent
配方在任何情况下都能运行,那会更好。

虽然我同意上面的评论,即每次重新生成依赖项都没有好处,但我也认为首先实现所有这些并不是你的工作。作为一个可靠的构建工具,我们会为您解决这个问题。而且它不局限于头文件依赖项,但它考虑了所有因素,比如更改了命令行,所以它更正确


还有很多事情要做。除了做GNU make所能做的几乎所有事情外,还有很多更有用的事情,你甚至可以通过一些Perl编程来扩展你的make文件。

虽然我同意上面的评论,即每次重新生成依赖项都没有好处,但我也认为首先实现所有这些并不是你的工作。作为一个可靠的构建工具,我们会为您解决这个问题。而且它不局限于头文件依赖项,但它考虑了所有因素,比如更改了命令行,所以它更正确


还有很多事情要做。除了做GNU make所能做的几乎所有事情外,还有许多更有用的事情,您甚至可以通过一些Perl编程来扩展make文件。

这种处理依赖关系的方法是非常次优的。创建依赖项信息的最佳方法是作为编译的副作用。它甚至比您现在所做的还要快,因为编译器已经必须计算所有这些信息

编译代码时,您已经知道此生成实例需要重建目标。构建的副作用是创建依赖项信息,这是为了构建的下一个实例。GCC提供了
-MMD-MP
选项,使其工作良好。在这种配置中,您绝对不应该提供单独的规则来构建包含的文件(这将破坏一切)。相反,可以这样做:

SRCS = foo.c bar.c baz.c ...

%.o : %.c
        $(CC) $(CPPFLAGS) $(CFLAGS) -MMD -MP -o $@ -c $<

-include $(SRCS:.c=.d)
SRCS=foo.cbar.cbaz.c。。。
%.o:%.c
$(CC)$(CPPFLAGS)$(CFLAGS)-MMD-MP-o$@-c$<
-包括$(SRCS:.c=.d)

使用
-include
,这样,如果依赖项文件尚未创建,则不会出现任何错误。就这样,这就是你所要做的。

这种处理依赖关系的方法是非常次优的。创建依赖项信息的最佳方法是作为编译的副作用。它甚至比您现在所做的还要快,因为编译器已经必须计算所有这些信息

编译代码时,您已经知道此生成实例需要重建目标。构建的副作用是创建依赖项信息,这是为了构建的下一个实例。GCC提供了
-MMD-MP
选项,使其工作良好。在这种配置中,您绝对不应该提供单独的规则来构建包含的文件(这将破坏一切)。相反,可以这样做:

SRCS = foo.c bar.c baz.c ...

%.o : %.c
        $(CC) $(CPPFLAGS) $(CFLAGS) -MMD -MP -o $@ -c $<

-include $(SRCS:.c=.d)
SRCS=foo.cbar.cbaz.c。。。
%.o:%.c
$(CC)$(CPPFLAGS)$(CFLAGS)-MMD-MP-o$@-c$<
-包括$(SRCS:.c=.d)

使用
-include
,这样,如果依赖项文件尚未创建,则不会出现任何错误。就这样,这就是你所要做的。

如果你想每次都得到依赖项,我想你最好每次都编译。编译器必须处理源代码才能获得依赖项,这样每次编译的主要部分都会完成(至少包括预处理器)。@Jonathan编译器不必处理源代码,只需获取每个对象所需的头文件列表。根据经验,我可以说这是有区别的,因为它以这种方式编译得更快。要确定所需的头文件,它必须读取源文件并充分注意预处理,以知道哪些头文件包含在当前选项和定义下,等等。它不必保留预处理的源代码,也不必做任何其他事情,因此它肯定比完整编译更简单,但它必须完成打开文件的所有工作,而打开文件本身相当慢。如果对你有用,那好。我没有对依赖项使用这种技术-我假设依赖项在很长一段时间内是稳定的,并且很少或从来没有出现过问题(我不知道是什么时候出现的)。@Jonathan好的,我相信你一定是对的,如果有足够的源文件和依赖项,那么会出现显著的减速(如果我理解的话)。在任何情况下,似乎我试图用Makefile完成的工作都应该是微不足道的。如果源代码没有更改,为什么要重建
。dependent
?如果每次都要获得依赖项,我想,你最好每次都编译。编译器必须处理源代码才能获得依赖项,这样每次编译的主要部分都会完成(至少包括预处理器)。@Jonathan编译器不必处理源代码,只需获取每个对象所需的头文件列表。根据经验,我可以说这是有区别的,因为它以这种方式编译得更快。要确定所需的头文件,它必须读取源文件并充分注意预处理,以知道哪些头文件包含在当前选项和定义下,等等。它不必保留预处理的源代码,也不必做任何其他事情,因此它当然比完整编译更简单,但它必须完成打开文件的所有工作,