Makefile для БОЛЬШОГО количества файлов

Я никогда раньше не писал Makefiles, но подозреваю, что это будет полезно в моей ситуации. У меня есть набор текстовых файлов, которые мне нужно предварительно обработать, чтобы извлечь функции для машинного обучения. Структура каталогов может быть такой:

/
+---Makefile
+---/corpus
|   +-- a.txt
|   +-- b.txt
|   +-- ...
|
+---/wordcounts
|   +-- a.wordcount
|   +-- b.wordcount
|   +-- ...
|
+---/lettercounts
|   +-- a.lettercount
|   +-- b.lettercount
|   +-- ...
|
...

Файлы в /wordcounts а также /lettercounts генерируются из файлов в /corpus, Только для файла a.txt, Я могу написать make зависимости как это:

all: wordcounts/a.wordcount lettercounts/a.lettercount

wordcounts/a.wordcount: corpus/a.txt
    cat corpus/a.txt | wc -w > wordcounts/a.wordcount

lettercounts/a.lettercount: corpus/a.txt
    cat corpus/a.txt | wc -m > lettercounts/a.lettercount

Тем не менее, с тысячами файлов в \corpus этот Makefile станет чрезвычайно длинным. Я хочу написать Makefile, который будет адаптироваться к любым файлам в \corpus, Идея в том, что независимо от того, сколько файлов я положил /corpus, Makefile автоматически создаст все остальные файлы. Как я могу это сделать? Это что automake для?

Фон В настоящее время я использую несколько скриптов для генерации больших csv файлы, и запуск всех сценариев для всего корпуса занимает пару часов. Мне нужно реструктурировать так, чтобы изменения в одном файле не требовали повторной обработки всего корпуса. Я приветствую любые предложения о том, как настроить проект более эффективно, если то, что я предлагаю, не является идеальным.

1 ответ

Решение

Вот один из способов сделать это

corpora      := $(wildcard corpus/*.txt)
wordcounts   := $(corpora:corpus/%.txt=wordcounts/%.wordcount)
lettercounts := $(corpora:corpus/%.txt=lettercounts/%.lettercount)

.PHONY: all
all: $(wordcounts) $(lettercounts)

$(wordcounts): wcflags += -w
$(wordcounts): wordcounts/%.wordcount: corpus/%.txt

$(lettercounts): wcflags += -m
$(lettercounts): lettercounts/%.lettercount: corpus/%.txt

$(wordcounts) $(lettercounts):
    cat $< | wc $(wcflags) > $@

Бежать make с -r флаг, чтобы отключить встроенные правила для максимальной производительности.

Другие вопросы по тегам