Сделайте: сделайте все, что соответствует правилу - PullRequest
0 голосов
/ 15 августа 2011

Я пытаюсь изучить make-файлы. У меня есть следующий Makefile:

ctx/%.ctx: rst/%.rst
    texlua rst_parser.lua $< $@

pdf: ctx
    mkdir -p pdf
    cd pdf; context ../ctx/main.ctx

ctx: rst
    mkdir -p ctx

.PHONY: clean
clean:
    rm -f pdf/*.log pdf/*.aux pdf/*.pgf pdf/*.top pdf/*.tuc

Как видите, все три предварительных условия являются каталогами; rst, ctx и pdf. Предпосылки повторяются до «первого». Я буду редактировать файлы в ctx вручную и файлы в rst, которые преобразуются в файлы в ctx.

Что мне нужно сделать, чтобы make сделать pdf :) следующим образом:

  1. Посмотрите, изменилось ли что-то в ctx и / или что-то в rst.
  2. Если изменилось только что-то в ctx, сделайте pdf, иначе сделайте ctx.
  3. Если что-то в rst изменилось, используйте первое правило, чтобы создать соответствующий файл в ctx, затем ctx, а затем pdf.

Моя проблема теперь в том, что я не знаю, как сказать make «Чтобы сделать ctx при изменении файлов в rst, используйте первое правило (ctx/%.ctx: ctx/%.rst), чтобы сделать каждый соответствующий файл в ctx от соответствующего в rst

1 Ответ

1 голос
/ 15 августа 2011

Ваш вопрос немного неясен (например, вы путаете каталог pdf/ с целью makefile pdf), но это должно сделать то, что, я думаю, вы хотите:

TARGETS := $(wildcard rst/*.rst)
TARGETS := $(patsubst rst/%.rst,%,$(TARGETS))

ctx/%.ctx: rst/%.rst    # I assume you didn't mean ctx/%.rst
  texlua rst_parser.lua $< $@

pdf: ctx
  mkdir -p pdf
  cd pdf; context ../ctx/main.ctx

.PHONY:cxt
ctx: $(patsubst %,ctx/%.ctx, $(TARGETS))
  mkdir -p ctx

И причина, по которой make строит pdf, заключается в том, что когда вы вызываете Make без цели, она выбирает цель по умолчанию, которая является первой целью (если вы не выполняете некоторые операции), которая в данном случае равна pdf. (Правило шаблона не считается.)

EDIT:
Теперь, когда я думаю об этом, то, что я написал выше, выглядит неуклюже, и оно всегда будет запускать правило pdf, даже если ничего не изменилось. Это несколько лучше:

# You're right, this is better.        
CTX_TARGETS := $(patsubst rst/%.rst,ctx/%.ctx, $(wildcard rst/*.rst))

pdf: $(CTX_TARGETS)
  mkdir -p pdf
  cd pdf; context ../ctx/main.ctx

$(CTX_TARGETS): ctx/%.ctx: rst/%.rst ctx
  texlua rst_parser.lua $< $@    

ctx:
  mkdir -p ctx

Я сделал ctx PHONY, потому что боролся со случаем, когда каталог существует, но правило все еще должно быть запущено. Это оказалось ненужным (как можно догадаться из того факта, что я не уловил опечатку).

И да, предварительными условиями являются имена файлов или каталогов (или PHONY целей). Я хотел сказать, что такие фразы, как «make pdf», немного сбивают с толку, если pdf - это и каталог, и правило, которое его создает (и выполняет другие действия).

Проблема использования каталогов в качестве целей заключается в том, что они не подчиняются интуитивно понятным правилам времени изменения: если вы изменяете файл в каталоге, время модификации каталога не изменяется. Также сложно сознательно изменить время мода, так как touch не делает этого (не спрашивайте меня, почему допустимо touch каталог, если он ничего не делает). Это можно сделать, например, добавляя и удаляя фиктивный файл, но это уродливо.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...