HTML Diff
0 added 0 removed
Original 2026-01-01
Modified 2026-02-26
1 <p>Makefile - это декларативный скрипт‑конфигурационный файл, набор правил, который описывает, как собрать проект: какие шаги выполнять, в каком порядке и при каких условиях. Инструмент появился ещё в конце 1970-х вместе с экосистемой Unix и стал стандартом для автоматизации повторяющихся действий. Несмотря на появление множества современных систем сборки, Make по-прежнему используют в разработке С/С++, для управления скриптами, генерации документации, тестирования и вспомогательных задач.</p>
1 <p>Makefile - это декларативный скрипт‑конфигурационный файл, набор правил, который описывает, как собрать проект: какие шаги выполнять, в каком порядке и при каких условиях. Инструмент появился ещё в конце 1970-х вместе с экосистемой Unix и стал стандартом для автоматизации повторяющихся действий. Несмотря на появление множества современных систем сборки, Make по-прежнему используют в разработке С/С++, для управления скриптами, генерации документации, тестирования и вспомогательных задач.</p>
2 <p>Главная идея проста: разработчик один раз описывает зависимость между целями, а дальше все рутинные шаги выполняются автоматически. Это позволяет избежать ручных ошибок, ускоряет работу и делает проект повторяемым на любой машине.</p>
2 <p>Главная идея проста: разработчик один раз описывает зависимость между целями, а дальше все рутинные шаги выполняются автоматически. Это позволяет избежать ручных ошибок, ускоряет работу и делает проект повторяемым на любой машине.</p>
3 <h2>Синтаксис и структура</h2>
3 <h2>Синтаксис и структура</h2>
4 <p>Структура Makefile достаточно минималистична. Документ состоит из трёх ключевых элементов:</p>
4 <p>Структура Makefile достаточно минималистична. Документ состоит из трёх ключевых элементов:</p>
5 <h3>Цели (targets)</h3>
5 <h3>Цели (targets)</h3>
6 <p>Это именованные действия, которые можно вызвать. Например, "собрать проект", "очистить временные файлы", "запустить тесты". Каждая цель может быть связана с набором входных ресурсов.</p>
6 <p>Это именованные действия, которые можно вызвать. Например, "собрать проект", "очистить временные файлы", "запустить тесты". Каждая цель может быть связана с набором входных ресурсов.</p>
7 <h3>Зависимости (dependencies)</h3>
7 <h3>Зависимости (dependencies)</h3>
8 <p>Список объектов, на основании которых определяется, нужно ли выполнять цель. Если исходные ресурсы изменились, Make понимает, что действие нужно повторить.</p>
8 <p>Список объектов, на основании которых определяется, нужно ли выполнять цель. Если исходные ресурсы изменились, Make понимает, что действие нужно повторить.</p>
9 <h3>Правила (rules)</h3>
9 <h3>Правила (rules)</h3>
10 <p>Команды, которые выполняются, когда цель "протухла" - то есть требует обновления. Важно: каждое действие начинается с табуляции, и это одна из самых частых причин ошибок.</p>
10 <p>Команды, которые выполняются, когда цель "протухла" - то есть требует обновления. Важно: каждое действие начинается с табуляции, и это одна из самых частых причин ошибок.</p>
11 <p>Также в файле можно объявлять переменные, использовать условия, выполнять подстановки и переиспользовать повторяющиеся фрагменты.</p>
11 <p>Также в файле можно объявлять переменные, использовать условия, выполнять подстановки и переиспользовать повторяющиеся фрагменты.</p>
12 <h2>Примеры реализации</h2>
12 <h2>Примеры реализации</h2>
13 <ol><li><strong>Сборка C-приложения</strong></li>
13 <ol><li><strong>Сборка C-приложения</strong></li>
14 </ol><p>Здесь описана простая схема: как собрать итоговый бинарный артефакт из объектных файлов, а также правила для компиляции каждого исходника.</p>
14 </ol><p>Здесь описана простая схема: как собрать итоговый бинарный артефакт из объектных файлов, а также правила для компиляции каждого исходника.</p>
15 <ol><li><strong>Автоматизация задач для Python-проекта.</strong>Можно запускать виртуальное окружение, обновлять зависимости, выполнять тесты:</li>
15 <ol><li><strong>Автоматизация задач для Python-проекта.</strong>Можно запускать виртуальное окружение, обновлять зависимости, выполнять тесты:</li>
16 </ol><ol><li><strong>Работа с LaTeX</strong></li>
16 </ol><ol><li><strong>Работа с LaTeX</strong></li>
17 </ol><p>Такой подход помогает превратить сложную цепочку команд в короткое и понятное действие.</p>
17 </ol><p>Такой подход помогает превратить сложную цепочку команд в короткое и понятное действие.</p>
18 <h2>Основные команды Make</h2>
18 <h2>Основные команды Make</h2>
19 <p>Наиболее распространённые варианты вызова:</p>
19 <p>Наиболее распространённые варианты вызова:</p>
20 <ul><li>make - выполняет первую цель в файле (часто это "build").</li>
20 <ul><li>make - выполняет первую цель в файле (часто это "build").</li>
21 <li>make clean - удаляет временные материалы, чтобы сборка началась "с нуля".</li>
21 <li>make clean - удаляет временные материалы, чтобы сборка началась "с нуля".</li>
22 <li>make install - переносит артефакты в нужные каталоги.</li>
22 <li>make install - переносит артефакты в нужные каталоги.</li>
23 <li>make test - запускает тестовые сценарии.</li>
23 <li>make test - запускает тестовые сценарии.</li>
24 <li>make &lt;имя_цели&gt; - позволяет вызвать любую пользовательскую операцию, например deploy или format.</li>
24 <li>make &lt;имя_цели&gt; - позволяет вызвать любую пользовательскую операцию, например deploy или format.</li>
25 </ul><p>Каждый разработчик может определить свои правила, превращая Makefile в центральную точку автоматизации.</p>
25 </ul><p>Каждый разработчик может определить свои правила, превращая Makefile в центральную точку автоматизации.</p>
26 <h2>Ошибки и отладка</h2>
26 <h2>Ошибки и отладка</h2>
27 <p>Несмотря на лаконичность синтаксиса, присутствует довольно высокая чувствительность к форматированию:</p>
27 <p>Несмотря на лаконичность синтаксиса, присутствует довольно высокая чувствительность к форматированию:</p>
28 <ul><li><strong>отступы табом</strong>, а не пробелами - частая причина сбоев;</li>
28 <ul><li><strong>отступы табом</strong>, а не пробелами - частая причина сбоев;</li>
29 <li><strong>циклические зависимости</strong>приводят к бесконечным попыткам пересборки;</li>
29 <li><strong>циклические зависимости</strong>приводят к бесконечным попыткам пересборки;</li>
30 <li><strong>неверные пути</strong>к файлам нарушают логику, особенно при больших проектах;</li>
30 <li><strong>неверные пути</strong>к файлам нарушают логику, особенно при больших проектах;</li>
31 <li><strong>переопределение переменных</strong>без учёта области видимости приводит к непредсказуемому поведению.</li>
31 <li><strong>переопределение переменных</strong>без учёта области видимости приводит к непредсказуемому поведению.</li>
32 </ul><p>Для проверки используется флаг: make --debug. Он помогает увидеть, какие правила анализируются и почему выполняется то или иное действие.</p>
32 </ul><p>Для проверки используется флаг: make --debug. Он помогает увидеть, какие правила анализируются и почему выполняется то или иное действие.</p>
33 <h2>Интеграция с современными инструментами</h2>
33 <h2>Интеграция с современными инструментами</h2>
34 <p>Makefile остаётся востребованным благодаря универсальности:</p>
34 <p>Makefile остаётся востребованным благодаря универсальности:</p>
35 <ul><li>запускается внутри<strong>Docker</strong>-контейнеров для подготовки окружения;</li>
35 <ul><li>запускается внутри<strong>Docker</strong>-контейнеров для подготовки окружения;</li>
36 <li>используется в<strong>CI/CD</strong>, где простые команды Make формируют этапы пайплайна;</li>
36 <li>используется в<strong>CI/CD</strong>, где простые команды Make формируют этапы пайплайна;</li>
37 <li>взаимодействует с другими системами сборки - например, cmake генерирует Makefile автоматически.</li>
37 <li>взаимодействует с другими системами сборки - например, cmake генерирует Makefile автоматически.</li>
38 </ul><p>Такой подход упрощает переносимость: проект можно собрать как локально, так и на сервере с идентичным результатом.</p>
38 </ul><p>Такой подход упрощает переносимость: проект можно собрать как локально, так и на сервере с идентичным результатом.</p>
39 <h2>Современные тенденции</h2>
39 <h2>Современные тенденции</h2>
40 <p>Хотя сегодня появились новые инструменты (CMake, Ninja, Gradle), Makefile сохраняет свои позиции:</p>
40 <p>Хотя сегодня появились новые инструменты (CMake, Ninja, Gradle), Makefile сохраняет свои позиции:</p>
41 <ul><li>применяется как "универсальный инструмент" для автоматизации;</li>
41 <ul><li>применяется как "универсальный инструмент" для автоматизации;</li>
42 <li>работает практически в любой Unix-среде;</li>
42 <li>работает практически в любой Unix-среде;</li>
43 <li>остаётся удобным способом документировать процесс сборки через понятные цели.</li>
43 <li>остаётся удобным способом документировать процесс сборки через понятные цели.</li>
44 </ul><p>Что интересно, Makefile встречается даже в проектах, созданных на языках, для которых существуют собственные сборщики.</p>
44 </ul><p>Что интересно, Makefile встречается даже в проектах, созданных на языках, для которых существуют собственные сборщики.</p>
45 <p><a>https://ru.hexlet.io/blog/posts/makefile-as-task-runner</a></p>
45 <p><a>https://ru.hexlet.io/blog/posts/makefile-as-task-runner</a></p>