Руководства, Инструкции, Бланки

Gnu Make Руководство img-1

Gnu Make Руководство

Рейтинг: 4.8/5.0 (1709 проголосовавших)

Категория: Руководства

Описание

Мини-руководство по созданию Makefile-ов

Эта статья представляет собой небольшое руководство по созданию Makefile-ов. В ней объясняется для чего нужен Makefile и дается несколько правил, которых следует придерживаться при его создании.

Допустим, вы разрабатываете некую программу под названием foo. состоящую из пяти заголовочных файлов -- 1.h. 2.h. 3.h. 4.h и -- 5.h. и шести файлов с исходным текстом программы на языке С - 1.cpp. 2.cpp. 3.cpp. 4.cpp. 5.cpp и main.cpp. (Хочу заметить, что в реальных проектах следует избегать подобного стиля именования файлов).

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

Существует ли решение проблемы?

Не стоит беспокоиться, друзья мои! Эта проблема уже давно решена. Опытными программистами была разработана утилита make. Вместо того, чтобы производить повторную компиляцию всех файлов с исходными текстами, она обрабатывает только те файлы, которые претерпели изменения. В нашем случае будет скомпилирован только один файл - 2.cpp. Разве это не здорово!?

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

Несмотря на все свои достоинства, утилита make ничего не знает о нашем проекте, поэтому необходимо создать простой текстовый файл, который будет содержать все необходимые инструкции по сборке. Файл с инструкциями по сборке проекта называется makefile (произносится как "мэйкфайл". прим. перев. ) .

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

Например, если свой makefile вы назвали bejo. то команда на сборку проекта будет выглядеть так:

Makefile содержит разделы для "целей" [targets]. зависимостей [dependencies] и правил (rules) сборки. Все это оформляется следующим образом: сначала указывается имя цели (обычно это имя исполняемого или объектного файла), после которого следует двоеточие, затем следуют имена зависимостей, т.е. файлов, необходимых для получения данной цели. И, наконец, следует список правил: т.е. команд, которые необходимо выполнить для получения указанной цели.

Простой пример структуры makefile'а:

Каждое правило command должно начинаться с символа табуляции -- это обязательное условие! Отсутствие символа табуляции в начале строки с правилом - самая распространенная ошибка. К счастью, подобные ошибки легко обнаруживаются, так как утилита make сообщает о них.

Ниже приводится простой пример (номера строк добавлены для ясности).

В этом примере строка, содержащая текст
client: conn.o ,
называется "строкой зависимостей", а строка
g++ client.cpp conn.o -o client
называется "правилом" и описывает действие, которое необходимо выполнить.

А теперь более подробно о примере, приведенном выше:

  • Задается цель -- исполняемый файл client. который зависит от объектоного файла conn.o
  • Правило для сборки данной цели
  • В третьей строке задается цель conn.o и файлы, от которых она зависит -- conn.cpp и conn.h .
  • В четвертой строке описывается действие по сборке цели conn.o .

Строки, начинающиеся с символа "#", являются комментариями

Ниже приводится пример makefile с комментариями:

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

Допустим в makefile имеется правило, которое не создает ничего, например:

Поскольку команда rm не создает файл с именем clean. то такого файла никогда не будет существовать и поэтому команда make clean всегда будет отрабатывать.

Однако, данное правило не будет работать, если в текущем каталоге будет существовать файл с именем clean. Поскольку цель clean не имеет зависимостей, то она никогда не будет считаться устаревшей и, соответственно, команда 'rm *.o temp' никогда не будет выполнена. (при запуске make проверяет даты модификации целевого файла и тех файлов, от которых он зависит. И если цель оказывается "старше", то make выполняет соответствующие команды-правила -- прим. ред.) Для устранения подобных проблем и предназначена специальная декларация .PHONY. объявляющая "ложную" цель. Например:

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

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

В соответствии с соглашениями имена переменных задаются в верхнем регистре:

Чтобы получить значение переменной, необходимо ее имя заключить в круглые скобки и перед ними поставить символ '$', например:

В makefile-ах существует два типа переменных: "упрощенно вычисляемые" и "рекурсивно вычисляемые" .

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

При обращении к переменной SRCDIR вы получите значение /home/tedi/project/src .

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

выльются в бесконечный цикл. Для разрешения этой проблемы следует использовать "упрощенно вычисляемые" переменные:

Где символ ':=' создает переменную CC и присваивает ей значение "gcc -o". А символ '+=' добавляет "-O2" к значению переменной CC.

Я надеюсь, что это краткое руководство содержит достаточно информации, чтобы начать создавать свои makefile. А за сим -- успехов в работе.

  • 1 GNU Make Documentation File, info make.
  • 2 Kurt Wall, et.al. Linux Programming Unleashed(Программирование под Linux на оперативном просторе -- прим. ред.). 2001.

Другие статьи

GNU make

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

Это фрагмент статьи GNU make свободной энциклопедии Википедия. В Википедии приведен список авторов.

На сайте ru.wikipedia.org к статье GNU make за последние 30 дней обращались 26 раз. (по состоянию на: 04.05.2014 г.)

Изображения о GNU make

Стандартная задача — есть поток входящих файлов, на их основе надо создавать результирующие файлы. Входящих файлов десятки и сотни, постоянно …

На 64-х битной Windows при использовании 32-х битных утилит GnuWin переменная окружения PROCESSOR_ARCHITECTURE в Makefile имеет значение x86. Команды cmd.exe, имеющиеся в Makefile'е, выполняются успешно. Например, if not exist $(BUILD_DIR) mkdir $(BUILD_DIR) в командах цели работает так, как и ожидалось: создает папку при ее отсутствии.

Для знающих проблема известная и давно решённая, но я с этим столкнулся только сегодня. Итак, у нас имеется небольшой проект на C/C++, который собирается с помощью make. Пусть это будет программа под названием «program».

Пользуюсь под Windows набором компиляторов (хотя там не только компиляторы в комплекте конечно же) mingw (порт gcc под Windows). Очень расстраивает тот факт, что make не.

Использование XCode совместно с GNU make

Создание make-файлов

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

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

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

После того, как нужный make-файл создан, простой команды :

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

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

Простой make-файл

Простой make-файл состоит из "правил" (rules) следующего вида:

Обычно, цель ( target ) представляет собой имя файла, который генерируется в процессе работы утилиты make. Примером могут служить объектные и исполняемый файлы собираемой программы. Цель также может быть именем некоторого действия, которое нужно выполнить (например, clean - очистить).

Пререквизит ( prerequisite ) - это файл, который используется как исходдные данные для порождения цели. Очень часто цель зависит сразу от нескольких файлов.

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

Обычно, команды находятся в правилах с пререквизитами и служат для создания файла-цели, если какой-нибудь из пререквизитов был модефицирован. Однако, правило, имеющее команды, не обязательно должно иметь пререквизиты. Например, правило с целью clean ("очистка"), содержащее команды удаления, может не иметь пререквизитов.

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

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

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

В данном примере, заголовочный файл defs.h включается во все файлы с исходным текстом. Заголовочный файл command.h включается только в те исходные файлы, которые относятся к командам редактирования, а файл buffer.h - только в "низкоуровневые" файлы, непосредственно оперирующие буфером редактирования.

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

Для того, чтобы с помощью этого make-файла создать исполняемый файл edit. следует подать команду

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

В приведенном примере, целями, в частности, являются объектные файлы main.o и kbd.o. а также исполняемый файл edit. К пререквизитам относятся такие файлы, как main.c и defs.h. Каждый объектный файл, фактически, является одновременно и целью и пререквизитом. Примерами команд могут служить cc -c main.c и cc -c kbd.c .

В случае, если цель является файлом, этот файл должен быть перекомпилирован или перекомпонован всякий раз, когда был изменен какой-либо из его пререквизитов. Кроме того, любые пререквизиты, которые сами генерируются автоматически, должны быть обновлены первыми. В нашем примере, исполняемый файл edit зависит от восьми объектных файлов; объектный файл main.o зависит от исходного файла main.c и заголовочного файла defs.h .

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

