Заставить Makefile выполнить скрипт перед созданием целей - PullRequest
18 голосов
/ 23 января 2010

Я использую Makefiles.

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

Спасибо!

Ответы [ 4 ]

22 голосов
/ 23 января 2010

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

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

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

ZSH_RESULT:=$(shell zsh myscript.zsh)

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

9 голосов
/ 23 января 2010

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

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

zsh: 
   rule for running zsh script.

или, наоборот, сделайте свою первую цель зависимой от нее

goal: zsh foo.exe
2 голосов
/ 12 января 2017

Решение для предварительной и последующей обработки в 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..."
0 голосов
/ 10 октября 2018

Существует решение без изменения существующего Makefile (основное отличие от принятого ответа). Просто создайте makefile, содержащий:

.PHONY: all

all:
    pre-script
    @$(MAKE) -f Makefile --no-print-directory $(MAKECMDGOALS) MAKE='$(MAKE) -f Makefile'
    post-script

$(MAKECMDGOALS): all ;

Единственный недостаток заключается в том, что пре- и постскрипты будут выполняться всегда, даже если больше нечего делать. Но они не будут запущены, если вы вызовете make с одним из параметров --dry-run (другое отличие с принятым ответом).

...