Шаг предварительной сборки в 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?
Ответы
Ответ 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 работает, как мне нужно.