如何强制make始终重建文件

时间:2011-10-04 06:01:18

标签: makefile

我的项目中有一个version.c文件,其中包含项目的当前版本以及其他一些从makefile作为定义(-D编译器选项)传递的内容。

我知道要强制make来编译version.c,无论修改日期如何,我都可以touch version.c

是否只有makefile才能实现此目的?如果我写.PHONY : version.o,则目标文件根本不会构建。

修改 这是我的makefile:

export CC = gcc


export MODULES = $(sort \
     sys \
     cim \
     version \
)

export FILES = $(sort \
             main.c \
             cim.c \
             version.c \
)

VPATH = $(MODULES)

OBJS = $(FILES:.c=.o)

INCLUDES = $(addprefix -I,$(MODULES))

all:$(OBJS)
    $(CC) $(INCLUDES) $(OBJS) -o main.exe


clean:
    rm -rf *.o *.exe

cim.o: cim.c
main.o: main.c cim.o
version.o: version.c

.PHONY: version.o

.c.o :
    $(CC) $(CFLAGS) $(INCLUDES) -c $<

4 个答案:

答案 0 :(得分:43)

这样做的经典方法是:

version.o:   .FORCE

.FORCE:

(您可以添加.PHONY: .FORCE)。假定文件'.FORCE'不存在,因此它总是'创建',因此version.o总是过时的,所以version.o总是被编译。

我不确定将version.o变成虚假文件是否正确;它实际上是一个真实的文件,而不是虚假文件。

答案 1 :(得分:8)

不是makefile方式,但比触摸更容易:

make -B
  

' - B'' - round-make'

     

将所有目标都视为过时。 GNU make继续使用常规算法来考虑目标及其先决条件;然而,   无论状态如何,所有考虑的目标总是被重建   他们的先决条件。为了避免无限递归,如果MAKE_RESTARTS   (请参阅其他特殊变量)设置为大于0的数字   在考虑是否重制makefile时,选项被禁用(参见   如何制作Makefiles)。

答案 2 :(得分:5)

如果您想使用FORCE机制执行此操作,正确的解决方案如下所示:

version.o: FORCE

.PHONY: FORCE
FORCE:

明确声明FORCE是假的,即使使用了.SECONDARY:,我们也会确保一切正常(.SECONDARY:会导致FORCE被视为中间文件,并且不会重建中间文件,除非它们具有比最终目标更新的先决条件,并且FORCE没有任何先决条件,因此需要.PHONY: FORCE

另一个解决方案(使用$(shell touch version.c))也有一个问题:它可能会导致编辑器认为version.c已经更新,并提示重新加载文件,如果你&可能最终会破坏性#39;已经编辑了文件的缓冲区但还没有保存它。如果你不介意这一点,可以通过观察touch命令是静默的来更简单,因此不需要分配hack虚拟变量:

$(shell touch version.c)  # This is enough, but will likely confuse your editor

.PHONY&#34;技巧&#34;在问题的评论中提到的一般都不起作用。它可能看起来像是因为它会强制重新链接iff version.o已经存在,但如果.o文件规则是一个隐含规则(通常是fooprog: test.o cp $< $@ %.o: %.c cp $< $@ .PHONY: test.o # WRONG clean: rm test.o fooprog 文件规则,实际的目标文件将不会被重建是)。问题是make不会对明确的虚假目标进行隐式规则搜索。此make文件显示失败:

.PHONY: version.o

如果使用静态模式规则而不是隐式规则,@Html.DisplayFor(modelItem => item.vouchertype == "P" ? "Paid" : "Receipt") & @Html.DisplayFor(modelItem => item.dated.ToString("dd-MMM-yy")) 技巧将起作用。通常,使用静态模式规则而不是隐式规则会削减大多数令人困惑的Make行为。但大多数make文件都使用隐式规则。

答案 3 :(得分:0)

快速黑客版本,当你需要它工作而你不想玩制作游戏时:

# Hack to get main.c rebuilt
hack := $(shell touch main.c)

基本上只为你制作运行touch