Gnumake и шаблон правил - PullRequest
       7

Gnumake и шаблон правил

4 голосов
/ 16 февраля 2012

Я использую GNUmake для генерации версии для развертывания некоторого веб-контента из исходного каталога. Я хочу быть правилами, которые будут запускать некоторые файлы с помощью инструментов сжатия (например, компрессора YUI), а затем для всего, что не имеет правила, просто скопируйте его.

Так, например:

# Rule with all the $(WWW_OUT_DIR)/*.* files as a prerequisite
all: $(WWW_OUT_FILES)

# Generic rule to perform compression on Javascript files.
$(WWW_OUT_DIR)/%.js:     $(WWW_SRC_DIR)/%.js
    $(YUI_COMP) $(YUI_COMP_OPTS) $< > $@

# Generic rule to perform compression on CSS files.
$(WWW_OUT_DIR)/%.css:    $(WWW_SRC_DIR)/%.css
    $(YUI_COMP) $(YUI_COMP_OPTS) $< > $@

# TDB Rule to magically handle everything else? (This doesn't work)
$(WWW_OUT_DIR)/%.%:   $(WWW_SRC_DIR)/%.%
    cp $< $@

Как мне выполнить то, что пытается сделать последнее правило? То есть Для всего в $ (WWW_OUT_FILES) это не .js или .css, просто скопируйте его? Если возможно, я хочу сохранить зависимость от соответствующего входного файла.

1 Ответ

7 голосов
/ 16 февраля 2012

Вы почти правы, единственное, что нужно исправить - это последнее правило шаблона, просто удалите лишний символ процента:

$(WWW_OUT_DIR)/%:   $(WWW_SRC_DIR)/%
    cp $< $@

Также имейте в виду, что с GNU Make 3.82 алгоритм поиска шаблона был измененнемного (из журнала изменений):

Переменные, характерные для шаблона, и правила шаблона теперь применяются в порядке наименьшего стебля, а не в порядке определения (все еще применяются переменные и правила с одинаковой длиной стебля).в порядке определения).Это приводит к обычно желаемому поведению, когда предпочтительны более конкретные шаблоны.

Это именно то, что вам нужно в случае, если вы используете самую последнюю версию Make.Чтобы ваш Makefile был совместим с другими версиями GNU Make (включая версии более ранние, чем 3.82), правило должно быть определено после других (как в исходном вопросе).

UPD.

Хороший пример из здесь :

До версии 3.82, когда gmake находит несколько совпадений во время поиска шаблона, он предпочитает шаблоны, объявленные ранее в make-файле, шаблонам, объявленным позже.Начиная с 3.82, gmake вместо этого предпочитает шаблон, который приводит к самому короткому стеблю.Это звучит немного запутанно благодаря жаргону, но я думаю, что это на самом деле заставит gmake лучше придерживаться принципа наименьшего удивления.Вот пример:

all: sub/foo.x

%.x:
    @echo "Prefer first match (stem is $*)."

sub/%.x:
    @echo "Prefer most specific match (stem is $*)."

Сравните вывод из gmake 3.81 и 3.82:

  • gmake 3.81

    Prefer first match (stem is sub/foo).
    
  • gmake 3.82

    Prefer most specific match (stem is foo).
    

gmake 3.82 предпочитает второй шаблон, потому что это более конкретное совпадение, чем первый.Обратите внимание, что это значительная обратная несовместимость по сравнению с предыдущими версиями gmake!

...