2015-11-25 14 views
1

Пример: допустим, у меня есть bar.c и baz.c, я хочу произвести foo.a. Итак:

foo.a: bar.o baz.o 
    ar -rc [email protected] $? 

Теперь я решаю всегда хочу bar.o быть обновлен. Я решил сделать его финишной целью. Это также требует явного рецепта для него, так как неявные правила не ищут финских целей. Итак:

.PHONY: bar.o 
bar.o: bar.c 
    cc -c -o [email protected] $< 

foo.a: bar.o baz.o 
    ar -rc [email protected] $? 

Теперь, когда я бегу make foo.a, bar.c всегда компилируется. С момента обновления bar.o рецепт foo.a всегда запускается.

Но: $? имеет пустое значение, поэтому foo.a не может быть изменено. Зачем?

+0

Сделать, очевидно, не запрещает это, но в руководстве говорится: «Фальшивая цель не должна быть обязательным условием реального файла цели». Поскольку фальшивые цели всегда выполняются, имеет смысл, что они будут считаться всегда старше, чем что-либо еще внутри. – user657267

+0

@ user657267 Всегда выполняемый будет отображать более новую версию, чем старше, так как рецепт * обычно * обновляет свою цель при ее запуске. Тем не менее, «не следует», потому что цель, которая перечисляет фальшивое предварительное условие, сама будет работать, потому что фальшивая цель будет считаться более новой. –

+0

@ EtanReisner, вы правы, мои времена были смущены. Возможно, у внутренних фальшивых файлов есть специальное значение даты, которое не является ни новым, ни более старым. – user657267

ответ

1

Хороший вопрос. Я не уверен точно, но я подозреваю, что это связано с тем, что фальшивые цели - это то, что «фальшивые» как-будто они явно ожидаются не для представления файлов, и поэтому наличие их в списке предварительных условий, более новых, чем цель, на самом деле все это имеет смысл.

Это сказал, что если вы хотите сохранить это поведение, но обрабатывать вещи правильно, вы хотите избегать.PHONY цели и вместо этого использовать forced target.

Если правило не имеет каких-либо предварительных условий или рецептов, а цель правила является несуществующим файлом, то заставьте воображать, что эта цель обновлена ​​всякий раз, когда выполняется ее правило. Это означает, что все цели, в зависимости от этого, всегда будут иметь свой рецепт.

Пример иллюстрирует это:

clean: FORCE 
    rm $(objects) 
FORCE: 

Здесь цель «FORCE» удовлетворяет специальным условиям, поэтому цель чистой, что зависит от него принудительно запустить свой рецепт. Нет ничего особенного в названии «FORCE», но это одно имя, обычно используемое таким образом.

Как вы можете видеть, использование «FORCE» таким образом имеет те же результаты, что и при использовании «.PHONY: clean».

Использование «.PHONY» более явное и более эффективное. Однако другие версии make не поддерживают «.PHONY»; таким образом, «FORCE» появляется во многих make-файлах. См. «Призрачные цели».

+0

ОК, спасибо. Стоит отметить, что Фоны цели * * появляются в '$ ^', что кажется мне непоследовательным. – Brendan

+1

Да и нет. Они * являются * предпосылками, но они не (на самом деле) новее, чем цель.Так что это имеет смысл, но я согласен, что это немного странно. –