2010-01-23 3 views

ответ

19

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

Вы можете либо сделать, как @John предлагает; размещение zsh-скрипта в качестве первой зависимости. Затем вы должны пометить цель zsh как .PHONY, если она фактически не генерирует файл с именем zsh.

Другое решения (в GNU сделать, по крайней мере), чтобы вызвать функцию $(shell ...) как часть присваивания переменного:

ZSH_RESULT:=$(shell zsh myscript.zsh) 

Это будет выполнять сценарий, как только Makefile анализируются, и перед Выполняются любые целей. Он также выполнит скрипт, если вы вызовете make-файл рекурсивно.

+2

Обратите внимание, что '$ (shell ...)' работает даже тогда, когда make задан как опция -n, --just-print, --dry-run, --recon. – thejoshwolfe

+0

Хороший ответ. Есть ли способ запустить команду при выходе из make? Написал вопрос здесь: http://stackoverflow.com/questions/20582006/force-makefile-to-execute-script-after-building-any-target-just-before-exiting – PonyEars

9

Просто убедитесь, что зависимости одной из других целей

foo.obj : zsh foo.c 
    rule for compileing foo.c 

zsh: 
    rule for running zsh script. 

или в качестве альтернативы, сделать свой первый целевой зависят от него

goal: zsh foo.exe 
+2

Проблема с первым решением заключается в том, что он будет каждый раз перестраивать 'foo.obj', даже если' foo.c' не был обновлен. Проблема со вторым заключается в том, что теперь вы не можете вызвать ваш файл с несколькими целями. –

2

Решение как для предварительной обработки, так и для постобработки в make-файлах с использованием MAKECMDGOALS и двойных правил двоеточия.

MAKECMDGOALS - это цели, перечисленные в командной строке.

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

ifneq ($(MAKECMDGOALS),) 
FIRST_GOAL := $(word 1, $(MAKECMDGOALS)) 
LAST_GOAL := $(word $(words $(MAKECMDGOALS)), $(MAKECMDGOALS)) 
else 
FIRST_GOAL := all 
LAST_GOAL := all 
endif 

Двойные правила двоеточия допускают несколько рецептов для одной и той же цели, выполненной по порядку. Вам придется изменить все цели командной строки на двойные правила двоеточия.

#Dummy rule to set the default 
.PHONY: all 
all :: 

#Preprocessing 
$(FIRST_GOAL) :: 
    echo "Starting make..." 

all :: normal_prerequistes 
    normal_recipe 

other_stuff 

#Postprocessing 
$(LAST_GOAL) :: 
    echo "All done..." 
Смежные вопросы