Makefile: может ли (GNU) сделать внутренний отчет, нуждается ли цель в обновлении? - PullRequest
1 голос
/ 29 декабря 2010

Это моя проблема: я могу создать двоичный файл одним из двух способов, и у каждого есть проверки, которые могут быть выполнены на них (в соответствии с их собственными целями создания); Я бы хотел, чтобы цель check запускалась в зависимости от того, какая цель была выбрана в зависимости от того, какая цель сборки была запущена при предыдущем вызове make: это можно сделать внутренне, не касаясь файлов или каким-либо другим «внешним» способом записи, какая цель сборки был запущен?

Может помочь иллюстрация:

.PHONY: all modified
all: $(obj)
    $(CXX) ... -o $(BIN)

modified: $(obj) $(extra_objs)
    $(CXX) ... -o $(BIN)


.PHONY: check check_all check_modified
check_all: all
    ...

check_modified: modified
    ...

check:
    # ??? Some makefile variable I don't know about?

чтобы я мог спросить об этом из оболочки:

make X       # <-- X = {all, modified}
...          # <-- this is important: this is not a question of target dependency
make check   # <-- have `check' run `check_X' target

Я полагаю, что для конкретного вызова make единственный способ узнать, какая цель выполнялась ранее, - это определить, нужно ли ей обновить или нет. То есть, если all обновлен, тогда запустите check_all, если modified обновлен, тогда запустите check_modified и по умолчанию check_all.

Итак, могу ли я спросить make "внутренне", будет ли обновлена ​​цель X, если бы я ее запустил? «Внутренний» означает отсутствие вызова $(MAKE) -n или touch Y, а затем запрос оболочки if [ -f Y ] ....

Как вы можете видеть, это не совсем вопрос зависимости, потому что это, очевидно, создаст зависимость, когда все, что я хочу сделать, это проверить, была ли она запущена раньше. Итак, есть идеи или (альтернативные предложения)?

UPDATE:

ОК, я думаю, ответ: Нет. Лучшее, что я могу сделать, это:

.PHONY: check
check: $(if $(wildcard $(firstword $(extra_objs))),check_modified,check_all)

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

(Примечание: я столкнулся с проблемой:

.PHONY: check
check:
    $(MAKE) -q modified && $(MAKE) check_modified || $(MAKE) check_all

точно не будет работать для кода, который я имел выше, потому что all и modified являются фальшивыми и поэтому всегда будут нуждаться в обновлении, если речь идет о make, так что такие правила действуют! Но это простой и лаконичный способ решения проблемы для целей, названных по имени файла, который они создают, поэтому я упомяну его для справки.)

Ответы [ 3 ]

1 голос
/ 29 декабря 2010

Может быть, порождает другую марку внутри с помощью флага -q?

Использование: make [options] [target] ...

Параметры:

[...]

-q, --question Прогон № команды; статус выхода говорит, если до дата.

0 голосов
/ 06 января 2011

Чтобы ответить на заголовок вашего вопроса, см. правила двойного двоеточия. Цитирование руководства:

Правила двойного двоеточия несколько неясны и не часто очень полезны; они предоставляют механизм для случаев, в которых метод, используемый для обновления цели, отличается в зависимости от того, какие файлы предварительных требований вызвали обновление, и такие случаи редки.

Звучит (почти) именно то, что вы ищете.

0 голосов
/ 30 декабря 2010

Вы можете записать тип сборки в файл и прочитать его позже, чтобы выбрать правильную «галочку» цели следующим образом:

all: $(obj)
    $(CXX) ... -o $(BIN)
    echo $@ > $(BIN)-kind

modified: $(obj) $(extra_objs)
    $(CXX) ... -o $(BIN)
    echo $@ > $(BIN)-kind

check: $(if $(wildcard $(BIN)-kind),check_$(shell cat $(BIN)-kind))
...