gmake规则,用于由makefile创建的头文件

时间:2012-12-19 23:03:39

标签: makefile gnu-make

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

假设我可以传递do make BUILDTYPE=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次,我想确保此过程至少完成一次

我想要确保的是,此规则始终只运行一次。也就是说,即使存在buidtype.h,它仍然必须运行。我有自动依赖关系跟踪,它应该只在make运行时触发一次这个规则。

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

gmake有可能吗?

2 个答案:

答案 0 :(得分:1)

  

我需要确保每个cpp文件不会重复此过程1000次

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

  

我希望确保此过程至少完成一次

这样做的规范方法是:

.PHONY: force
buildtype.h: force

您没有要求它,而是一种实施

的简单方法
//pseudo code:
if(TMPFILE != buildtype.h)
    cat TMPFILE > buildtype.h

cmp -s TMPFILE buildtype.h || cp TMPFILE buildtype.h

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

一个解决方案是将正确的依赖项手动编码到makefile中,如

foo.o: buildtype.h # because foo.c includes buildtype.h

一个更简单但更糟糕的选择是编写

Makefile: buildtype.h

确保make任何其他内容之前更新buildtype.h(请参阅the manual)。所以现在buildtype.h永远不会丢失或过时。

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

这样非常难看的hackery来缓解
ifneq (clean,$(MAKECMDGOALS))
Makefile: buildtype.h
endif

答案 1 :(得分:0)

以下是使用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)