繁体   English   中英

Makefile创建子目录并通过ID列表文件下载一些文件

[英]Makefile to create subdirectories and download some files by a file of ID list

描述

我正在编写GNU make Makefile以从服务器下载一些文件(L1.txt,L2.txt等)。 我有一个目标,使他们每个或全部。

每个文件都包含ID列表。

对于每个列表文件(L1.txt,L2.txt等),我想创建一个与列表文件同名的子目录(例如,L1.txt-> ./L1 ..)-简单:)。

然后,对于每个列表文件,对于列表文件中的每个ID,我想将其他文件下载到特定目录(由列表文件创建的目录)中,并对其进行处理以制作一些二进制文件。 每个子目录中的所有二进制文件都应聚合到其他.merged.bin-complex:/

L1.txt:

10, 20, 30

L2.txt:

101, 102, 105

因此,make之后,我希望拥有:

./L1.merged.bin
./L2.merged.bin
./conf/L1.txt
./conf/L2.txt

./data/L1/10.txt
./data/L1/20.txt
./data/L1/30.txt
./data/L1/10.bin
./data/L1/20.bin
./data/L1/30.bin

./data/L2/101.txt
./data/L2/102.txt
./data/L2/105.txt
./data/L2/101.bin
./data/L2/102.bin
./data/L2/105.bin

样例代码

LIST_FILES=$(wildcard conf/*.txt)
LIST_FOLDERS=$(patsubst conf/%.txt, data/%, ${LIST_FILES})
MERGED_FILES=$(patsubst conf/%.txt, %.merged.bin, ${LIST_FILES})

all: mergesubs


mergesubs: ${MERGED_FILES} 

conf/%: 
    curl -sSL some-list-url/$*.txt > $@

data/%: conf/%.txt
    test -d $@ || mkdir $@

# PSEUDO CODE STARTS HERE:
# template code to understand inner-workings.
# should not work as target should be made for each data sub directory.
data/*/%.bin: data/*/%.txt
     my_process $< > $@

data/*/%.txt:
    curl -sSL someurl/$* > $@

# PROBLEMS START HERE!
# prerequisite should be a list of files, 
# with file extension .bin and generated from list file 
# provided before. conf/L1.txt might be not downloaded
# so I need to add it to prerequisites, 
# but make does not provide ordering for prerequisites
# Something similar
%.merged.bin: $(shell cat conf/%.txt) conf/%
    cat $^ > $@

如何为这种情况编写依赖关系树? 我想保留所有gnu make的优良品质:仅下载一次文件,仅处理一次,依此类推。

聚苯乙烯

请不要建议使用GNU Make以外的其他工具,因为我需要在Linux环境中使用Makefile进行此操作。

在阅读我的代码之前,请注意以下几点:

不要使用$(wildcard) -到处都是个坏主意。 列出您期望的项目,就像我在LIST_FILE_STEMS所做的一样

追加/. 告诉这个目录是一个好方法(仅添加/不够-将其剥离)。 但是,我对%/.进行规则的方式%/. 在此,仅对存在父目录时创建的目录可靠地起作用。 这是因为mkdir -p与父目录存在较弱的竞争条件。 在您的情况下,您仅创建一个一级目录,所以可以。

下载远程文件时,没有必要依赖于远程文件,因为如果不先下载,就无法确定其时间戳。 因此,在这种情况下,进行此操作的一种好方法是仅在本地副本不存在的情况下下载。 如果要强制重新下载,则必须先删除本地副本。

任何不重要的配方都应取决于Makefile因此,如果配方更改,则目标将重新生成。

我在这里使用了一些微妙的技巧,如果您没有经验,那么在阅读代码时,这些技巧不会立即显而易见。 但是,当您尝试更改代码时,它可能会“停止工作”,因为您没有意识到正在发生的事情。 那将是您学习的机会-GNU Make手册是您的朋友:)所以这就是为什么我没有特别注释代码的原因。

记住,在尝试我的代码之前,请记住在食谱中用开头的制表符替换空格-据我所知,无法在Stack Overflow中的代码中粘贴制表符-它会将制表符更改为空格。

干得好:

LIST_FILE_STEMS := \
    L1 \
    L2 \

LIST_FILES := $(patsubst %, conf/%.txt, $(LIST_FILE_STEMS))

MERGED_FILES := $(patsubst conf/%.txt, %.merged.bin, $(LIST_FILES))

GENERATED_MAKEFILES := $(addsuffix _Makefile, $(LIST_FILE_STEMS))

all: $(MERGED_FILES)

-include $(GENERATED_MAKEFILES)

$(GENERATED_MAKEFILES): %_Makefile: conf/%.txt Makefile
    echo $*.merged.bin: $(patsubst %, data/$*/%.bin, $(shell sed 's/,//g' < $<)) > $@

%.merged.bin:
    cat $^ > $@

$(LIST_FILES): Makefile
    curl -sSL $(subst conf,some-list-url,$@) > $@

%/.:
    mkdir -p $@

.SECONDEXPANSION:

%.bin: %.txt Makefile | $$(dir $$@).
    my_process $< > $@

data/%.txt: Makefile | $$(dir $$@).
    curl -sSL someurl/$(notdir $*).txt > $@

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM