Make linux что это

Просто о make

Меня всегда привлекал минимализм. Идея о том, что одна вещь должна выполнять одну функцию, но при этом выполнять ее как можно лучше, вылилась в создание UNIX. И хотя UNIX давно уже нельзя назвать простой системой, да и минимализм в ней узреть не так то просто, ее можно считать наглядным примером количество- качественной трансформации множества простых и понятных вещей в одну весьма непростую и не прозрачную. В своем развитии make прошел примерно такой же путь: простота и ясность, с ростом масштабов, превратилась в жуткого монстра (вспомните свои ощущения, когда впервые открыли мэйкфайл).

Мое упорное игнорирование make в течении долгого времени, было обусловлено удобством используемых IDE, и нежеланием разбираться в этом ‘пережитке прошлого’ (по сути — ленью). Однако, все эти надоедливые кнопочки, менюшки ит.п. атрибуты всевозможных студий, заставили меня искать альтернативу тому методу работы, который я практиковал до сих пор. Нет, я не стал гуру make, но полученных мною знаний вполне достаточно для моих небольших проектов. Данная статья предназначена для тех, кто так же как и я еще совсем недавно, желают вырваться из уютного оконного рабства в аскетичный, но свободный мир шелла.

Make- основные сведения

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

1) целями (то, что данное правило делает);
2) реквизитами (то, что необходимо для выполнения правила и получения целей);
3) командами (выполняющими данные преобразования).

В общем виде синтаксис makefile можно представить так:

То есть, правило make это ответы на три вопроса:

Несложно заметить что процессы трансляции и компиляции очень красиво ложатся на эту схему:

Простейший Makefile

Предположим, у нас имеется программа, состоящая всего из одного файла:

Для его компиляции достаточно очень простого мэйкфайла:

Компиляция из множества исходников

Предположим, что у нас имеется программа, состоящая из 2 файлов:
main.c

Makefile, выполняющий компиляцию этой программы может выглядеть так:

Он вполне работоспособен, однако имеет один значительный недостаток: какой — раскроем далее.

Инкрементная компиляция

Представим, что наша программа состоит из десятка- другого исходных файлов. Мы вносим изменения в один из них, и хотим ее пересобрать. Использование подхода описанного в предыдущем примере приведет к тому, что все без исключения исходные файлы будут снова скомпилированы, что негативно скажется на времени перекомпиляции. Решение — разделить компиляцию на два этапа: этап трансляции и этап линковки.

Теперь, после изменения одного из исходных файлов, достаточно произвести его трансляцию и линковку всех объектных файлов. При этом мы пропускаем этап трансляции не затронутых изменениями реквизитов, что сокращает время компиляции в целом. Такой подход называется инкрементной компиляцией. Для ее поддержки make сопоставляет время изменения целей и их реквизитов (используя данные файловой системы), благодаря чему самостоятельно решает какие правила следует выполнить, а какие можно просто проигнорировать:

Попробуйте собрать этот проект. Для его сборки необходимо явно указать цель, т.е. дать команду make hello.
После- измените любой из исходных файлов и соберите его снова. Обратите внимание на то, что во время второй компиляции, транслироваться будет только измененный файл.

После запуска make попытается сразу получить цель hello, но для ее создания необходимы файлы main.o и hello.o, которых пока еще нет. Поэтому выполнение правила будет отложено и make станет искать правила, описывающие получение недостающих реквизитов. Как только все реквизиты будут получены, make вернется к выполнению отложенной цели. Отсюда следует, что make выполняет правила рекурсивно.

Фиктивные цели

На самом деле, в качестве make целей могут выступать не только реальные файлы. Все, кому приходилось собирать программы из исходных кодов должны быть знакомы с двумя стандартными в мире UNIX командами:

Командой make производят компиляцию программы, командой make install — установку. Такой подход весьма удобен, поскольку все необходимое для сборки и развертывания приложения в целевой системе включено в один файл (забудем на время о скрипте configure). Обратите внимание на то, что в первом случае мы не указываем цель, а во втором целью является вовсе не создание файла install, а процесс установки приложения в систему. Проделывать такие фокусы нам позволяют так называемые фиктивные (phony) цели. Вот краткий список стандартных целей:

Теперь мы можем собрать нашу программу, произвести ее инсталлцию/деинсталляцию, а так же очистить рабочий каталог, используя для этого стандартные make цели.

Обратите внимание на то, что в цели all не указаны команды; все что ей нужно — получить реквизит hello. Зная о рекурсивной природе make, не сложно предположить как будет работать этот скрипт. Так же следует обратить особое внимание на то, что если файл hello уже имеется (остался после предыдущей компиляции) и его реквизиты не были изменены, то команда make ничего не станет пересобирать. Это классические грабли make. Так например, изменив заголовочный файл, случайно не включенный в список реквизитов, можно получить долгие часы головной боли. Поэтому, чтобы гарантированно полностью пересобрать проект, нужно предварительно очистить рабочий каталог:

Для выполнения целей install/uninstall вам потребуются использовать sudo.

Переменные

Все те, кто знакомы с правилом DRY (Don’t repeat yourself), наверняка уже заметили неладное, а именно — наш Makefile содержит большое число повторяющихся фрагментов, что может привести к путанице при последующих попытках его расширить или изменить. В императивных языках для этих целей у нас имеются переменные и константы; make тоже располагает подобными средствами. Переменные в make представляют собой именованные строки и определяются очень просто:

Существует негласное правило, согласно которому следует именовать переменные в верхнем регистре, например:

Ниже представлен мэйкфайл, использующий две переменные: TARGET — для определения имени целевой программы и PREFIX — для определения пути установки программы в систему.

Это уже посимпатичней. Думаю, теперь вышеприведенный пример для вас в особых комментариях не нуждается.

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

Автоматические переменные предназначены для упрощения мейкфайлов, но на мой взгляд негативно сказываются на их читабельности. Как бы то ни было, я приведу здесь несколько наиболее часто используемых переменных, а что с ними делать (и делать ли вообще) решать вам:

Источник

Введение в make

Назначение, история, варианты

Утилита make предназначена для автоматизации сборки проектов. Если какие-либо файлы проекта могут быть сгенерированы из других файлов, утилита позволяет выполнить процесс построения наиболее оптимальным способом, по возможности минимизируя количество обрабатываемых файлов.

Исторически утилита предназначалась для сборки проектов на языке C в операционной системе Unix, однако может быть использоваться для работы с любыми проектами. Первая версия системы была создана в 1977 году.

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

Мы работаем с GNU make. На BSD системах (в частности, FreeBSD, он может быть доступен как gmake, на Linux — просто make).

Основные принципы

Утилита make работает по правилам (rules), записанным в специальном конфигурационном файле. Правила определяют цели (targets), завимости между целями и набор команд для выполнения каждой цели.

Цели могут соответствовать определенным файлам. Кроме того, цели могут не соответствовать ни одному файлу и использоваться для группировки других целей или определенной последовательности команд. Такие цели называются phony targets.

Каждая цель может зависеть от выполнения других целей. Выполнение цели требует предварительного выполнения других целей, от которых она зависит.

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

Таким образом, makefile определяет граф зависимостей, по которому утилита make выполняет ту или иную цель, по возможности минимизируя количество операций сборки.

Запуск make

При запуске make можно указать цель, которая будет выполнена. Если цель не указана, используется цель по умолчанию, которая либо указана в файле правил явно, либо неявно используется первая определенная цель.

Явное указание цели выполняется инструкцией DEFAULT_GOAL в Makefile :

Можно указать сразу несколько целей.

Выполнение целей может быть настроено с использованием переменных (о которых ниже). При запуске make можно указать значения переменных:

Значение переменной PREFIX будет доступно в правилах Makefile и может быть использовано при сборке.

Команда поддерживает также ряд дополнительных опций, из которых наиболее важные следующие:

Базовый синтаксис make

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

PHONY targets

Цели, не соответствующие файлам, и предназначенные для выполнения набора команд или группировки завимостей, декларируются следующим образом:

Соответственно, в Makefile мы можем написать:

Переменные

В make-файле можно использовать переменные, хотя правильнее сказать, что можно использовать макросы.

Переменные определяются присваиванием в makefile или могут быть переданы извне.

Переменные — это макроопределения, причем вычисление переменной всегда выполняется в самый последний момент перед подстановкой. Макросы могут использовать везде в тексте makefile.

Соответственно, если мы вызовем

Если переменная содержит несколько строк, можно использовать синтаксис define :

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

В результате www/js/script.js будет результатом объединения трех js-файлов.

Полный список таких переменных приведен в документации, для нас наиболее интересны:

С полным списком можно ознакомиться в документации: Automatic Variables.

Условное выполнение

В Makefile можно использовать условные выражения. Опять же, мы говорим о макрообработке make, соответственно, условные выражения работают на уровне makefile, а не на уровне команд. Обычно условные выражения используются для определения тех или иных целей в зависимости от значения переменных. Например:

В качестве условий можно проверять определенность переменной, а также ее значение:

Полностью с возможностями условных выражений можно ознакомиться в документации: Conditional syntax.

Шаблонные правила

Шаблонные правила (pattern rules) позволяют указать правило преобразования одних файлов в другие на основании зависимостей между их именами. Например, мы можем указать правило для получения объектного файла из файла на языке C:

Шаблоны не обязаны ограничиваться расширениями файлов. Если исходные и выходные файлы соответствуют друг другу и в их именах есть какая-либо зависимость, можно использовать pattern rule.

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

Файл make может подключить другие файлы make оператором include :

Таким образом, из файлов можно строить модульную систему, часто имеет смысл выполнять include внутри условного оператора.

Функции

Make определяет большой набор функций, которые могут быть использованы в переменных (макросах). Вызов функции выполняется конструкцией:

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

Несколько примеров из hive. Получаем текущее время (обратите внимание на использование := :

Включение файла container.mk только в случае, если он существует:

Добавление префиксов и суффиксов к именам файлов

Подробнее о функциях можно прочитать в документации Functions.

Собственные функции

Очень тупой пример:

Теперь можно написать:

Рекурсивный make

Помимо включения другого файла make, Makefile может выполнить другой файл make в виде отдельного make-процесса.

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

Параллельный make

Специальные цели

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

Варианты использования

Чаще всего о make говорят в контексте сборки программ на C/C++, в конце концов, для этого он изначально предназначался. Однако, make ­— гораздо более универсальный инструмент. Записывая makefile, мы декларативно описываем определенное состояние отношений между файлами, которое каждый запуск make будет стараться поддерживать. Декларативный характер определения состояния очень удобен, в случае использования какого-либо императивного языка (например, shell) нам приходилось бы выполнять большое количество различных проверок, получая на выходе сложный и запутанный код.

Кроме того, использование зависимостей между phony targets, позволяющии, по сути, декларативно описывать некий (ограниченный) конечный автомат, может быть полезно для написания различных административных сценариев. Используя make в качестве каркаса для выполнения различных shell-команд, мы получаем по сути некий базовый framework для shell с готовым пользовательским интерфейсом (вызов make + передача переменных), встроенными средствами отслеживания зависимостей, параллельного выполнения, макроопределениями и т.д.

Поэтому базовое знание make позволяет в ряде случаев решить проблему пусть и не самым красивым, но зато быстрым и достаточно надежным способом.

Источник

Make files not war: что такое утилита GNU make, зачем ее использовать и как это делать правильно

Авторизуйтесь

Make files not war: что такое утилита GNU make, зачем ее использовать и как это делать правильно

Make linux что это. Смотреть фото Make linux что это. Смотреть картинку Make linux что это. Картинка про Make linux что это. Фото Make linux что это

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

Суть автоматической сборки состоит в том, чтобы взять за основу генерацию какого-то одного элемента, вычленить правила, по которым она происходит, и применить их к большему количеству элементов такого же типа, обновляя только изменяемые параметры.

Это может быть сделано (и часто делается) под определенную задачу с помощью кастомных скриптов, но мы в данной статье рассмотрим, как можно удобно автоматизировать сборку, используя утилиту make и её встроенные правила.

Почему стоит использовать утилиту make

Пишем make-файлы

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

Базовый синтаксис для определения цели (в файле makefile ):

Важно Индентация производится с помощью табуляции, а не пробелов.

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

Часто нам нужно обрабатывать несколько файлов одного вида по одним и тем же правилам. Например, при создании страниц HTML на основе размеченного текста. Это делается с помощью шаблонных правил, наличие которых является отличительной чертой make в сравнении с обычной сборкой через командную строку.

Теперь мы можем упростить make-файл, избегая написания команд в случаях, когда make сама знает, что делать. Главное, не забывать ставить пустую строку после цели — make это нужно, чтобы определять, где кончается одна цель и начинается другая.

Будьте аккуратны: когда вы предлагаете make свой список команд, она будет ориентироваться только на ваш код и в данном случае не будет искать шаблонные правила для сборки цели.

Вызываем make

Запустим make в текущей директории:

Если make-файл в ней уже есть, будет создана (собрана) первая цель, которую make сможет найти. Если make-файла нет (или он есть, но в нем нет целей), make об этом сообщит.

Чтобы обратиться к конкретной цели, запустите:

Здесь цель — это название цели (без квадратных скобок).

Специальные цели

В большинстве make-файлов можно найти цели, называемые специальными. Вот самые распространенные:

Они не обязательно должны присутствовать в make-файле, но большинство сборочных процессов странно представить без хотя бы первых трех.

Цель all обычно просто содержит главный исполняемый файл в пререквизите — иногда с дополнительными командами для пост-обработки генерируемых файлов. Так как мы в большинстве случаев хотим, чтобы цель all исполнялась по умолчанию, она должна стоять первой в файле.

Для цели clean стоит добавить список команд, удаляющих все генерируемые файлы. Это может быть легко сделано с использованием переменных, о которых мы поговорим в следующем разделе.

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

Как и в большинстве языков программирования, make-файлы можно сделать более читабельными, используя переменные. make импортирует свою среду, позволяя нам определять переменные внутри файла через внешние источники.

Основные операции

Определять переменные и ссылаться на них можно следующим образом:

Передача аргументов встроенным шаблонным правилам

Ранее мы видели некоторые шаблонные правила в действии, правда, во всех случаях они запускали одни и те же базовые команды. Конечно, требования к сборке не всегда одинаковы, и инструменты могут запрашивать разные флаги для разных задач.

Например, какому-то ПО нужно обеспечить соединение с разными библиотеками, или заданные оптимизации различаются для сборки отладки и итоговой сборки.

Поэтому встроенные правила в make включают в себя несколько распространённых переменных в важных местах команд. Мы можем установить их по желанию из make-файла или внешней среды.

Это позволяет, например, запускать один и тот же make-файл с разными компиляторами, снабдив make необходимым именем бинарного файла для выполнения. Так задаётся переменная среды компилятора C:

Вот некоторые из самых известных переменных, которые вы могли видеть, если когда-нибудь заглядывали в make-файл:

Программные переменные

make хранит некоторые распространённые программы в переменных. В основном это делается для того, чтобы при необходимости их можно было перезаписать.

Функции нескольких переменных

GNU make определяет некоторые очень полезные методы, большинство которых работает со словами, то есть с разделенными пробелами строками символов. Это облегчает работу с переменными, содержащими в себе списки файлов.

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

Вот некоторые наиболее интересные методы:

Подробное описание функций можно найти в официальной документации.

Продвинутое использование переменных

Отсылки к переменным можно делать в любом контексте внутри make-файла. Можно даже соорудить имя исполняемого файла внутри списка команд с помощью соединения нескольких переменных. Это позволяет использовать переменные в качестве целей или пререквизитов и создавать простые конструкции типа:

Это становится мощным инструментом в сочетании с шаблонными правилами — мы можем автоматически собирать пререквизиты, которые косвенно используются в качестве новых целей.

Замена суффиксов

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

Целезависимые переменные

Это ещё одна интересная особенность, использование которой ведёт к сокращению кода: она позволяет устанавливать переменным разные значения в зависимости от текущей цели.

Интеграция с внешними процессами

В связи с тем, что дистрибутивы Linux в большинстве случаев поставляются с системой управления пакетами и многие пакеты создаются из проектов, использующих make для сборки, были приняты некоторые общие правила использования переменных.

Определение шаблонных правил

Синтаксис для написания шаблонных правил во многом похож на обычный синтаксис целей. Основное отличие состоит в использовании шаблонного символа % в основе цели (её имени до расширения), который и будет применяться для поиска соответствий.

Шаблон также может быть использован в списке пререквизитов, где он будет заменён на основу для формирования неявно определённых пререквизитов. (Список пререквизитов в случае чего можно расширить и явно определёнными.)

Также можно перезаписать любое из встроенных правил с помощью определения правила с такой же целью и пререквизитами.

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

Динамические переменные

Все имена динамических переменных состоят из одного знака, поэтому скобки для ссылки на них не нужны. Таких переменных довольно много, рассмотрим наиболее необходимые:

Итоги

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

Скрипт generate_article.py реализует минималистичный шаблонизатор, используя index.htm в качестве базы для вставки HTML, сгенерированного из входных файлов. Присутствие шаблонизатора в пререквизитах шаблонного правила обеспечивает, что изменения в шаблонизаторе вызовут изменения всех файлов, относящихся к статье.

Для дальнейшего изучения make рекомендуем ознакомиться с официальным руководством.

Источник

Понимание команд Unix и Linux: make

Цель утилиты make – автоматически определить, какие части большой программы нужно перекомпилировать, и выполнить команды для их перекомпиляции. В руководстве описана реализация make для GNU, написанная Ричардом Столлманом и Роландом Макгрэтом. В этих примерах показаны программы на C, так как они наиболее распространены, но вы можете использовать make с любым языком программирования, чей компилятор можно запустить с помощью команды оболочки. На самом деле, make не ограничивается программами. Вы можете использовать его для описания любой задачи, когда некоторые файлы должны обновляться автоматически от других, когда другие изменяются.

Эта страница является выдержкой из документации GNU make . Она обновляется только из-за того, что проект GNU не использует nroff. Для полной текущей документации обратитесь к информационному файлу make.info, который сделан из исходного файла Texinfo make.texinfo.

Синтаксис и подготовка утилиты make

Чтобы подготовиться к использованию make, вы должны написать файл под названием makefile, который описывает отношения между файлами в вашей программе и содержит команды для обновления каждого файла. Обычно исполняемый файл обновляется из объектных файлов, которые, в свою очередь, создаются путем компиляции исходных файлов.

Когда существует подходящий make-файл, каждый раз, когда вы меняете некоторые исходные файлы, этой простой команды оболочки make достаточно для выполнения всех необходимых перекомпиляций. Программа make использует базу данных makefile и время последнего изменения файлов, чтобы решить, какие из файлов необходимо обновить. Для каждого из этих файлов он выдает команды, записанные в базе данных.

Утилита make обновляет цель, если она зависит от файлов предварительных требований, которые были изменены с момента последнего изменения цели, или если цель не существует.

Опции

Параметры -b и -m игнорируются для совместимости с другими версиями make.

Опция -e дает переменные, взятые из приоритета среды над переменными из make-файлов.

Параметр -f файл использует файл в качестве файла сборки.

Параметр -i игнорирует все ошибки в командах, выполняемых для преобразования файлов.

Параметр -I dir указывает каталог dir для поиска включенных make-файлов. Если несколько опций -I используются для указания нескольких каталогов, каталоги ищутся в указанном порядке. В отличие от аргументов других флагов make, каталоги с флагами -I могут указываться непосредственно после флага: -Idir разрешен, а также -I dir . Этот синтаксис разрешен для совместимости с флагом -I препроцессора C.

Опция -k продолжается в максимально возможной степени после ошибки; в то время как цель, которая вышла из строя, и те, которые зависят от нее, не могут быть переделаны, другие зависимости этих целей могут быть обработаны одинаково.

Параметры -l и -l load указывают, что не следует запускать новые задания (команды), если выполняются другие задания, а средняя нагрузка составляет не менее load (число с плавающей точкой). Без аргументов удаляет предыдущий лимит загрузки.

Опция -n печатает команды, которые будут выполнены, но не выполняет их.

Опция -p печатает базу данных (правила и значения переменных), полученную в результате чтения make-файлов. Затем он выполняется как обычно или как указано иначе. Это также печатает информацию о версии, предоставленную переключателем -v (см. Ниже). Чтобы распечатать базу данных, не пытаясь переделать какие-либо файлы, используйте make -p -f/dev/null .

Опция -q задает режим вопросов. Не выполняйте никаких команд и ничего не печатайте, просто верните состояние выхода, которое равно нулю, если указанные цели уже обновлены, в противном случае – ненулевое значение.

Опция -r исключает использование встроенных неявных правил. Также очищает список суффиксов по умолчанию для правил суффиксов.

Параметр -s отключает операцию. Это не печатает команды, поскольку они выполнены.

Опция -t касается файлов (помечает их как актуальные, без их реального изменения) вместо запуска их команд. Это используется, чтобы сделать вид, что команды были выполнены, чтобы обмануть будущие вызовы make.

Опция -v печатает версию программы make, а также авторские права, список авторов и уведомление об отсутствии гарантии.

Параметр -W файл делает вид, что целевой файл только что был изменен. При использовании с флагом -n это показывает, что произойдет, если вы измените этот файл. Без -n это почти то же самое, что запуск команды touch для данного файла перед запуском make, за исключением того, что время модификации изменяется только в воображении make.

Источник

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *