大多数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).c构建$(TARGET).c,如果$(TARGET).o比$(TARGET).c新,则不执行任何工作。在不更改源文件的情况下多次运行make时会发生这种情况。
但是,构建上面的all目标似乎总是会重新运行$(CC) $(CFLAGS) -o $(TARGET) $(TARGET).c链接来链接应用程序并创建应用程序二进制文件。即使该二进制文件已经存在,并且不需要重新创建,也会发生这种情况。在一些较大的项目中,这个过程可能需要很长时间(数十秒),这有时是不可取的。
编辑#1:这个问题必须对一个额外的假目标做一些事情,在构建对象文件之前,我确实想运行它一次。在我的例子中,我正在运行一个脚本,它接受Makefile变量,并可能更新C文件中包含的头文件。但是,如果Makefile不改变,则不会运行预构建目标。但是,即使$(TARGET)不做任何事情(例如,因为Makefile没有被更改),也仍然运行着Makefile目标。FYI:由于构建系统的结构,我总是运行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 nor Makefile没有改变。我希望发生的是预构建不运行(因为a和Makefile不改变),main也不运行,因为预构建没有运行。很明显,我有些误会。
发布于 2021-10-08 19:29:56
问题是额外的依赖触发了您的重建。试试这个:
.PHONY: all
OUTPUTDIR=common/
TARGET=finalexe
all: $(OUTPUTDIR)/$(TARGET)
$(OUTPUTDIR)/$(TARGET): $(TARGET).c | $(OUTPUTDIR)
$(CC) $(CFLAGS) -o $@ $(TARGET).c
$(OUTPUTDIR):
mkdir -p $@在上面的示例中,如果A.还不存在,则创建'finalexe‘;如果修改了finalexe.c,则创建B。未检查OUTPUTDIR上的时间戳。
https://stackoverflow.com/questions/53838544
复制相似问题