我有一个数据文件,该文件由脚本处理以产生多个输出文件。这些输出文件中的每一个都将被进一步处理。创建哪些文件取决于输入文件的内容,因此我无法明确列出它们。我不太清楚如何引用Makefile中生成的各种文件。
目前,我有这样的事情:
final.out: *.out2
merge_files final.out $(sort $^)
%.out2: %.out1
convert_files $?
%.out1: data.in
extract_data data.in
此操作失败,显示为No rule to make target '*.out2', needed by 'final.out'
。我认为这是因为.out2文件尚不存在,因此通配符表达式未按我希望的方式替换。我尝试使用通配符功能,但是失败,因为先决条件列表最终为空。
任何指针将不胜感激。
答案 0 :(得分:1)
编辑:修复了第二遍考试中的先决条件列表。
您显然无法在运行extract_data
命令之前计算中间文件列表。在这种情况下,解决方案包括运行make两次。第一次生成*.out1
文件,第二次完成作业。您可以使用一个空的虚拟文件来标记是否
extract_data
命令应再次运行或不运行:
ifeq ($(FIRST_PASS_DONE),)
final.out: .dummy
$(MAKE) FIRST_PASS_DONE=yes
.dummy: data.in
extract_data $<
else
OUT1 := $(wildcard *.out1)
OUT2 := $(patsubst %.out1,%.out2,$(OUT1))
final.out: $(OUT2)
merge_files $@ $(sort $^)
%.out2: %.out1
convert_files $?
endif
答案 1 :(得分:0)
不幸的是,您的问题缺少一些详细信息,我会立即询问一些软件开发人员是否会提供此makefile进行审查:
extract_files
是否提供文件列表?convert_files
是转换一个文件还是多个文件?该示例似乎暗示它可以转换多个。
以下是我会选择的方法。我将使用tar文件作为输入文件的示例,该文件会导致多个输出文件
tar
选项v
在提取文件时打印文件$(DATA_FILES)
的片段
.PHONY: all
all: final.out
# extract files and created sorted list of files in $(DATA_FILES)
Makefile.data_files: data.tar
set -o pipefail; tar xvf $< | sort | sed 's/^/DATA_FILES += /' >$@
DATA_FILES :=
include Makefile.data_files
CONVERTED_FILES := $(DATA_FILES:%.out1=%.out2)
$(CONVERTED_FILES): %.out2: %.out1
convert_files $< >$@
final.out: $(CONVERTED_FILES)
merge_files final.out $^
更新,如果extract_data
没有提供文件列表,您可以像这样修改我的示例。但是,当然这取决于您的目录中没有其他与*.out1
匹配的文件。
# extract files and created sorted list of files in $(DATA_FILES)
Makefile.data_files: data.in
set -o pipefail; \
extract_data $< && \
(ls *.out1 | sort | sed 's/^/DATA_FILES += /') >$@