Цель clean является не файлом, а именем действия. Поскольку, при обычной сборке программы это действие не требуется, цель clean не является пререквизитом какого-либо из правил. Следовательно, make не будет "трогать" это правило, пока вы специально об этом не попросите. Заметьте, что это правило не только не является пререквизитом, но и само не содержит каких-либо пререквизитов. Таким образом, единственное предназначение данного правила - выполнение указанных в нем команд. Цели, которые являются не файлами, а именами действий называются абстрактными целями (phony targets). Абстрактные цели подробно рассматриваются в разделе Абстрактные цели. В разделе Ошибки при выполнении команд описано, как заставить make игнорировать ошибки, которые могут возникнуть при выполнении команды rm и любых других команд.

Использование переменных

В приведенном выше примере, в правиле для edit нам дважды пришлось перечислять список объектных файлов программы:

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

Обычной практикой при построении make-файлов является использование переменной с именем objects. OBJECTS. objs. OBJS. obj. или OBJ. которая содержит список всех объектных файлов программы. Например:

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

Дополнительные цели сборки

Часто в make-файл включаются также и другие цели помимо компиляции:

  • Строка 1 — это комментарий; make следует обычной традиции Unix определения комментариев с помощью символа #.
  • В строке 3 определяется переменная по имени 0BJS как foo.о bar.o baz.о.
  • В строке 4 определяется другая переменная — LDLIBS.
  • В строке 6 начинается определение правила, которое указывает на то, что файл foo зависит от (в этом случае, собран из) файлов, имена которых содержатся в переменной OBJS. foo называется целевым объектом, а $ (OBJS) — списком зависимостей. Обратите внимание на синтаксис расширения переменной: имя переменной помещается в $(. ).
  • Строка 7 — это командная строка, указывающая на то, как построить целевой объект из списка зависимостей. Командных строк может быть много, и первым символом в командной строке должна быть табуляция.
  • Строка 9 — довольно интересный целевой объект. Фактически тут не предпринимается попытка создать файл по имени install; вместо этого foo инсталлируется в /usr/bin с помощью стандартной программы install. Эта строка вызывает неоднозначность в make. что, если файл install уже существует и является более новым, нежели foo. В этом случае запуск команды make install приведет к выдаче сообщения 'install' is up to date (install новее) и завершению работы.
  • Строка 11 указывает make на то, что install не является файлом, и что необходимо игнорировать любой файл по имени install при вычислении зависимости install. Таким образом, если зависимость install была вызвана (как это сделать мы рассмотрим далее), команда в строке 10 всегда будет выполняться.
    . PHONY — это директива, которая изменяет операцию make ; в этом случае она указывает make на то, что целевой объект install не является именем файла.
    Целевые объекты. PHONY часто используются для совершения действий вроде инсталляции или создания одиночного имени целевого объекта, которое основывается на нескольких других уже существующих целевых объектов, например:
    all: foo barbaz
    .PHONY: all
    К сожалению, . PHONY не поддерживается некоторыми версиями make. Менее очевидный, не такой эффективный, но более переносимый способ для этого показан ниже.
    all: foo bar baz FORCE
    FORCE:
    Это срабатывает только тогда, когда нет файла по имени FORCE .
Суффиксные правила

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

с.о:
$(СС) -с $(CFLAGS) $(CPPFLAGS) -о $@ $<
.SUFFIXES. с .о

В этом правиле говорится (если не касаться излишних деталей), что make должна, если не было других явных указаний, превратить файл а.с в а.о путем запуска приложенной командной строки. Каждый файл будет рассматриваться так, будто он явно внесен в список в качестве зависимости соответствующего файла в вашем make -файле.
Это суффиксное правило демонстрирует другую возможность make — автоматические переменные. Понятно, что нужно найти способ подставить зависимость и целевой объект в командную строку. Автоматическая переменная $@ выступает в качестве целевого объекта, $< выступает в качестве первой зависимости, а $^ представляет все зависимости.
Существуют и другие автоматические переменные, которые рассматриваются в руководстве по make. Все автоматические переменные можно использовать в обыкновенных правилах, а также в суффиксных и шаблонных правилах. Последняя строка примера представляет еще одну директиву .SUFFIXES указывает make на то, что и являются суффиксами, которые должен использовать make для нахождения способа превратить существующие исходные файлы в необходимые целевые объекты.
Шаблонные правила более мощные и, следовательно, немного сложнее, чем суффиксные правила. Ниже приведен пример эквивалентного шаблонного правила для показанного выше суффиксного правила.

%.о: %.с
$(СС) -с $(CFLAGS) $(CPPFLAGS) -о $@ $<

Большинство крупных проектов с открытым исходным кодом используют инструменты Automake, Autoconf и Libtool. Эти инструменты представляют собой коллекцию знаний об особенностях различных систем и стандартах сообщества, которая может помочь в построении проектов. Таким образом, потребуется писать лишь немного кода, специфического для проекта. Например, Automake пишет целевые объекты install и uninstall. Autoconf автоматически определяет возможности системы и настраивает программное обеспечение для его соответствия системе, a Libtool отслеживает различия в управлении совместно используемыми библиотеками на разных системах.

© УГАТУ 2014. кафедра ВВТиС. Бикмеев А.Т. Мухтаров А.Р.

GNU Make в автоматическом режиме по умолчанию

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

Теперь по умолчанию будет печатать ничего, но если запустить make VERBOSE=1. она будет распечатана.

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

ответ от Jun 3, '14 at 00:40

Даже более простой метод, чем использование ifndef просто писать $(VERBOSE).SILENT. Теперь, если VERBOSE пусто, вы получите .SILENT целевой аудитории, но если вы установите VERBOSE в любое непустое значение, то он будет отключен (определяют абсолютно разные цели, значит, ничего не сделать). Это также портативный для других версий сделать, если это важно для вас. – Jun 3, '14 at 03:46

Вы можете добавлять. --silent в MAKEFLAGS переменной в начале Makefile :

ответ от Jun 3, '14 at 09:23

Не нашли ответ на свой вопрос? Попробуйте просмотреть другие вопросы с тэгами:
makefile
Обсуждаемые вопросы

GNU Make - Эффективное использование GNU Make

2. GNU Make

В этой главе я кратко опишу некоторые возможности программы GNU Make. которыми я пользуюсь при написании своих make-файлов, а также укажу на ее отличия от "традиционных" версий make. Предполагается, что вы знакомы с принципом работы подобных программ. В противном случае сначала прочтите главу 3 - Утилита make.

GNU Make - это версия программы make распространяемая Фондом Свободного Программного Обеспечения (Free Software Foundation - FSF) в рамках проекта GNU (www.gnu.org ). Получить самую свежую версию программы и документации можно на "домашней страничке" программы www.gnu.org/software/make либо на страничке Paul D. Smith - одного из авторов GNU Make (www.paulandlesley.org/gmake ).

Программа GNU Make имеет очень подробную и хорошо написанную документацию, с которой я настоятельно рекомендую ознакомиться. Если у вас нет доступа в интернет, то пользуйтесь документацией в формате Info, которая должна быть в составе вашего дистрибутива Linux. Будьте осторожны с документацией в формате man-странички (man make) - как правило, она содержит лишь отрывочную и сильно устаревшую информацию.

2.1. Две разновидности переменных

GNU Make поддерживает два способа задания переменных, которые несколько различаются по смыслу. Первый способ - традиционный, с помощью оператора '=':

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

Значение переменной, заданной с помощью оператора '=', будет вычислено в момент ее использования. Например, при обработке make-файла:

