Шаг перед сборкой в ​​make-файле - PullRequest
28 голосов
/ 23 октября 2009

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

Я искал SO и Google, но ничего не могу найти.

У меня есть этот обходной путь:

# myscript.bat output is empty
CHEAT_ARGUMENT = (shell myscript.bat)
CFLAGS += -DCHEAT_ARGUMENT=$(CHEAT_ARGUMENT)
AFLAGS += -DCHEAT_ARGUMENT=$(CHEAT_ARGUMENT)

Но это очень уродливо. Есть ли другой способ запустить " шаг предварительной сборки " в makefile ?

Ответы [ 5 ]

26 голосов
/ 26 октября 2009

Я предлагаю два решения. Первое имитирует то, что генерирует среда IDE NetBeans:

CC=gcc

.PHONY: all clean

all: post-build

pre-build:
    @echo PRE

post-build: main-build
    @echo POST

main-build: pre-build
    @$(MAKE) --no-print-directory target

target: $(OBJS)
    $(CC) -o $@ $(OBJS)

clean:
    rm -f $(OBJS) target

Второй основан на том, что генерирует Eclipse IDE:

CC=gcc

.PHONY: all clean
.SECONDARY: main-build

all: pre-build main-build

pre-build:
    @echo PRE

post-build:
    @echo POST

main-build: target

target: $(OBJS)
    $(CC) -o $@ $(OBJS)
    @$(MAKE) --no-print-directory post-build

clean:
    rm -f $(OBJS) target

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

Во втором шаг после пост-сборки не выполняется, если состояние основной сборки обновлено. В то время как этап предварительной сборки всегда выполняется в обоих случаях.

11 голосов
/ 23 октября 2009

В зависимости от вашей версии make, что-то вроде следующего должно, по крайней мере, избегать выполнения десятков раз, если CFLAGS и AFLAGS оцениваются десятки раз:

CHEAT_ARG := $(shell myscript)

Обратите внимание на двоеточие.

Это выполняется ровно один раз. Никогда не более одного раза, но также никогда не реже, чем один раз. Выберите свой собственный компромисс.

5 голосов
/ 23 октября 2009

Вы можете добавить специальную цель в ваш Makefile, и все ваши правила сборки зависят от этого:

run-script:
    myscript

.o.c: run-script
     $(CC) $(CFLAGS) -o $@ $<

.o.S: run-script
     $(AS) $(AFLAGS) -o $@ $<

В зависимости от того, что на самом деле делает ваш скрипт, запуск его один раз на этапе перед Makefile (этап конфигурирования в терминах autoconf) может иметь еще больший смысл (и меньше работать).

3 голосов
/ 23 октября 2009

То, что вы предлагаете, выглядит немного "не по-настоящему". Почему бы просто не запустить команду в какой-либо цели make-файла, в которой она должна быть раньше?

Пример, если вам нужно запустить его перед установкой ссылки foo:

foo: ${OBJS}
    my-command-goes-here
    ${CC} -o $@ ${OBJS} ${LIBS}
1 голос
/ 25 октября 2009

Спасибо за ответы. ndim мне очень помогли, asveikau . Последний файл представляет собой один исполняемый файл двоичного кода, поэтому теперь я могу использовать что-то вроде этого:

run-script:
    myscript
$(AXF_FILE): run-script $(OBJ_DIRS) $(OBJ_FILES)
    $(LINK) #......

Он будет запускать myscript один раз. Значение {AXF_FILE} зависит от myscript, и я должен запустить его до . И в этом случае myscript запускается всегда, а не только тогда, когда требуется перестроение. После того, как Простейший ответ пришел мне в голову:

all: run-script $(AXF_FILE)

То есть все ;) (Конечно, вместо «все» может использоваться любая цель)


Редактировать: этот метод выполняет скрипт после вычисления $ (AXF_FILE) . Таким образом, возможно получить неправильное значение AXF_FILE. Теперь только первый ответ ndim работает так, как мне нужно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...