Подтвердить что ты не робот

Шаг предварительной сборки в make файле

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

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

У меня есть это обходное решение:

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

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

4b9b3361

Ответ 1

Я предлагаю два решения. Первый имитирует создание среды 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 [email protected] $(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 [email protected] $(OBJS)
    @$(MAKE) --no-print-directory post-build

clean:
    rm -f $(OBJS) target

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

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

Ответ 2

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

CHEAT_ARG := $(shell myscript)

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

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

Ответ 3

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

run-script:
    myscript

.o.c: run-script
     $(CC) $(CFLAGS) -o [email protected] $<

.o.S: run-script
     $(AS) $(AFLAGS) -o [email protected] $<

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

Ответ 4

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

Пример, если вам нужно, чтобы он запускался до компоновки foo:

foo: ${OBJS}
    my-command-goes-here
    ${CC} -o [email protected] ${OBJS} ${LIBS}

Ответ 5

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

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

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

all: run-script $(AXF_FILE)

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


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