Make
| Make | |
|---|---|
| Класс языка | утилита UNIX[вд], сценарный, язык, использующий отступы[вд], система сборки[вд] и язык программирования |
| Появился в | 1976[1][2] |
| Автор | Стюарт Фельдман |
| Диалекты | BSD make, GNU make, Microsoft nmake |
| Повлиял на | Ant, Rake, MSBuild и другие |
| Лицензия | GPLv3+ (GNU make) |
| ОС | Unix-like |
Make (МФА [meɪk]; с англ. — «сделать», «изготовить») — утилита, автоматизирующая процесс преобразования файлов из одной формы в другую. Чаще всего это компиляция исходного кода в объектные файлы и последующая компоновка в исполняемые файлы или библиотеки.
Утилита использует специальные make-файлы, в которых указаны зависимости файлов друг от друга и правила для их удовлетворения. На основе информации о времени последнего изменения каждого файла Make определяет и запускает необходимые программы.
Происхождение
До создания Make системы сборки (компиляции) ПО Unix обычно состояли из shell-скриптов сборки, сопровождавших исходный код программ.
Make была создана Стюартом Фельдманом (англ. Stuart Feldman) в 1976 году в Bell Labs. В 1977 году программа стала доступна пользователям[3].
В настоящее время существует множество утилит для отслеживания зависимостей, но Make — одна из самых широко распространённых, в первую очередь благодаря тому, что она включена в Unix, начиная с версии PWB/UNIX (англ. Programmer’s Workbench), которая содержала инструменты для разработки программного обеспечения.
Современные реализации
Существует много реализаций Make, основанных на оригинальной Make или написанных с нуля, использующих те же самые форматы файлов и базовые принципы и алгоритмы, а также содержащих некоторые улучшения и расширения. Наиболее распространёнными являются:
- BSD Make, основанная на работе Адама де Бура (Adam de Boor) над версией Make, с возможностью параллельной сборки; в той или иной форме перешла в FreeBSD, NetBSD и OpenBSD.
- GNU Make — входит в большинство дистрибутивов Linux и часто используется в сочетании с GNU toolchain.
POSIX включает в себя стандарт основных возможностей утилиты Make, с той или иной степенью совместимости реализованный в различных версиях Make. Как правило, простые make-файлы могут быть успешно обработаны различными версиями Make.
Использование
make [ -f make-файл ] [ цель ... ]
Файл ищется в текущем каталоге. Если ключ -f не указан, используется имя по умолчанию для make-файла — Makefile (однако в разных реализациях Make, кроме этого, могут проверяться и другие файлы, например GNUmakefile).
Make открывает make-файл, считывает правила и выполняет команды, необходимые для создания указанной цели.
Стандартные цели для сборки дистрибутивов GNU:
- all — выполнить сборку пакета;
- install — установить пакет из дистрибутива (производит копирование исполняемых файлов, библиотек и документации в системные каталоги);
- uninstall — удалить пакет (производит удаление исполняемых файлов и библиотек из системных каталогов);
- clean — очистить дистрибутив (удалить из дистрибутива объектные и исполняемые файлы, созданные в процессе компиляции);
- distclean — очистить все созданные при компиляции файлы и все вспомогательные файлы, созданные утилитой ./configure в процессе настройки параметров компиляции дистрибутива.
По умолчанию Make использует самую первую цель в make-файле.
В процессе сборки приложений BSD часто применяют:
- depend — выполнить компиляцию/выстраивание зависимостей.
Make-файл
Программа Make выполняет команды согласно правилам, указанным в специальном файле. Этот файл называется make-файл (makefile, мейкфайл). Как правило, make-файл описывает, каким образом нужно компилировать и компоновать программу.
make-файл состоит из правил и переменных. Правила имеют следующий синтаксис:
цель1 цель2 ...: зависимость1 зависимость2 ...
команда1
команда2
...
Правило представляет собой набор команд, выполнение которых приведёт к сборке файлов-целей из файлов-зависимостей.
Правило сообщает Make, что файлы, получаемые в результате работы команд (цели), являются зависимыми от соответствующих файлов-зависимостей. Make никак не проверяет и не использует содержимое файлов-зависимостей, однако указание списка файлов-зависимостей требуется только для того, чтобы Make убедилась в наличии этих файлов перед началом выполнения команд и для отслеживания зависимостей между файлами.
Обычно цель представляет собой имя файла, который генерируется в результате работы указанных команд. Целью также может служить название некоторого действия, которое будет выполнено в результате выполнения команд (например, цель clean в make-файлах для компиляции программ обычно удаляет все файлы, созданные в процессе компиляции).
Строки, в которых записаны команды, должны начинаться с символа табуляции.
Рассмотрим несложную программу на Си. Пусть программа program состоит из пары файлов кода — main.c и lib.c, а также из одного заголовочного файла — defines.h, который подключён в обоих файлах кода. Поэтому для создания program необходимо из пар (main.c defines.h) и (lib.c defines.h) создать объектные файлы main.o и lib.o, а затем скомпоновать их в program. При сборке вручную требуется исполнить следующие команды:
cc -c main.c
cc -c lib.c
cc -o program main.o lib.o
Если в процессе разработки программы в файл defines.h будут внесены изменения, потребуется перекомпиляция обоих файлов и линковка, а если изменим lib.c, то повторную компиляцию main.c можно не выполнять.
Таким образом, для каждого файла, который мы должны получить в процессе компиляции, нужно указать, на основе каких файлов и с помощью какой команды он создаётся. Программа Make на основе этих данных выполняет следующее:
- собирает из этой информации правильную последовательность команд для получения требуемых результирующих файлов;
- и инициирует создание требуемого файла только в случае, если такого файла не существует или он старше, чем файлы, от которых он зависит.
Если при запуске Make явно не указать цель, то будет обрабатываться первая цель в make-файле, имя которой не начинается с символа «.».
Для программы program достаточно написать следующий make-файл:
program: main.o lib.o
cc -o program main.o lib.o
main.o lib.o: defines.h
В имени второй цели указаны два файла и для этой же цели не указана команда компиляции. Кроме того, нигде явно не указана зависимость объектных файлов от «*.c»-файлов. Дело в том, что программа Make имеет предопределённые правила для получения файлов с определёнными расширениями. Так, для цели-объектного файла (расширение «.o») при обнаружении соответствующего файла с расширением «.c» будет вызван компилятор «сс -с» с указанием в параметрах этого «.c»-файла и всех файлов-зависимостей.
Синтаксис для определения переменных:
переменная = значение
Значением может являться произвольная последовательность символов, включая пробелы и обращения к значениям других переменных. С учётом сказанного, можно модифицировать наш make-файл следующим образом:
OBJ = main.o lib.o
program: $(OBJ)
cc -o program $(OBJ)
$(OBJ): defines.h
Вычисление значений переменных происходит только в момент использования (используется так называемое ленивое вычисление). Например, при сборке цели all из следующего make-файла на экран будет выведена строка «Huh?».
foo = $(bar)
bar = $(ugh)
ugh = Huh?
all:
echo $(foo)
Предположим, что к проекту добавился второй заголовочный файл lib.h, который включается только в lib.c. Тогда make-файл увеличится ещё на одну строчку:
lib.o: lib.h
Таким образом, один целевой файл может указываться в нескольких целях. При этом полный список зависимостей для файла будет составлен из списков зависимостей всех целей, в которых он участвует, создание файла будет производиться только один раз.
Многопоточное исполнение
Для ускорения длительных задач используют распараллеливание вычислений внутри make-программы. Распараллеливание делается автоматически make-интерпретатором. Для запуска make-файла в многопоточном режиме необходимо передать опцию -j <число потоков>.
make [ -j <число потоков> ] [ цель ]
См. также
Примечания
- ↑ Fowler G. S. The Fourth Generation Make // Proc. USENIX Summer Conference. — 1985. — P. 159—174.
- ↑ Curtsinger C., Barowy D. W. RIKER: Always-Correct and Fast Incremental Builds from Simple Specifications : [англ.] // 2022 USENIX Annual Technical Conference. — 2022. — P. 885-898.
- ↑ Akhlaghi M., Infante-Sainz R., Roukema B. F., Khellat M., Valls-Gabaud D., Baena-Gallé R. Toward Long-Term and Archivable Reproducibility // Computing in Science & Engineering. — Vol. 23, no. 3. — P. 82-91. — doi:10.1109/MCSE.2021.3072860.
Литература
- Руководство по GNU make Архивная копия от 24 сентября 2006 на Wayback Machine и его переводы — не единственные документы, подходящие для обучения. Для того, чтобы изучить данный инструмент, можно воспользоваться и другими информационными источниками:
- Управление проектами с GNU Make (эта книга — русский перевод «Managing Projects with GNU Make, Third Edition») Архивная копия от 11 июня 2018 на Wayback Machine
- Managing Projects with GNU Make, Third Edition Архивная копия от 9 июля 2016 на Wayback Machine
- Как создавать, собирать, устанавливать и использовать пакеты с программами и библиотеками для UNIX-подобных систем Архивная копия от 9 февраля 2017 на Wayback Machine
- Просто о make Архивная копия от 11 февраля 2017 на Wayback Machine
Ссылки
- Руководство по GNU make на gnu.org Архивная копия от 24 сентября 2006 на Wayback Machine (англ.)
- Руководство по GNU make (версия 3.79) Архивная копия от 12 июня 2011 на Wayback Machine (рус.)
- Руководство по FreeBSD make Архивная копия от 22 декабря 2013 на Wayback Machine (англ.)
- Решение проблем, возникающих при выполнении команд
./configure,makeиmake installАрхивная копия от 23 сентября 2007 на Wayback Machine - Эффективное использование GNU Make Архивная копия от 24 февраля 2009 на Wayback Machine (рус.)
Content Disclaimer
Informasi ini disarikan dari Wikipedia dan disajikan kembali untuk tujuan edukasi. Konten tersedia di bawah lisensi CC BY-SA 3.0. Kami tidak bertanggung jawab atas ketidakakuratan data yang bersumber dari kontribusi publik tersebut.
- The information displayed on this website is sourced in part or in whole from Wikipedia and has been adapted for the purpose of restating it. We strive to provide accurate and relevant information, however:
- There is no guarantee of absolute accuracy. Wikipedia is an open, collaborative project that can be edited by anyone, so information is subject to change.
- It is not intended to constitute professional advice. The content displayed is for informational and educational purposes only. For important decisions (e.g., medical, legal, or financial), please consult a professional.
- Content copyright. Wikipedia is licensed under the Creative Commons Attribution-ShareAlike License (CC BY-SA). This means that content may be reused with appropriate attribution and shared under a similar license.
- Responsible use. Any risk arising from the use of information from this website is entirely the responsibility of the user.