我正在尝试使用makefile在一个小项目中管理我的构建过程,其中目标数量和目标名称事先是未知的,但取决于输入。具体来说,我想根据.csv
文件生成一堆数据文件(比如cities_list.txt
个文件),里面有城市名称列表。例如,如果txt文件的内容是:
纽约 华盛顿 多伦多
然后,名为write_data.py
的脚本会生成三个名为newyork.csv
,washington.csv
和toronto.csv
的文件。当cities_list.txt
文件的内容发生变化时,我希望make能够巧妙地处理这一变化,即只更新新添加的城市文件。
我试图在目标名称中定义变量名称以实现这一目标,但没有成功。我现在正在尝试创建一堆中间.name
文件,如下所示:
all: *.csv
%.name: cities_list.txt
/bin/bash gen_city_files.sh $<
%.csv: %.name write_data.py
python3 write_data.py $<
clean:
rm *.name *.csv
这似乎非常接近成功,但它只给了我一个.csv文件。原因很明显,因为make无法确定应为all
目标生成哪些文件。如何知道此*.csv
应包含存在相应*.name
文件的所有文件?或者有没有更好的方法来实现我想在这里做的事情?
答案 0 :(得分:1)
好的,这个应该这样做。我们喜欢文件头部的变量赋值:
CITY_FILES := newyork.csv washington.csv toronto.csv
有两种方法可以做到这一点。这样:
-include cities.mak
# this rule can come later in the makefile, near the bottom
cities.mak: cities_list.txt
@sed 's/^/CITIES := /' $< > $@
这样:
CITIES := $(shell cat cities_list.txt)
在我们完成其中一个之后,我们可以构建所需文件的列表:
CITY_FILES := $(addsuffix .csv, $(CITIES))
并构建它们:
# It is convenient to have this be the first rule in the makefile.
all: $(CITY_FILES)
%.csv: write_data.py
python3 $< $*.name