Чтение онлайн

ЖАНРЫ

Внутреннее устройство Linux
Шрифт:

• test или check. Некоторые разработчики предусматривают цели test или check, чтобы убедиться в том, что все работает после выполнения сборки.

• depend. Создает зависимости, вызывая компилятор с параметром -M для проверки исходного кода. Эта цель выглядит необычно, поскольку часто она изменяет сам файл Makefile. Это больше не является общепринятой практикой, но, если вам встретятся инструкции, в которых говорится об использовании этого правила, следуйте им.

• all. Часто является первой целью в файле Makefile. Вам много раз будут попадаться ссылки на эту цель, а не на исполняемый файл.

15.2.8. Устройство файла Makefile

Несмотря на то что существуют различные

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

MYPACKAGE_INCLUDES=-I/usr/local/include/mypackage

MYPACKAGE_LIB=-L/usr/local/lib/mypackage -lmypackage

PNG_INCLUDES=-I/usr/local/include

PNG_LIB=-L/usr/local/lib -lpng

Каждый тип флагов компилятора и компоновщика часто оформляется в виде таких макроопределений:

CFLAGS=$(CFLAGS) $(MYPACKAGE_INCLUDES) $(PNG_INCLUDES)

LDFLAGS=$(LDFLAGS) $(MYPACKAGE_LIB) $(PNG_LIB)

Объектные файлы обычно группируются в соответствии с исполняемыми файлами. Допустим, например, что у вас есть пакет, который создает исполняемые файлы boring и trite. У каждого из них есть файл .c с исходным кодом и необходимый код в файле util.c. Вы можете увидеть нечто вроде следующего:

UTIL_OBJS=util.o

BORING_OBJS=$(UTIL_OBJS) boring.o

TRITE_OBJS=$(UTIL_OBJS) trite.o

PROGS=boring trite

Остальная часть файла Makefile могла бы выглядеть так:

all: $(PROGS)

boring: $(BORING_OBJS)

$(CC) -o $@ $(BORING_OBJS) $(LDFLAGS)

trite: $(TRITE_OBJS)

$(CC) -o $@ $(TRITE_OBJS) $(LDFLAGS)

Вы могли бы скомбинировать две цели для исполняемых файлов в виде одного правила, но обычно так поступать не следует, поскольку вам было бы непросто перенести правило в другой файл Makefile и удалить исполняемый файл или группу исполняемых файлов в отдельности. Более того, зависимости стали бы некорректными: если бы у вас было лишь одно правило для файлов boring и trite, файл trite зависел бы от файла boring.c, файл boring — от файла trite.c, и утилита make всегда пыталась бы собрать заново обе программы, если вы изменили один из файлов с исходным кодом.

примечание

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

15.3. Отладчики

Стандартным отладчиком в системах Linux является gdb; доступны также системы с дружественным к пользователю интерфейсом, например Eclipse IDE и Emacs. Чтобы включить полную отладку ваших программ, запустите компилятор с параметром -g для записи таблицы имен и другой отладочной информации в исполня­емый файл. Чтобы запустить отладчик gdb для исполняемого файла program, выполните такую команду:

$ gdb program

Вы должны получить приглашение (gdb). Чтобы запустить программу program с параметром командной строки options, введите следующую команду после приглашения отладчика:

(gdb) run options

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

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

(gdb) print variable

Чтобы отладчик остановил программу в указанном месте исходного кода, используйте контрольные точки. В следующей команде файл file является файлом с исходным кодом, а параметр line_num — это номер строки этого файла, в которой отладчик должен остановиться:

(gdb) break file:line_num

Для продолжения отладки выполните такую команду:

(gdb) continue

Чтобы удалить контрольную точку, введите команду:

(gdb) clear file:line_num

Этот раздел содержит только краткое введение в отладчик gdb в надежде на то, что вы изучите более полное руководство, онлайн или в печатном виде, например 10-е издание книги Ричарда М. Столлмана (Richard M. Stallman) и др. Debugging with GDB («Отладка с помощью GDB», GNU Press, 2011). Еще одним руководством по отладке является книга Нормана Матлофа (Norman Matloff) и Питера Джея Зальцмана (Peter Jay Salzman) The Art of Debugging («Искусство отладки», No Starch Press, 2008).

примечание

Если вам интересно выявление проблем в памяти и запуск профильных тестов, посетите сайт проекта Valgrind .

15.4. Инструменты Lex и Yacc

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

• Lex — это разметчик (tokenizer), который переводит текст в пронумерованные теги с ярлыками. Версия GNU/Linux для этого инструмента называется flex. Для его совместной работы с компоновщиком могут потребоваться флаги -ll или -lfl.

• Yacc — это синтаксический анализатор, который пытается считывать метки в соответствии с грамматикой. Анализатор GNU называется bison; для его совместимости с Yacc запустите команду bison -y. Может потребоваться флаг компоновщика -ly.

15.5. Языки сценариев

В давние времена обычному системному администратору Unix не приходилось особенно беспокоиться насчет других языков сценариев, кроме Bourne shell и awk. Сценарии оболочки (рассмотренные в главе 11) по-прежнему остаются важной частью системы Unix, но язык awk понемногу сходит со сценарной арены. В то же время появились его мощные наследники, и теперь многие системные команды созданы не на языке C, а на языках сценариев (например, практичная версия команды whois). Рассмотрим некоторые основы сценариев.

Для начала вам необходимо знать о любом языке сценариев следующее: первая строка сценария выглядит так же, как и в сценарии оболочки Bourne shell. Например, сценарий на языке Python начинается так:

#!/usr/bin/python

Или так:

#!/usr/bin/env python

В Linux любой исполняемый текстовый файл, начинающийся символами #!, является сценарием. Путь, который следует за этим префиксом, представляет исполняемый файл интерпретатора языка сценариев. Когда Unix пытается запустить исполняемый файл, который начинается с символов #!, она выполняет следующую за ним команду, используя оставшуюся часть файла как стандартный ввод. Следовательно, даже такой код является сценарием:

Поделиться с друзьями: