Система выполнения задач Make
Зачада: исходные коды на языке C/C++ и их надо преобразовать в бинарный формат, т.е. в исполняемое приложение. То есть надо скомпилировать приложение.
Понятно, что большое приложение на Си состоит из множества файлов. В таком случае процесс компиляции выглядит следующим образом:
- Для каждого файла с исходными кодами на Си создать объектный бинарный файл. Проверси собственно процесс компиляции. Т.е. перевести из текста в бинарный формат.
- Создать испольняемый файл, который включал бы в себя все бинарные файлы, которые были созданы. Этот процесс называется линковка. Во время линковки проверяется, что все ранее декларированные функции доступны для работы бинарных файлов.
Давайте рассмотрим пример.
В 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 позволяет такое. Цели без файлов называются ложными.
Что ещё полезного есть?
Есть комментарии! Они начинаются с #
.
Есть переменные!
Есть автоматические переменные в рамках команд!
Есть шаблонные правила!