Это моя проблема: я могу построить двоичный файл одним из двух способов, и у каждого есть проверки, которые могут выполняться на них (под их собственными целевыми целями); Я хотел бы, чтобы цель check
выполнялась в зависимости от того, какая цель подходит, в зависимости от того, какая цель сборки была запущена при предыдущем вызове make
: может ли это быть сделано внутренне, не касаясь файлов или какого-либо другого «внешнего» способа записи, цель которой была создана?Makefile: can (GNU) внутренне сообщают, нужно ли обновлять цель?
Иллюстрацией может помочь:
.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
вызова знать, какая цель была запущена прежде чем определить, нуждается ли он в обновлении или нет. Id est, если 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
обеспокоен , так что некоторые правила, которые один из! Но это простой и сжатый способ решения проблемы для целей, названных в честь файла, который они создали, поэтому я упомянул его для справки.)
Ну, это намного лучше, чем shell-скрипты в целевом рецепте! Интересно, что замена '$ (BIN) -kind' на' $ (MAKE) -q all' в '$ (wildcard ...)' также делает то же самое (для чего мне это нужно) и не полагается о существовании внешнего файла. По внешнему виду (в моей системе) '$ (wildcard $ (MAKE) -q all)' оценивает '' все '' if '$ (MAKE) -q all' возвращает ноль и вычисляет пустую строку, иначе , Но я не могу найти документацию по этому поведению в руководстве GNU make: не определено? – Zorawar
'$ (wildcard $ (MAKE) -q all)' оценивает те, если они есть, «make», «-q» и «all», которые являются файлами в текущем каталоге. Если это дает вам правильное поведение, это чертовски совпадение :-) – slowdog
Да, я не рассчитывал на то, что это действительно полезно! Я забыл точно, какую цель я указал в Makefile, который у меня был, но я думаю, что это, должно быть, было не фальшивым ... – Zorawar