на экран будет выдана строка "three two". Значение переменной var2 будет вычислено непосредственно в момент выполнения команды echo, и будет представлять собой текущее значение переменной var1, к которому добавлена строка " two". Как следствие - одна и та же переменная не может одновременно фигурировать в левой и правой части выражения, так как это может привести к бесконечной рекурсии. GNU Make распознает подобные ситуации и прерывает обработку make-файла. Следующий пример вызовет ошибку:

GNU Make поддерживает также и второй, новый способ задания переменной - с помощью оператора ':=':

В этом случае переменная работает подобно "обычным" текстовым переменным в каком-нибудь из языков программирования. Вот приблизительный аналог этого выражения на языке C++.

Значение переменной вычисляется в момент обработки оператора присваивания. Если, например, записать

то при обработке такого make-файла на экран будет выдана строка "one two".

Переменная может "менять" свое поведение в зависимости от того, какой из операторов присваивания был к ней применен последним. Одна и та же переменная на протяжении своей жизни вполне может вести себя и как "макрос" и как "текстовая переменная".

Все свои make-файлы я пишу с применением оператора ':='. Этот способ кажется мне более удобным и надежным. Вдобавок это более эффективно, так как значение переменной не вычисляется заново каждый раз при ее использовании. Подробнее о двух способах задания переменных можно прочитать в документации на GNU Make в разделе "The Two Flavors of Variables".

2.2. Функции манипуляции с текстом

Утилита GNU Make содержит большое число полезных функций, манипулирующих текстовыми строками и именами файлов. В частности в своих make-файлах я использую функции addprefix. addsuffix, wildcard. notdir и patsubst. Для вызова функций используется синтаксис

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

на экран будет выведено

Видно, что к каждому имени директории добавлен префикс "../../". Функция addprefix обсуждается в разделе "Functions for File Names" руководства по GNU Make.

Функция addsuffix работает аналогично функции addprefix. только добавляет указанную строку в конец каждого слова. Например, в результате выполнения make-файла:

на экран будет выведено

Видно, что к каждому имени директории добавлен суффикс "/*.cpp". Функция addsuffix обсуждается в разделе "Functions for File Names" руководства по GNU Make.

Функция wildcard "расширяет" переданный ей шаблон или несколько шаблонов в список файлов, удовлетворяющих этим шаблонам. Пусть в директории Editor находится файл Editor.cpp. а в директории TextLine - файл TextLine.cpp.
  • wildcard _example /
    • Editor /
      • Editor.cpp
    • TextLine /
      • TextLine.cpp
    • makefile

Тогда в результате выполнения такого make-файла:

на экран будет выведено

Видно, что шаблоны преобразованы в списки файлов. Функция wildcard подробно обсуждается в разделе "The Function wildcard " руководства по GNU Make.

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

на экран будет выведено

Видно, что из имен файлов убраны "пути" к этим файлам. Функция notdir обсуждается в разделе "Functions for File Names" руководства по GNU Make.

Функция patsubst позволяет изменить указанным образом слова, подходящие под шаблон. Она принимает три параметра - шаблон, новый вариант слова и исходную строку. Исходная строка рассматривается как список слов, разделенных пробелом. Каждое слово, подходящее под указанный шаблон, заменяется новым вариантом слова. В шаблоне может использоваться специальный символ '%', который означает "любое количество произвольных символов". Если символ '%' встречается в новом варианте слова (втором параметре), то он заменяется текстом, соответствующим символу '%' в шаблоне. Например, в результате выполнения make-файла:

на экран будет выведено

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

Применяя "короткий" вариант записи предыдущий пример можно записать так:

2.3. Новый способ задания шаблонных правил

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

То есть под действие правила попадают файлы с определенными расширениями (".cpp" и ".o" в данном случае).

GNU Make поддерживает более универсальный подход - с использованием шаблонов имен файлов. Для задания шаблона используется символ '%', который означает "последовательность любых символов произвольной длины". Символ '%' в правой части правила заменяется текстом, который соответствует символу '%' в левой части. Пользуясь новой формой записи, приведенный выше пример можно записать так:

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

2.4. Переменная VPATH

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

