Зачада: исходные коды на языке C/C++ и их надо преобразовать в бинарный формат, т.е. в исполняемое приложение. То есть надо скомпилировать приложение.

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

  1. Для каждого файла с исходными кодами на Си создать объектный бинарный файл. Проверси собственно процесс компиляции. Т.е. перевести из текста в бинарный формат.
  2. Создать испольняемый файл, который включал бы в себя все бинарные файлы, которые были созданы. Этот процесс называется линковка. Во время линковки проверяется, что все ранее декларированные функции доступны для работы бинарных файлов.

Давайте рассмотрим пример.

В Debian для установки make, а также других инструментов сборки (включая компилятор) необходимо поставить пакет build-essential.

  • Компиляция: gcc -c -o some.o some.c
  • Линковка: gcc -o app-name some.o
  • Если весь исходный код содержится в 1 файле, то можно сделать всё и сразу: gcc -o app-name some.c

Какие есть трудности у ручного подхода:

  • Файлов может быть много => возрастает возможность ошибки
  • Трудоёмко :)
  • Последовательность действий всё-равно надо передать другим разработчикам или пользователям, чтобы они смогли скомпилировать приложение.
  • Есть зависимость последнего шага от успеха всех остальных предыдущих шагов. Т.е. я не могу создать исполняемый файл раньше того как я создам объектные файлы.

Все эти проблемы решает make :).

Структура файла конфигурации make

Конфигурационный файл make называется: Makefile, makefile. Каноническим считается первый вариант.

Внутри Makefile необходимо определить цели, их зависимости и способ создания целей из зависимостей:

target: dependency dependency ...
    command
    command
    command

Зачастую в качестве целей и зависимостей выступают реальные файлы. В случае компиляции у нас цель - объектный файл, а зависимость - исходный файл.

Команды - это просто действия bash.

Для того, чтобы make создал цель достаточно будет дать команду: make target.

  • Автоматизиация действий
  • Документация

Что значит “цель не требует обновления”?

Make - умный. Он не будет создавать файл-цель, если его время изменения его зависимостей меньше, чем время изменения целевого файла.

Помимо компиляции есть также ещё и другие полезные действия, которые можно выполнять

  • Очистка от результатов (чтобы не хранить ненужные бинарные версии файлов)
  • Установка
  • Деинсталяция
  • Выполнение различного рода проверок

Для большинства этих команд цель в виде файла описать невозможно. Т.е. нам просто хочется выполнять действия без привязки к файлам.

Make позволяет такое. Цели без файлов называются ложными.

Что ещё полезного есть?

Есть комментарии! Они начинаются с #. Есть переменные! Есть автоматические переменные в рамках команд! Есть шаблонные правила!