【发布时间】:2021-02-05 22:43:28
【问题描述】:
我有一个 makefile,由于各种原因,它每次都依赖于一个支持的 python 脚本来运行,并从几个外部位置获取文件,复制到工作目录,并在编译之前通过单独的预处理器运行。
这个makefile必须能够并行运行(-j8)所以不能保证处理的顺序。
在尝试明确指定先决条件时,我创建了一种情况,其中 make 会跳过所有目标文件,直接进行链接,并且由于必要的对象不存在而失败。在第二次运行时,所有对象都已经存在(预处理步骤跳过了已经存在的文件)并且所有文件都被正确编译和链接。
在没有 -j# 的情况下运行时一切正常,但在我添加 -j2 的那一刻,跳过开始。
以下是制作文件的示例:
GEN_FILES := file1.cpp file2.cpp file3.cpp
CXX_FILES := bin_main.cpp $(GEN_FILES)
OBJ_FILES := $(patsubst %.cpp,%.o,$(CXX_FILES))
.PHONY : all clean prepare
all : bin_file
prepare :
# Copy and preprocess all source files
[ -f file1.cpp ] || cp d1/file1.cpp .
[ -f file2.cpp ] || cp d2/file2.cpp .
[ -f file3.cpp ] || cp d3/file3.cpp .
$(OBJ_FILES) : prepare
bin_file : $(OBJ_FILES)
[ -f file1.o ] && [ -f file2.o ] && [ -f file3.o ] && touch bin_file
%.o : %.cpp
@echo "Compiling $<..."
[ -f $< ] && touch $@
clean :
$(RM) *.o
$(RM) file*
$(RM) bin_file
我怎样才能一次构建它,首先运行准备收集所有文件,然后根据需要编译和链接?
【问题讨论】:
-
这个解释隐藏了你的makefile的问题。您在此处显示的 makefile 无法按照您所说的方式运行。事实上,它不仅会等待构建目标文件,即使您不更改任何内容,它也会每次都重新构建所有目标文件,因为所有目标文件都依赖于
prepare目标,即.PHONY。即使不是.PHONY,prepare规则也永远不会创建prepare目标,因此它永远不会是最新的。 -
请创建一个最小的完整示例,在运行它时显示问题,然后编辑您的问题以包含该示例。如果您的食谱实际上不运行编译器或运行任何内部命令(如
copy_and_pp_files.py),这是最简单的,因为我们不知道它是做什么的。只需使用cp、touch等来模拟创建和更新的文件。 -
首先,我进行了编辑以删除任何非标准操作。这应该运行并重复问题。其次,简而言之就是这个问题。如何每次都先运行复制操作,然后允许 make 仅正确构建第一次操作中实际需要复制的文件?
-
@Squaven 我刚刚在答案中添加了一条关于您如何应对的注释,以避免总是重新编译您复制的文件...