预先在Makefile

时间:2018-06-06 19:37:07

标签: makefile build

我正在尝试使用makefile在一个小项目中管理我的构建过程,其中目标数量和目标名称事先是未知的,但取决于输入。具体来说,我想根据.csv文件生成一堆数据文件(比如cities_list.txt个文件),里面有城市名称列表。例如,如果txt文件的内容是:

  

纽约   华盛顿   多伦多

然后,名为write_data.py的脚本会生成三个名为newyork.csvwashington.csvtoronto.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文件的所有文件?或者有没有更好的方法来实现我想在这里做的事情?

1 个答案:

答案 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