Управление многословием марки - PullRequest
11 голосов
/ 16 февраля 2012

Я использую make-файл для компиляции программы, состоящей из многих .c файлов, и каждый раз, когда make вызывается, он компилирует только те файлы, которые были изменены после последнего запуска (ничего особенного, пока здесь).

Чтобы не загромождать мой экран, я добавляю @ в начале каждого $(CC) вызова, а перед ним печатаю настроенное сообщение echo.Например:

%.o: %.c $(h1) $(h3) %.h
    @echo -e "\tCompiling <" $< 
    @$(CC) $(CFLAGS) -c $< -o $(libDir)$@$(MATHOPTS)

Мой вопрос: как я могу контролировать многословие make более «динамичным» образом, чтобы иметь возможность:

  1. Нормальное поведение : для каждого выполненного правила make-файла печатается только настроенное сообщение.
  2. Подробное поведение : вывод команды, фактически выполняемой каждым правилом make-файла (как если бы @ вообще не использовался).

Ответы [ 5 ]

16 голосов
/ 17 февраля 2012

Я бы сделал это так, как работает automake:

V = 0
ACTUAL_CC := $(CC)
CC_0 = @echo "Compiling $<..."; $(ACTUAL_CC)
CC_1 = $(ACTUAL_CC)
CC = $(CC_$(V))

%.o: %.c $(h1) $(h3) %.h
        $(CC) $(CFLAGS) -c $< -o $(libDir)$@$(MATHOPTS)

Если вам нужно выполнить другие команды в ваших правилах, мне нравится следующий фрагмент. Напишите $(AT) вместо @, и будет тихо, когда V=0, но напечатано, когда V=1.

AT_0 := @
AT_1 := 
AT = $(AT_$(V))
8 голосов
/ 08 марта 2012

Другое решение (которое мне нравится, потому что оно гибкое)

ifeq ("$(BUILD_VERBOSE)","1")
Q :=
vecho = @echo
else
Q := @
vecho = @true
endif

%.o: %.c
    $(vecho) "-> Compiling $@"
    $(Q)$(CC) $(CFLAGS) -c $< -o $@

Вы можете пропустить все, что нужно, но иногда это может пригодиться.

4 голосов
/ 21 сентября 2015

Вместо использования «@gcc» для компиляции вы можете опустить этот «@» и вместо этого передать опцию «-s» в команду make. (Оставьте "@echo" как есть.) Тогда "make -s" будет вашей краткой командой make, а "make" будет многословной.

Флаг "-s" или "--silent", чтобы сделать, предотвращает эхо, как если бы все рецепты начинались с "@".

Из GNU Make страниц справочника

(Другие ответы лучше ответят на ваш вопрос, но этот подход заслуживает упоминания.)

4 голосов
/ 16 февраля 2012

Я бы создал функцию, которая принимает команду для выполнения и решает, следует ли ее повторить.

# 'cmd' takes two arguments:
#   1. The actual command to execute.
#   2. Optional message to print instead of echoing the command
#      if executing without 'V' flag.
ifdef V
cmd = $1
else
cmd = @$(if $(value 2),echo -e "$2";)$1
endif

%.o: %.c $(h1) $(h3) %.h
    $(call cmd, \
        $(CC) $(CFLAGS) -c $< -o $(libDir)$@$(MATHOPTS), \
        Compiling $<)

Тогда результат простого вызова make будет выглядеть примерно так:

Compiling foo.c

Тогда как make V=1 даст:

gcc -Wall -c foo.c -o foo.o ...
3 голосов
/ 12 ноября 2014

Поскольку я не могу комментировать предложение AT = $(AT_$(V)), обратите внимание, что Automake предоставляет стандартный макрос, который делает то же самое, что и AT, который называется AM_V_at.

Вы также обнаружите, что у него есть еще одна очень полезная переменная AM_V_GEN, которая разрешается либо в ничего, либо в @echo " GEN " $@;, в зависимости от многословия.

Это позволяет вам кодировать что-то вроде этого:

grldr.mbr: mbrstart
    $(AM_V_GEN)
    $(AM_V_at)-rm -f grldr.mbr
    $(AM_V_at)cat mbrstart > grldr.mbr

Вывод которого будет либо (многословие отключено):

  GEN    grldr.mbr

или (многословие включено):

rm -f grldr.mbr
cat mbrstart > grldr.mbr

Довольно удобно, и это избавляет от необходимости определять свои собственные макросы.

...