Майкл Джонсон - Разработка приложений в среде Linux. Второе издание
OBJS := foo.о
OBJS := $(OBJS) bar.о
OBJS := $(OBJS) baz.о
Операция := заставляет GNU make вычислить выражение переменной при присваивании, а не ждать вычисления выражения при его использовании в правиле. В результате выполнения этого кода OBJS действительно получит foo.о bar.о baz.о.
Простое присваивание переменной используется очень часто, но в GNU make есть еще и другой синтаксис присваивания, который позаимствован из языка С:
OBJS := foo.о
OBJS += bar.о
OBJS += baz.о
4.2.3. Суффиксные правила
Суффиксные правила — это другая область, в которой вам нужно решить, писать ли стандартные make-файлы или использовать расширения GNU. Стандартные суффиксные правила намного ограниченнее, нежели шаблонные правила GNU, но во многих ситуациях стандартные суффиксные правила могут оказаться полезными. К тому же шаблонные правила поддерживаются не во всех версиях make. Суффиксные правила выглядят следующим образом:
.c.o:
$(CC) -с $ (CFLAGS) $ (CPPFLAGS) -о $<
.SUFFIXES: .с .о
В этом правиле говорится (если не касаться излишних деталей), что make должна, если не было других явных указаний, превратить файл а.с в а.о путем запуска приложенной командной строки. Каждый файл .с будет рассматриваться так, будто он явно внесен в список в качестве зависимости соответствующего файла .о в вашем make-файле.
Это суффиксное правило демонстрирует другую возможность make — автоматические переменные. Понятно, что нужно найти способ подставить зависимость и целевой объект в командную строку. Автоматическая переменная [email protected] выступает в качестве целевого объекта, $< выступает в качестве первой зависимости, а $^ представляет все зависимости.
Существуют и другие автоматические переменные, которые рассматриваются в руководстве по make. Все автоматические переменные можно использовать в обыкновенных правилах, а также в суффиксных и шаблонных правилах.
Последняя строка примера представляет еще одну директиву. .SUFFIXES указывает make на то, что .с и .о являются суффиксами, которые должен использовать make для нахождения способа превратить существующие исходные файлы в необходимые целевые объекты.
Шаблонные правила более мощные и, следовательно, немного сложнее, чем суффиксные правила. Ниже приведен пример эквивалентного шаблонного правила для показанного выше суффиксного правила.
% .о: % .с
$(CC) -с $(CFLAGS) $(CPPFLAGS) -о $<
Дополнительные сведения о make можно получить в [26]. GNU make также включает замечательное и удобное в обращении руководство в формате Texinfo, которое можно почитать на сайте FSF, распечатать или заказать у них в форме книги.
Большинство крупных проектов с открытым исходным кодом используют инструменты Automake, Autoconf и Libtool. Эти инструменты представляют собой коллекцию знаний об особенностях различных систем и стандартах сообщества, которая может помочь в построении проектов. Таким образом, потребуется писать лишь немного кода, специфического для проекта. Например, Automake пишет целевые объекты install и uninstall, Autoconf автоматически определяет возможности системы и настраивает программное обеспечение для его соответствия системе, a Libtool отслеживает различия в управлении совместно используемыми библиотеками на разных системах.
По этим трем инструментам написана целая книга — [41]; здесь мы даем лишь основу, которая понадобится для работы с GNU Autoconf, Automake и Libtool.
4.3. Отладчик GNU
gdb — это отладчик, рекомендуемый Free Software Foundation, gdb представляет собой хороший отладчик командной строки, на котором строятся некоторые инструменты, включая режим gdb в Emacs, графический отладчик Data Display Debugger (http://www.gnu.org/software/ddd/) и встроенные отладчики в некоторых графических интерфейсах IDE. В этом разделе рассматривается только gdb.
Запустите gdb с помощью команды gdb имя_программы. gdb не будет просматривать значение PATH в поисках исполняемого файла. Отладчик загрузит символьную информацию для исполняемого файла и запросит дальнейших действий.
Существует три способа проверить процесс с помощью gdb.
• Используя команду run для обычного выполнения программы.
• Используя команду attach для начала проверки уже запущенного процесса. При подключении к процессу, последний останавливается.
• Исследуя существующий файл ядра для определения состояния процесса при его завершении. Для исследования файла ядра gdb потребуется запустить с помощью команды имя_программы файл_ядра.
Перед запуском программы или подключением к уже запущенному процессу можно установить точку прерывания, просмотреть исходный код и выполнить другие операции, которые не обязательно относятся к запущенному процессу.
gdb не требует написания полного имени команды; указание r достаточно для run, n — для next, s — для step. Более того, для повторения наиболее часто употребляемой команды, нужно просто нажать клавишу <Enter>. Таким образом, пошаговое выполнение программы становится проще.
Ниже предложен небольшой набор полезных команд gdb; gdb включает полное онлайновое руководство в формате GNU info (запустите info gdb), в котором детально объясняются все опции gdb. В [19] содержится неплохое подробное руководство по работе с gdb. gdb также поддерживает оперативную справку, ссылки на которую можно найти внутри gdb; доступ к справочным файлам можно получить, введя команду help. Можно также получить справку по каждой определенной команде, набрав help команда или help тема.
Подобно командам оболочки, команды gdb могут принимать аргументы. "Вызвать help с аргументом команда" означает то же самое, что и "набрать help команда".
Некоторые команды gdb также принимают идентификаторы формата для спецификации вывода значений. Идентификаторы формата располагаются за именем команды и отделяются от него косой чертой. После выбора формата необходимость использовать его каждый раз при повторе команды отпадает; gdb запоминает выбранный формат и использует его по умолчанию.
Идентификаторы формата отделены от команд символом / и состоят из трех элементов: цифра, буква формата и буква, отражающая размер. Цифра и буква размера не обязательны; по умолчанию в качестве цифры устанавливается 1, а размер получает подходящее значение по умолчанию, основанное на букве формата.
Буквы формата следующие: о для обозначения восьмеричного числа, x для шестнадцатеричного числа, d для десятичного числа, и для беззнакового десятичного числа, t для двоичных данных, f для числа с плавающей запятой, а для адреса, i для инструкций, с для символа, s для строки.
Символы, отображающие размер, таковы: b — байт, h — полуслово (2 байта), w — слово (4 байта), g — слово-гигант (8 байт).
attach, at
Подключает отладчик к уже запущенному процессу. Единственным аргументом является идентификатор процесса (pid), к которому осуществляется подключение. Процессы, с которыми установлено подключение, останавливаются, прерывая любые ожидающие или текущие системные вызовы, которые разрешено прерывать. См. detach.
backtrace, bt, where, w
Выводит трассировку стека.
break, b
Устанавливает точку прерывания. Можно указать имя функции, номер строки текущего файла (файл, содержащий выполняемый в данный момент код), пару имя_файла:номер_строки или даже произвольный адрес с помощью *адрес.gdb назначает и выводит уникальный номер для каждой точки прерывания. См. condition, clear и delete.
clear
Удаляет точку прерывания. Принимает такой же аргумент, как break. См. delete.
condition
Изменяет точку прерывания, определенную номером (см. break), для прерывания, только если выражение истинно. Допускаются произвольные выражения.
(gdb) b664
Breakpoint 3 at 0х804а5с0: file ladsh4.c, line664.
(gdb) condition 3 status==0
delete
Удаляет точку прерывания, определенную номером.
detach
Отключается от текущего подключенного процесса.
display
Отображает значение выражения каждый раз при остановке выполнения. Принимает такие же аргументы (включая модификаторы формата), как print. Выводит номер отображения, которое впоследствии может использоваться для отмены отображения. См. undisplay.