makefile выполнить другую цель - PullRequest
91 голосов
/ 16 июля 2010

У меня есть make-файл, структурированный примерно так:

all : 
    compile executable

clean :
    rm -f *.o $(EXEC)

Я понял, что последовательно запускаю команду «make clean», а затем «clear» в своем терминале перед запуском «make all» Мне нравится иметь чистый терминал, прежде чем я попытаюсь проанализировать неприятные ошибки компиляции C ++. Поэтому я попытался добавить третью цель:

fresh :
    rm -f *.o $(EXEC)
    clear
    make all

Это работает, однако запускает второй экземпляр make (я полагаю). Есть ли правильный способ получить ту же функциональность без запуска второго экземпляра make?

Ответы [ 2 ]

135 голосов
/ 16 июля 2010

На самом деле вы правы: он запускает другой экземпляр make.Возможное решение было бы:

.PHONY : clearscr fresh clean all

all :
    compile executable

clean :
    rm -f *.o $(EXEC)

fresh : clean clearscr all

clearscr:
    clear

. Вызвав make fresh, вы получите сначала цель clean, затем clearscreen, которая запускает clear и, наконец, all, которая выполняет работу.

РЕДАКТИРОВАТЬ Авг 4

Что происходит в случае параллельных сборок с опцией make -j?Есть способ исправить порядок.Из руководства по make, раздел 4.2:

Иногда, однако, возникает ситуация, когда вы хотите наложить определенный порядок на правила, которые должны быть вызваны, не заставляя цель обновляться, если один из нихправила выполнены.В этом случае вы хотите определить предварительные условия только для заказа.Предварительные условия только для заказа можно указать, поместив символ трубы (|) в список предварительных условий: любые предварительные условия слева от символа трубы являются нормальными;все предварительные условия справа - только для заказа: target: normal-prerequisites |обязательные предварительные условия заказа

Нормальный раздел предварительных условий, конечно, может быть пустым.Кроме того, вы все равно можете объявить несколько строк предварительных условий для одной и той же цели: они добавляются соответствующим образом.Обратите внимание, что если вы объявляете один и тот же файл как нормальным и обязательным предварительным условием, нормальное предварительное условие имеет приоритет (так как они являются строгим надмножеством поведения обязательного предварительного заказа).

Следовательно, make-файл становится

.PHONY : clearscr fresh clean all

all :
    compile executable

clean :
    rm -f *.o $(EXEC)

fresh : | clean clearscr all

clearscr:
    clear

РЕДАКТИРОВАТЬ 5 декабря

Запустить не более одного экземпляра make-файла, так как каждая команда внутри задачи будетбыть субоболочкой в любом случае.Но вы можете использовать повторно используемые методы, используя функцию вызова .

log_success = (echo "\x1B[32m>> $1\x1B[39m")
log_error = (>&2 echo "\x1B[31m>> $1\x1B[39m" && exit 1)

install:
  @[ "$(AWS_PROFILE)" ] || $(call log_error, "AWS_PROFILE not set!")
  command1  # this line will be a subshell
  command2  # this line will be another subshell
  @command3  # Use `@` to hide the command line
  $(call log_error, "It works, yey!")

uninstall:
  @[ "$(AWS_PROFILE)" ] || $(call log_error, "AWS_PROFILE not set!")
  ....
  $(call log_error, "Nuked!")
5 голосов
/ 01 февраля 2018

Если вы удалили строку make all из своей «свежей» цели:

fresh :
    rm -f *.o $(EXEC)
    clear

Вы можете просто запустить команду make fresh all, которая будет выполняться как make fresh; make all.

Некоторые могут считать это вторым экземпляром make, но это, конечно, не под-экземпляр make (make внутри make), к которому, как казалось, ваша попытка привела.

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