Похоже, разработчики боятся использовать make, поскольку они связывают это с болезненным опытом компиляции с нуля - ужасным ./configure && make && make install.

Частично этот страх связан с описанием того, что делает make (1):

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

Фонд свободного программного обеспечения Справочные страницы Linux

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

Выполнение задач

Давайте начнем с простого создания Makefile и определения задачи для выполнения:

task:
  date

Если вы запустите make task, вы столкнетесь со следующей ошибкой:

/tmp ᐅ make task
Makefile:2: *** missing separator.  Stop.

И это потому, что Makefile использует табуляцию для отступа кода. Давайте обновим наш пример, используя табуляции, а не пробелы и… Вуаля.

/tmp ᐅ make task
date
Fri Jun 15 08:34:15 +04 2018

Что это за колдовство? Итак, make понял, что вы хотите запустить раздел task своего make-файла, и запустил код (date) в этом разделе в оболочке, выводя и команду, и ее вывод. Если вы хотите пропустить вывод выполняемой команды, вы можете просто поставить перед ней знак @:

task:
  @date

Повторный запуск команды make:

/tmp ᐅ make task
Fri Jun 15 08:34:15 +04 2018

Первая задача в Makefile - это по умолчанию, что означает, что мы можем запустить make без каких-либо аргументов:

/tmp ᐅ make       
Fri Jun 15 08:37:11 +04 2018

Выполнение дополнительных задач

Вы можете добавить дополнительные задачи в свой Makefile и вызывать их с помощью make $TASK:

task:
  @date
some:
  sleep 1
  echo "Slept"
thing:
  cal

Повторный запуск команды make:

/tmp ᐅ make thing
cal
     June 2018        
Su Mo Tu We Th Fr Sa  
                1  2  
 3  4  5  6  7  8  9  
10 11 12 13 14 15 16  
17 18 19 20 21 22 23  
24 25 26 27 28 29 30

Выполнение задач в определенном порядке

Очень часто вы захотите выполнить задачу перед текущей. Думайте об этом как о before или after ловушках в ваших автоматических тестах. Это можно сделать, указав список задач сразу после названия задачи:

task: thing some
  @date
...

Повторный запуск команды make:

/tmp ᐅ make task
cal
     June 2018        
Su Mo Tu We Th Fr Sa  
                1  2  
 3  4  5  6  7  8  9  
10 11 12 13 14 15 16  
17 18 19 20 21 22 23  
24 25 26 27 28 29 30
sleep 1
echo "Slept"
Slept
Fri Jun 15 08:40:23 +04 2018

Использование переменных с make

Определение и использование переменных довольно просто:

VAR=123
print_var:
        echo ${VAR}
...

Повторный запуск команды make:

/tmp ᐅ make print_var    
echo 123
123

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

print_user:
        echo $USER

Повторный запуск команды make:

/tmp ᐅ make print_user   
echo SER
SER

Вам нужно будет избежать их с помощью ${VAR} или $$VAR.

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

print_foo:
  echo $$FOO

Повторный запуск команды make:

/tmp ᐅ make print_foo
echo $FOO
/tmp ᐅ make print_foo FOO=bar
echo $FOO
bar

Сделайте и оболочку

5.3.1 Choosing the Shell
------------------------
The program used as the shell is taken from the variable `SHELL'.  If this variable is not set in your makefile, the program `/bin/sh' is used as the shell.

Make будет использовать sh для выполнения кода в задаче. Это означает, что некоторые вещи могут не работать, поскольку вы, вероятно, используете какой-то синтаксис, специфичный для bash. Чтобы переключиться, вы можете просто указать переменную SHELL. В нашем случае мы хотели бы использовать SHELL:=/bin/bash.

Как было замечено ранее, иногда вам нужно использовать необычный настраиваемый синтаксис, чтобы заставить обычную команду оболочки работать в make. Так же, как переменные нужно экранировать с помощью $$ или ${...}, вам нужно будет использовать shell при использовании подстановки команд:

subshell:
  echo $(shell echo ${USER})

Повторный запуск команды make:

/tmp ᐅ make subshell
echo alex
alex

Не верите мне? Попробуйте удалить shell инструкцию. Вот что вы получите:

/tmp ᐅ make subshell
echo

Заключение

Можно сделать гораздо больше, make и еще столько необычных вещей, которые вам, возможно, придется выяснить, чтобы уменьшить WPS (WTF в секунду) при работе с ним. 😄

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

Изначально опубликовано на odino.org (15 июня 2018 г.).
Вы можете подписаться на меня в Twitter - тирады приветствуются!
😉