makefile виконує іншу ціль


123

У мене makefile структурований приблизно так:

all : 
    compile executable

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

Я зрозумів, що я постійно працюю "очистити", а потім "очистити" в своєму терміналі, перш ніж запустити "зробити все". Мені подобається мати чистий термінал, перш ніж спробувати просіювати помилкові помилки компіляції C ++. Тому я спробував додати 3-ю ціль:

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

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

Відповіді:


172

Насправді ви праві: він запускає інший екземпляр 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яка виконує роботу.

EDIT 4 серпня

Що відбувається у випадку паралельних побудов із -jваріантом make ? Існує спосіб фіксації замовлення. З інструкції до виготовлення, розділ 4.2:

Однак інколи у вас виникає ситуація, коли ви хочете накласти певне замовлення на правила, які слід викликати, не примушуючи оновлення цілі, якщо виконується одне з цих правил. У цьому випадку потрібно визначити передумови лише для замовлення. Необхідні умови для замовлення можна вказати, розмістивши символ труби (|) у списку передумов: будь-які передумови зліва від символу труби є нормальними; будь-які передумови праворуч - лише замовлення: цілі: звичайні передумови | передумови лише для замовлення

Звичайно, розділ звичайних передумов може бути порожнім. Також ви можете оголосити кілька рядків передумов для однієї цілі: вони додаються належним чином. Зауважте, що якщо ви оголошуєте один і той же файл як звичайною, так і умовою лише для замовлення, нормальна умова має перевагу (оскільки вони є суворим набором поведінки лише для замовлення).

Отже, makefile стає

.PHONY : clearscr fresh clean all

all :
    compile executable

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

fresh : | clean clearscr all

clearscr:
    clear

EDIT 5 грудня

Запускати більше ніж один екземпляр makefile - це не велика справа, оскільки кожна команда всередині завдання в будь - якому випадку буде підколюшкою. Але ви можете використовувати багаторазові методи за допомогою функції виклику .

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!")

6
@ sas4740: в основному все, що випливає .PHONY : , трактується як якесь ключове слово, яке завжди виконується, тоді як некеровані цілі призначені для файлів.
Dacav

чи є "передумовами лише замовлення" умовними? для цілі t2 я хочу спочатку зробити t0, ніж лише тоді, коли t0 успіхів запустити t1, і лише якщо обидва успішні виконують якусь задачу в t3
фантастика

1
@fantastory, ні, я думаю, що вони незалежні. t2буде залежати від того t0, t1і t3. Якщо вам це потрібно, слід покласти так, t3як того вимагає t2, t1як того вимагає t3і t0як вимагає t1. Це означає 3 різних правила. Однак ви повинні це підтвердити. Я не впевнений на 100%.
Дакав

3
"Передумови лише для замовлення" є незалежними
фантастичні

2
Я не бачу, де гарантія того, що "чистота" діє перед "всім"? Те, що ви їх поставили прямо з | не змушує їх виконувати в порядку. Залежність лише для замовлення означає, що ціль не обов'язково оновлюється після такої операції. Це не має нічого спільного з впорядкуванням залежних елементів ... чи?
CygnusX1

6

Якщо ви видалили make allрядок зі своєї "свіжої" цілі:

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

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

Дехто може розглянути це як другий екземпляр make, але це, звичайно, не підменш make (make всередині make), до чого, здавалося, привела ваша спроба.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.