make будет искать файлы с расширением ".cpp" сначала в текущем каталоге, а затем, при необходимости, в подкаталогах Editor и TextLine. Я часто использую подобную возможность, так как предпочитаю располагать исходные тексты в иерархии каталогов, отражающих логическую структуру программы.

Переменная VPATH описывается в главе "VPATH. Search Path for All Dependencies" руководства по GNU Make. На страничке Paul D. Smith есть статья под названием "How Not to Use VPATH " ( paulandlesley.org/gmake/VPATH.html ), в которой обсуждается "неправильный" стиль использования переменной VPATH.

2.5. Директива override Переменные в GNU Make могут создаваться и получать свое значение разными способами:
  • Задаваться внутри make-файла
  • "Автоматически" создаваться программой make из переменных среды
  • Задаваться через командную строку при вызове программы make

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

Предположим, что переменная compile_flags была задана через командную строку при запуске программы make:

В результате обработки make-файла на экран будет выведена строка:

То есть попытка изменить значение переменной compile_flags внутри make-файла была проигнорирована. Если все-таки возникает необходимость в изменении переменной, которая была задана с помощью командной строки, нужно использовать директиву override. Директива помещается перед именем переменной, которая должна быть изменена:

Теперь в результате обработки make-файла на экран будет выдана строка:

2.6. Добавление текста в строку

Часто возникает необходимость добавить текст к существующей переменной. Для этой цели служит оператор "+=". Добавляемый текст может быть как текстовой константой, так и иметь ссылки на другие переменные:

При использовании этого оператора, "тип" переменной (см. раздел 2.1 "Две разновидности переменных" ) не меняется - "макросы" остаются "макросами", а "текстовые переменные" по-прежнему остаются таковыми.

Если переменная задана с помощью командной строки, то по-прежнему для изменения ее значения внутри make-файла нужно использовать директиву override. В следующем примере предполагается, что переменная compile_flags задана в командной строке:

2.7. Директива include

С помощью директивы include можно включать в обрабатываемый make-файл другие файлы. Работает она аналогично директиве #include в языках C и C++. Когда встречается эта директива, обработка "текущего" make-файла приостанавливается и make временно "переключается" на обработку указанного в директиве файла. Директива include может оказаться полезной для включения в make-файл каких-либо "общих", или автоматически сгенерированных другими программами фрагментов.

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

Указанные в директиве файлы должны существовать - иначе make предпримет попытку "создать" их, а при невозможности этого достигнуть, выдаст сообщение об ошибке. Директива include с пустым списком файлов:

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

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

Имя автоматической переменной

Компиляция и установка программ из исходников

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

Программы обычно распространяются в упакованных архивах, это файлы с расширениями

Нужно понимать отличие между архиватором и упаковщиком.

Для архивации директорий и файлов используется программа tar ; результатом её работы является файл с расширением .tar. Грубо говоря, это копия файловой системы - директорий и файлов с их атрибутами и правами доступа, помещённая в один файл.

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

Программа tar умеет распаковывать, поэтому не нужно вызывать gunzip. а можно просто указать программе tar. что файл нужно cначала распаковать. Например, команда

сразу распакует и разархивирует. Отличие файлов с расширениями

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

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

Для сборки программ в GNU/Linux используется (в основном) программа make. которая запускает инструкции из Makefile. но поскольку дистрибутивов GNU/Linux много, и они все разные, то для того чтобы собрать программу, нужно для каждого дистрибутива отдельно прописывать пути,где какие лежат библиотеки и заголовочные файлы. Программисты не могут изучать каждый дистрибутив и для каждого отдельно создавать Makefile. Поэтому придумали конфигураторы, которые «изучают» систему, и в соответствии с полученными знаниями создают Makefile. Но на конфигураторе они не остановились и придумали конфигураторы конфигураторов …на этом они остановились

Для сборки нам нужны компиляторы: они прописаны в зависимостях пакета build-essential. так что достаточно установить его со всеми зависимостями. Ещё нужны autoconf и automake.

