由makefile创建的头文件的gmake规则

由makefile创建的头文件的gmake规则,makefile,gnu-make,Makefile,Gnu Make,如何正确地为make本身生成的头文件编写gmake规则 假设我可以传递domakebuildtype=1,BUILDTYPE.h将被创建并填充为 #define BUILDTYPE 1 Makefile将简单地执行以下操作: buildtype.h: echo #define BUILDTYPE 1 > TMPFILE //pseudo code: if(TMPFILE != buildtype.h) cat TMPFILE > buildt

如何正确地为make本身生成的头文件编写gmake规则

假设我可以传递do
makebuildtype=1
,BUILDTYPE.h将被创建并填充为

#define BUILDTYPE 1
Makefile将简单地执行以下操作:

buildtype.h:
    echo #define BUILDTYPE 1 > TMPFILE
    //pseudo code:
    if(TMPFILE != buildtype.h)
        cat TMPFILE > buildtype.h
我需要确保此过程不会对每个cpp文件重复1000次,并且我希望确保此过程至少执行一次

我要确保的是,此规则始终且仅运行一次。也就是说,即使BuildType.h存在,也必须运行它。我有自动依赖项跟踪,它应该只在运行make时触发此规则一次

也就是说,如果我运行makebuildtype=2,而无需执行任何操作,它仍然必须为BUILDTYPE.h运行该规则,并且如果BUILDTYPE.h将根据它应该重新编译所有文件的规则进行更新


gmake有可能做到这一点吗

这里有一种使用sed的方法:

deps = 
ifdef BUILDTYPE
old = $(shell sed -n 's/\#define *BUILDTYPE *\([0-9]*\)/\1/p' buildtype.h)
ifneq ($(BUILDTYPE),$(old))
deps := buildtype.h
endif
endif

all: $(deps)
  @echo $(deps)
我需要确保这个过程不会对每个cpp文件重复1000次

你不需要做任何特殊的事情来确保这一点。Make将跟踪其已更新的目标。它不会因为多个其他目标依赖于其输出而多次重新运行规则

我想确保这个过程至少完成一次

实现这一点的标准方法是:

.PHONY: force
buildtype.h: force
您并没有要求它,而是一种简单的实现方法

更新:一个相关的“有趣的问题”是如何确保
buildtype.h
在任何编译尝试使用它之前是最新的。对于“干净”版本,自动依赖项跟踪系统可能会在这里失败,因为它们的输出仅基于它们在磁盘上可以看到的头文件;如果尚未创建
buildtype.h
makeDependent
gcc-M
无法了解它,因此无法生成正确的依赖项

一种解决方案是小心地将正确的依赖项手工编码到makefile中,如

foo.o: buildtype.h # because foo.c includes buildtype.h
另一种更简单但不太老套的方法是写作

Makefile: buildtype.h
它确保
make
在执行任何其他操作之前更新
buildtype.h
(请参阅)。所以现在,
buildtype.h
将永远不会丢失或过时

这种方法的一个缺点是,即使键入类似于
makeclean
的内容,也会导致
buildtype.h
被更新,即使在这种情况下根本不需要它。在特定情况下,这可以通过像

ifneq (clean,$(MAKECMDGOALS))
Makefile: buildtype.h
endif

假设
foo.o
依赖于
buildtype.h
。如果
buildtype.h
已经存在并且包含“1”,并且您运行
makebuildtype=1
,它是否应该重建
foo.o
?如果
buildtype.h
包含“2”,并且您运行
makebuildtype=2
,它是否应该重建任何内容?实际上buildtype.h的规则基本上创建了tmp文件,如果其内容不同,那么它将覆盖该文件。我更新了代码。我需要确保此过程不会对每个cpp文件重复1000次,并且我希望确保此过程至少执行一次。所以,为了回答你的问题:在没有必要的时候,它不会重建任何东西。我使用它作为android makefiles的一部分,它已经自动将各种依赖项添加到我的makefiles中。所以,这种方法有效吗(例如,有一个.PHONY指令在其他地方自动生成)我不知道android,但是多个.PHONY指令,即使对于同一个目标,也没有问题。它部分有效。它不适用于干净的项目(当没有生成依赖项信息时,依赖项信息是使用-MDD与编译一起生成的)。换句话说,对于一个干净的项目,make不知道编译c/cpp文件规则
force
是一个先决条件。我试图添加%.cpp:force,但它似乎不起作用。有没有办法向所有源文件添加一个先决条件?向所有源文件添加一个
force
先决条件不是一个好主意——这会导致make始终重建所有内容。也许您真正想要的是添加“buildtype.h”作为源文件编译规则的先决条件?我用一些可能有用的东西更新了答案。另外,我刚刚意识到“%.cpp:force”无法工作,因为“cpp”文件没有与之关联的规则。你真正的意思是“%.o:force”。
Makefile: buildtype.h
ifneq (clean,$(MAKECMDGOALS))
Makefile: buildtype.h
endif