2009-09-24 5 views
1

У меня есть Makefile со следующим типом правила:GNU Make и шаблоны - отсутствующие файлы

%.html: 
    ./generate-images.py > [email protected] 
    make $(patsubst %.png,%.gif,$(wildcard *.png)) 

generate-images скрипт записывает не только файл HTML (стандартный вывод), но несколько .png файлов в текущей директории , Цель здесь состоит в том, чтобы преобразовать их в .gif. (не совсем, но это пример)

Это работает, если я вызываю его непосредственно. Проблема в том, что: если я вызываю его из другого правила, где foo.html является зависимостью, заявление подстановки не может найти файлы. Другими словами, он просто называется make без аргументов, что я не хочу здесь.

В чем дело с шаблоном? Или, есть ли лучший способ сделать это?

ответ

1

Похоже, что он оценивает все выражения $(), поскольку он обрабатывает Makefile, а не выполняет каждое правило. Вы можете добавить правило к вашему Makefile так:

images: $(patsubst %.png,%.gif,$(wildcard *.png)) 
.PHONY: images 

, а затем изменить ваш пример фрагмента кода для

%.html: 
    ./generate-images.py > [email protected] 
    make images 

так, что сделает оценку Glob в нужное время. Это то, о чем можно было бы проверить руководство.

3

Хотя ваша проблема может быть чем-то другим, я отчетливо вижу ее.

Весь текст все команды обрабатываются одновременно, поэтому функции и переменные make расширяются. Предположим, что у вас нет .png файлов в каталоге, и вы вызываете make, чтобы он их регенерировал: a.png и b.png. Затем, после того, как вы вызываете сделать, текст правила будет эффективно выглядеть следующим образом:

file.html: 
    ./generate-images.py > file.html 
    make 

потому в момент чтения Makefile не было .png файлов! После того, как первая строка будет выполнена, будут отображаться файлы, но следующая строка уже была создана, чтобы быть просто «make».

И только тогда, когда вы вызываете свой Makefile во второй раз, он будет расширяться

file.html: 
    ./generate-images.py > file.html 
    make a.gif b.gif 

Это не то, что вы хотите. Поэтому я предлагаю сделать это правильно.

# If you have batch conversion program, this may be helpful 
images.stamp: *.png 
    convert_all_images $? 
    touch images.stamp 

# OR, if you want convert one-by-one with means of make 
images.stamp: $(wildcard *.png) 
    touch images.stamp 

%.gif: %.png 
    convert_one --from=$^ [email protected] 

# HTML would look like 
%.html: 
    ./generate-images.py > [email protected] 
    make images.stamp 

Итак, когда вы вызываете make all, он генерирует HTMLs и преобразует вновь генерироваться изображения. Обратите внимание, что конвертирует только те изображения, которые обновляются, что и нужно.


Благодаря Beta за указание бардак с расширениями GIF/PNG.

+0

Это то, к чему мой пост был. – Novelocrat

+0

+1 для четкого объяснения проблемы с подстановочными знаками, -1 для чрезмерно сложных и ошибочных правил (даже после редактирования) и +1 для неожиданного нового понимания: вы действительно не можете сделать это без рекурсии! – Beta

+0

@Beta: Мне бы очень хотелось узнать, какие ошибки остались в моих правилах! Пожалуйста, брось подсказку - я отредактирую свой ответ и даю вам правильную атрибуцию. BTW, на самом деле, вы * можете * сделать это без рекурсии :-) Вот почему я удалил это заявление со своего поста :-) Но этот woul сделает мой пост еще более сложным ... –

Смежные вопросы