2009-10-23 1 views
23

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

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

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

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

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

+0

«не выполнить, если ничего не строить» сейчас не очень важно, но будет хорошо. Вопрос изменен. – zxcat

+0

Что вы в конечном итоге пытаетесь сделать? Что делает myscript.bat? Вы действительно просто пытаетесь вычислить некоторые дополнительные флаги компилятора, или это надуманный пример? –

+0

Мой скрипт получает ревизию и проверки SVN, изменен ли он от последнего коммита. Он помещает эту информацию в другой скрипт (генерирует файл rev.bat), который просто выводит эту информацию без каких-либо других. Позже в makefile я использую REVISION = $ (shell rev.bat), чтобы получить эту информацию. А затем: AXF_FILE = project_r $ (ПЕРЕСМОТР) _ $ (АРХИТЕКТУРА) .axf – zxcat

ответ

22

Предлагаю два решения. Первые имитирует то, что в среде 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 

Второй является inpired тем, что Eclipse, среда генерирует:

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 

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

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

+5

Предварительная сборка не должна запускаться до main-build во втором примере, поскольку между ними нет зависимости. Следите за этим, если вы делаете параллельный make. –

+0

Скотт Уэльс верен. Я видел дополнительные зависимости, добавленные от pre-build до main-build, и от main-build до post-build, для борьбы с этим. – mlepage

+0

Я думаю, что вы правы ... Не стесняйтесь предлагать/вносить изменения, чтобы улучшить второй пример. – Amro

9

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

CHEAT_ARG := $(shell myscript) 

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

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

+0

Не будет ли это работать, даже если это не нужно? Вопрос требует, чтобы он не исполнялся, если нечего строить. – 2009-10-23 09:24:40

+0

О, хорошо. Ну, по крайней мере, он работает ровно один раз и, таким образом, никогда не переводится ни разу, даже если существуют десятки правил make, расширяющих CFLAGS и AFLAGS. – ndim

+1

ndim, Спасибо! Этот ответ - лучший способ для меня. – zxcat

3

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

Например, если вам это нужно запускать перед соединением foo:

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

Спасибо за ответ. Да, я тоже это пробовал. Но у меня есть несколько правил $ (CC) и $ (AS) (armasm использует разные параметры для разных архитектур - двоичный файл является универсальным и выбирает зависящий от архитектуры код во время выполнения). И не очень хорошая идея добавить «мою команду» во многих местах. Но лучше, чем мой текущий метод – zxcat

+0

Я не могу запустить его перед ссылкой, потому что мне нужны его результаты раньше. И я хочу запустить его один раз, а не при каждой обработке файлов. Перед любым другим прессованием файла. – zxcat

5

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

run-script: 
    myscript 

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

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

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

+0

Это почти то же самое, как предложил авейкау. Скрипт будет выполняться перед каждым файлом (несколько раз). – zxcat

+0

И autoconf приведет к тому же, что и в вашем первом ответе, не так ли? – zxcat

+1

Ум, вы правы (нужно больше кофе). Только в том случае, если вы можете выразить какой-то правильный отпечаток на свой скрипт, вы можете сохранить его при вызове. – ndim

1

Благодарим за ответы. 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 работает, как мне нужно.

+0

Я не думаю, что это гарантирует, что сценарий запуска выполняется до создания файлов obj. – mlepage

 Смежные вопросы

  • Нет связанных вопросов^_^