Итак, чтобы собрать что-то из исходников, нужно сначала собрать конфигуратор; как собрать конфигуратор, описано в файле configure.in. Для сборки конфигуратора необходимо выполнить

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

Все эти команды используют файл configure.in. После выполнения этих команд создастся файл configure. После этого необходимо запустить конфигуратор для проверки наличия всех зависимостей, а также установки дополнительных опций сборки (если возможно) и просмотра результата установки (опционально- может не быть)

Конфигуратор построит Makefile основываясь на полученных знаниях и файле makefile.am. Можно передать конфигуратору опции, предусмотренные в исходниках программы, которые позволяют включать/отключать те или иные возможности программы, обычно узнать о них можно командой

Также есть набор стандартных опций, вроде

которая указывает, какой каталог использовать для установки. Для Ubuntu обычно

БЕЗ слеша в конце! Теперь можно запустить процесс сборки самой программы командой

Для сборки достаточно привелегий обычного пользователя. Окончанием сборки можно считать момент, когда команды в консоли перестанут «беспорядочно» выполняться и не будет слова error. Теперь всё скомпилировано и готово для установки.

Усилия потраченные на Правильную установку в последствии с лихвой окупятся в случае удаления или обновления устанавливаемого программного обеспечения.

Установка при помощи утилиты checkinstall. Для установки выполните

Минус данного способа: checkinstall понимает не все исходники, поскольку автор программы может написать особые скрипты по установке и checkinstall их не поймёт.

Для создания и установки deb-пакета необходимо выполнить

Быстрое создание deb-пакета «вручную».

Основное отличие от предыдущего способа заключается в том, что в данном случае вы создаете пакет вручную и отслеживаете все вносимые изменения. Так же этот способ подойдет вам, если исходники не поддерживают сборку пакета с checkinstall.

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

Создадим в «корне пакета» директорию DEBIAN и сложим в DEBIAN/conffiles список всех файлов, которые должны попасть в /etc:

После чего создаём файл DEBIAN/control следующего содержания:

При необходимости там же можно создать скрипты preinst, postinst, prerm и postrm.

Создаем deb-пакет, для чего выполняем:

Получаем на выходе tempinstall.deb, который и устанавливаем

Процедура создания deb-пакета подробно описана в данной статье.

Минус данного способа заключается в том, что если вы устанавливаете напрямую через make install, то нормально удалить или обновить пакет вы, скорее всего, не сможете. Более того, установка новой версии поверх старой, скорее всего, затрёт ваши изменения в конфигах. make install делает ровно то, что ему сказано — производит установку файлов в нужные места, игнорируя тот факт, что там что-то уже есть. После этого процесса совершенно никакой информации о том, что и куда ставилось, получить в удобоваримом виде невозможно. Иногда, конечно, Makefile поддерживает действие uninstall, но это встречается не так часто, да и не факт, что корректно работает. Кроме того, вам будет необходимо хранить для деинсталяции распакованное дерево исходников и правил сборки.

Для установки необходимо выполнить

Для удаления пакета, установленного данным способом необходимо выполнить в корневой директории исходников программы (там где вы запускали make install).

Часто на этапе конфигурации конфигуратор сообщает, что нехватает той или иной библиотеки. Название библиотеки, которое он сообщает, не всегда соответствует названию пакета в Ubuntu. Из собственного опыта могу посоветовать поискать в Синаптике нужный пакет, исключив префикс lib, если нашлось несколько пакетов различающихся приставкой -dev в названии, то вам нужно установить именно -dev пакет (обычно он тянет за собой и не -dev пакет). Можно ещё поискать с помощью http://packages.ubuntu.com/. введя имя библиотеки в поиск по содержимому пакетов, аналогично, если найдётся dev и не dev, нужны оба . Ну или просто поискать в Google.

Пакеты с буквами mm в конце описания — это пакеты для C++ программ. Список для bmpx, но подойдёт почти для любой GTK2/Gnome программы. Так что если не получается собрать, то посмотрите на этот список и сверьте с тем что у вас установлено.