我的项目中有一个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 $<
答案 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
。