Открыть сервис

Make-код

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

История

Утилита make была разработана Стюартом Фельдманом в 1976 году в Bell Labs (подразделение AT&T). Первоначально она предназначалась для автоматизации сборки программ на языке C в операционной системе Unix. Идея заключалась в том, чтобы описать в текстовом файле (Makefile) правила преобразования исходных файлов в объектные и исполняемые, а затем запускать только те команды, которые необходимы из-за изменений в исходниках. Фельдман получил за эту разработку премию ACM Software System Award в 2003 году.

С тех пор make стал стандартным инструментом в Unix-подобных системах (Linux, macOS, BSD) и был портирован на многие другие платформы, включая Microsoft Windows (через Cygwin, MinGW или NMake). Существуют различные реализации make, такие как GNU Make (наиболее распространённая), BSD Make, Microsoft NMake и другие. Несмотря на появление более современных систем сборки (CMake, Meson, Gradle), make-файлы остаются широко используемыми, особенно в проектах на C/C++, а также в инфраструктурных скриптах.

Структура make-файла

Make-файл состоит из набора правил (rules), каждое из которых имеет следующий синтаксис:

`` цель: зависимости команды ``

  • Цель (target) — обычно имя файла, который нужно создать (например, program.o или program), или имя псевдоцели (например, clean, all).
  • Зависимости (prerequisites) — файлы, от которых зависит цель. Если хотя бы одна зависимость новее цели, цель считается устаревшей и пересобирается.
  • Команды (recipes) — последовательность команд оболочки (shell), которые выполняются для создания цели. Каждая команда должна начинаться с символа табуляции (не пробелов).

Пример простого make-файла

``` CC = gcc CFLAGS = -Wall -O2

program: main.o utils.o $(CC) $(CFLAGS) -o program main.o utils.o

main.o: main.c header.h $(CC) $(CFLAGS) -c main.c

utils.o: utils.c utils.h $(CC) $(CFLAGS) -c utils.c

clean: rm -f *.o program ```

В этом примере:

  • Определены переменные CC и CFLAGS.
  • Цель program зависит от объектных файлов main.o и utils.o.
  • Цели main.o и utils.o описывают компиляцию каждого исходного файла.
  • Псевдоцель clean удаляет все объектные файлы и исполняемый файл.

Переменные и функции

Make-код поддерживает переменные, которые упрощают управление параметрами сборки. Переменные могут быть заданы в файле, переданы в командной строке или унаследованы из окружения. Примеры:

``` CC = gcc CFLAGS = -std=c99 -pedantic LDFLAGS = -lm

SRCDIR = src OBJDIR = obj ```

Также в GNU Make доступны встроенные функции для работы со строками и файлами, например:

  • $(wildcard pattern) — поиск файлов по шаблону.
  • $(patsubst pattern,replacement,text) — замена суффиксов.
  • $(shell command) — выполнение команды оболочки.

Автоматические переменные

Для упрощения правил используются автоматические переменные, которые подставляются в команды:

  • $@ — имя цели.
  • $< — имя первой зависимости.
  • $^список всех зависимостей.
  • $? — список зависимостей, которые новее цели.

Пример с автоматическими переменными:

`` %.o: %.c $(CC) $(CFLAGS) -c $< -o $@ ``

Это правило говорит: «для любого файла с расширением .o, который зависит от соответствующего .c файла, скомпилировать его».

Псевдоцели и специальные цели

Псевдоцели (phony targets) — это цели, которые не соответствуют реальным файлам. Они объявляются с помощью .PHONY, чтобы избежать конфликтов с файлами, имеющими то же имя. Типичные псевдоцели:

  • all — сборка всего проекта (часто первая цель по умолчанию).
  • cleanудаление временных файлов.
  • install — установка программы в систему.
  • test — запуск тестов.

Специальные цели, такие как .DEFAULT, .SUFFIXES, .PRECIOUS, .INTERMEDIATE, управляют поведением make.

Условные конструкции

Make-код поддерживает условные директивы, позволяющие адаптировать сборку под разные платформы или конфигурации:

`` ifeq ($(OS),Windows_NT) RM = del /Q else RM = rm -f endif ``

Доступны директивы ifeq, ifneq, ifdef, ifndef.

Включение других файлов

Директива include позволяет подключать другие make-файлы, что полезно для разделения конфигурации:

`` include config.mk include $(wildcard *.d) ``

Применение

Make-код применяется в самых разных областях разработки:

  • Сборка программ на C/C++ — классическое использование.
  • Обработка документации — генерация PDF из LaTeX, HTML из Markdown.
  • Автоматизация тестирования — запуск тестовых наборов.
  • Развёртывание — копирование файлов, настройка окружения.
  • Научные вычисления — воспроизводимость экспериментов (например, сборка данных из сырых файлов).

Критика и ограничения

Несмотря на широкое распространение, make-код имеет ряд недостатков:

  • Синтаксисчувствительность к табуляции, неочевидные правила экранирования.
  • Сложность отладки — ошибки в make-файлах часто трудно диагностировать.
  • Платформенная зависимость — команды оболочки могут различаться на Windows и Unix.
  • Отсутствие модульности — для больших проектов make-файлы становятся громоздкими.
  • Параллельная сборка — хотя make -j поддерживает параллелизм, правильно описать зависимости бывает сложно.

Для преодоления этих ограничений были созданы инструменты-генераторы make-файлов, такие как CMake, Autotools (GNU Build System), а также альтернативные системы сборки (Ninja, SCons, Meson).

Интересные факты

  • GNU Make — самая популярная реализация; её версия 3.81 вышла в 2006 году, но до сих пор используется.
  • Make-файлы могут быть рекурсивными — вызывать make для подкаталогов, хотя это считается антипаттерном.
  • Существует стандарт POSIX для make, но GNU Make поддерживает множество расширений.
  • В некоторых проектах make-файлы используются не только для сборки, но и для управления проектом (например, «make deploy», «make migrate»).

BFOmetr — база данных и аналитика по компаниям России.

На главную BFOmetr →