Основное предназначение древней юниксовой утилиты make — сборка С/С++ программ.
Но в последнее время набирает популярность еще одно — запуск команд в проектах, особенно в веб-разработке.
Обычно в любом проекте требуется выполнять какие-то команды.
Например, из самого общего: запустить тесты, линтеры, веб-сервер.
Можно, конечно, просто записать их в документации, но её можно забыть обновить, да и неудобно всё время копировать или куда-то сохранять их на каждой машине (альясы, IDE, ...).
Многие добавляют команды в систему сборки или конфиг менеджера пакетов, которые уже есть в проекте (Gulp/Grunt, npm, Composer, ...). Но часто в проектах используется более одной такой системы (например, для backend и frontend) и команды оказываются в разных местах, потому что так проще по техническим причинам (например, не надо указывать полный путь к зависимости) или логичнее. Кроме того, в разных проектах используются разные технологии, и во всём этом легко запутаться.
Еще один вариант — скрипты на Bash или используемом в проекте языке (Python, JS, ...). Более гибко, но сложнее писать и читать, и тоже зависит от используемых технологий, неудобно тащить в проект Питон только для этого.
Решение этих проблем — использовать Makefile в качестве сборника команд.
Создаем файл с именем Makefile в корне проекта, и добавляем туда любые используемые команды, в том числе и вызовы команд других систем сборки.
install: composer install npm install setup: install cp -n .env.example .env || true start: php -S localhost:8000 -t public test: composer phpunit lint: composer phpcs deploy: git push heroku master
Теперь после git clone можно выполнить make setup для подготовки свежескаченного проекта к работе, make start для запуска веб-сервера, make lint test для запуска линтера и тестов, и make deploy для отправки изменений в продакшн.
Преимущества make:
- Как правило всегда доступен на Linux и MacOS (установлен по умолчанию или ставится со стандартными инструментами разработки). Обычно веб-разработчики и сидят на этих ОС.
- Не надо ставить ничего дополнительного для самого запуска команд. Например, интерпретатор и утилиты языка, чтобы просто запустить Docker или Vagrant уже содержащий всё нужное.
- Не зависит от языка, фреймворка, IDE и прочих инструментов.
- Простой синтаксис (для таких задач), проще и понятнее Bash-скриптов. Нельзя добавить сложную логику в сам Makefile, поэтому он не превратится в нечитаемую кашу. Не смешивается с другими вещами, в отличии от конфига менеджера пакетов.
- Удобно вызывать: make <cmd> вместо какого-нибудь npm run <cmd>. Доступен автокомплит по TAB в стандартных терминалах.
- Самодокументирование. Всегда можно открыть Makefile и посмотреть актуальные команды, узнать что можно делать в этом проекте.
- Не надо вспоминать что и как запустить при переключении между разными языками/технологиями.
- Стабильность. Мейку не первый десяток лет и вряд ли он поменяется.
Недостатки:
- Недоступен на Windows. Можно взять make/nmake из MinGW/VS, но Windows не POSIX-совместимая ОС и некоторые команды из не-виндовых проектов не будут работать. Как вариант, WSL в вин10, Git Bash.
- Некоторые особенности синтаксиса и работы. Отступы должны быть только TAB'ами, а команды совпадающие с именами папок/файлов надо добавить в .PHONY.
Примеры в проектах:
- PHP Lumen/Laravel https://github.com/AlexP11223/php-project-lvl3
- Ruby, Python, Node.JS, Java, ... https://github.com/Hexlet
Больше инфы, краткое руководство с тонкостями и примерами: https://ru.makefile.site