大多数makefile具有如下结构:
.PHONY: prebuild
all: $(TARGET)
prebuild: Makefile
$(shell DEPDIR=$(DEPDIR) mkdir -p $(DEPDIR)/../common >/dev/null)
# do other work related to preparing for the object files to be built such as run a script to modify a header file included by $(TARGET).c
$(TARGET): $(TARGET).c prebuild
$(CC) $(CFLAGS) -o $(TARGET) $(TARGET).c
隐式规则知道如何从$(TARGET).o
构建$(TARGET).c
,并且如果$(TARGET).o
已经比$(TARGET).c
更新了,则不做任何工作。当多次运行make而不更改源文件时,会发生这种情况。
但是,构建上面的all
目标似乎总是会重新运行$(CC) $(CFLAGS) -o $(TARGET) $(TARGET).c
链接以链接应用程序并创建应用程序二进制文件。即使该二进制文件已经存在并且不需要重新创建,也会发生这种情况。在某些较大的项目中,此过程可能需要很长时间(数十秒),这有时是不希望的。
编辑#1:这个问题与在创建目标文件之前我想运行一次ONCE的额外假目标有关。就我而言,我正在运行一个包含Makefile变量并可能更新C文件中包含的头文件的脚本。但是,如果Makefile不变,则不会运行预构建目标。但是,即使$(TARGET)
不执行任何操作(例如,因为prebuild
未被更改),Makefile
目标仍然可以运行。仅供参考:由于构建系统的结构,prebuild
始终运行,因为构建系统用于可动态重新定义prebuild
的各种应用程序。
编辑#2: 这是一个简化的示例,似乎可以说明我的问题:
在运行之前,创建一个新目录并touch a b
.PHONY: prebuild main all
all: main
prebuild: a Makefile
@echo prebuild ran
main: prebuild
@echo main ran
我跑步时得到以下输出:
prebuild ran
main ran
这是无论我运行make多少次都会发生的事情,即使前提条件a或Makefile不变。我希望发生的事情是prebuild无法运行(因为a和Makefile不会更改),并且main也不会运行,因为prebuild无法运行。显然,我误会了。