Как генерировать цели make-файла из переменных? - PullRequest
1 голос
/ 22 ноября 2011

В настоящее время у меня есть make-файл для обработки некоторых данных. Makefile получает входные данные для обработки данных, используя файл CONFIG, который определяет входные данные в переменной. В настоящее время я символически связываю входные файлы с локальным каталогом, то есть make-файл содержит:

tmp/%.txt: tmp
    ln -fs $(shell echo $(INPUTS) | tr ' ' '\n' | grep $(patsubst tmp/%,%,$@)) $@

Это не очень элегантно, но, похоже, работает. Есть ли способ лучше? В основном, учитывая

ВХОДЫ = /foo/bar.txt /zot/snarf.txt

Вышеприведенное связывает все входные файлы в tmp /, так что я могу обрабатывать их с правилами вроде

%.out: tmp/%.txt
    some command

А также цели для объединения результатов в зависимости от всех файлов $ (INPUT).

Кроме того, кроме kludgosity, make-файл не работает корректно с -j, что крайне важно для завершения анализа в разумные сроки. Я думаю, что это ошибка в GNU make, но любые подсказки приветствуются.

Ответы [ 3 ]

0 голосов
/ 22 ноября 2011

Несколько вещей здесь:

  • make позаботится о списке входов.Там нет необходимости использовать tr и тому подобное.Вы можете делать все, что вы хотите с make функциями, такими как patsubst.
  • make хорошо работает с -j.Если это не работает так, как вы ожидали, то это означает, что вы не выразили весь свой разум в правилах и зависимостях.
  • Вы писали о слиянии своих результатов.Причина предыдущей пули может быть здесь.Вы должны указать make, что ваша объединенная цель зависит от всех ваших .out целей.Затем make будет ожидать всех целей перед слиянием.
  • Я думаю, нет необходимости создавать символические ссылки на ваши .txt исходные файлы.Я уверен, что вы можете написать шаблонные правила, которые используют входные файлы там, где они есть.Вы должны разрешить выходным файлам находиться в различных подкаталогах.

В результате получится что-то вроде:

OUTPUTS = $(patsubst %.txt, out/%.out, $(INPUTS))

out/%.out: %.txt
    <some command>

merged: $(OUTPUTS)
    <merge command>
0 голосов
/ 22 ноября 2011

Вы можете попробовать использовать vpath, чтобы позволить make найти входные файлы. Затем вы можете просто работать с именами файлов без частей каталога. Нечто подобное должно работать. ($(sort ...) предназначен для удаления дубликатов; не обязательно).

INPUTS  := ...
OUTPUTS := $(patsubst %.txt, %.out, $(notdir $(INPUTS))

vpath %.txt $(sort $(dir $(INPUTS)))

merged.txt: $(OUTPUTS)
    <merge command> $^ -o $@

%.out: %.txt
    <some command> $< -o $@

Это решение основано на отсутствии дублирующих имен файлов, но я думаю, что вы подразумеваете это условие, создавая символические ссылки.

0 голосов
/ 22 ноября 2011

Вы хотите что-то подобное?

TARGET = x
INPUT  = a.txt b.txt
OUTPUT = $(INPUT:%.txt=%.out)

.PHONY: default
default: $(TARGET)

$(TARGET): $(OUTPUT)
    cat $^ > $@

%.out: %.txt
    cp $< $@

Пробовал с опцией -j в make, но для такого простого примера легко разрешить зависимости и построить параллельно.

...