Linux: Полное руководство — страница 73 из 98

Последовательность команд — это команды, которые нужно выполнить для достижения цели. Последовательность команд должна отделяться от начала строки символом табуляции, иначе вы получите ошибку «missing separator» (нет разделителя).

Make-файл может содержать комментарии — они начинаются символом #.

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

CC=gcc

PATH=/usr/include /usr/src/linux/include

MODFLAGS:= -O3 -Wall -DLINUX -I$(PATH)

...

$(CC) $(MODFLAGS) -c proga.c

Чтобы обратиться к макроопределению в команде или в другом макроопределении, нужно использовать конструкцию $(имя). Макроопределение может включать в себя другое, ранее определенное, макроопределение.

Формат запуска утилиты make:

make [-f файл] [ключи] [цель]

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

Примечание

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

Работа программы make заканчивается, когда достигнута цель, указанная в командной строке. Обычно это цель all, собирающая все результирующие файлы проекта. Другими распространенными целями являются install (установить собранную программу) и clean (удалить ненужные файлы, созданные в процессе сборки).

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

Листинг 21.2. Примерный make-файл

CC=gcc

CFLAGS=-O


all: client server


client: client.с

$(CC) client.с -о client


server: server.с

$(CC) server.с -о server

Обычно при вызове утилиты make не нужно задавать никаких ключей. Но иногда использование ключей бывает очень кстати (таблица 21.1).


Ключи команды make Таблица 21.1

КлючНазначение
-C каталогПерейти в указанный каталог перед началом работы
-dВывод отладочной информации
-eПриоритет переменным окружения. Если у нас установлена переменная окружения CC и в Makefile есть переменная с таким же именем, то будет использована переменная окружения
-f файлИспользовать указанный файл вместо Makefile
-iИгнорировать ошибки компилятора
-I каталогВ указанном каталоге будет производиться поиск файлов, включаемых в Makefile
-j nЗапускать не более n команд одновременно
-kПродолжить работу после ошибки, если это возможно
-nВывести команды, которые должны были выполниться, но не выполнять их
-о файлПропустить данный файл, даже если в Makefile указано, что он должен быть создан заново
-rНе использовать встроенные правила
-sНе выводить команды перед их выполнением
-wВывод текущего каталога до и после выполнения команды

21.3. Пакет binutils и другие полезные программы

Пакет

binutils
содержит утилиты для работы с бинарными файлами:

ld — компоновщик: программа, связывающая объектные файлы и библиотеки в исполняемый файл;

ar — работа с архивами (создания, модификация и извлечение);

nm — вывод названий идентификаторов из двоичных файлов;

objcopy — копирование и трансляция двоичных файлов;

objdump — вывод информации из двоичных файлов;

ranlib — генерирование индекса оглавления архива;

size — вывод размеров секций архива или двоичного файла;

strings — вывод строк, которые возможно прочитать, из двоичных файлов;

addr2line — конвертирование адресов в памяти в строку в файле;

nlmconv — конвертирует объектный код в NLM.

А теперь перечислим несколько полезных вспомогательных программ.

21.3.1. ansi2knr

Утилита ansi2knr предназначена для преобразования текстов программ, написанных в соответствии со стандартом ANSI С, в программы на «классическом» С Кернигана и Ричи. Формат вызова:

ansi2knr oldfile.c newfile.c

21.3.2. as

Программа as — это GNU-версия ассемблера, предназначенная для создания объектных файлов из программ, написанных на языке ассемблера. Формат вызова:

as [ключи] файл1 [файл2 ... файлN]


Ключи программы as Таблица 21.2

КлючНазначение
Вывод листинга
-adHe выводить отладочные сообщения
-adВключение в листинг текста программы, написанной на языке высокого уровни, если компиляций проводилась с ключом -g
-alВывод листинга на ассемблере
-anНе обрабатывать форм
-asВывод списка символов программы
-aфайлВывести листинг в указанный файл
-fБыстрый режим. Директивы препроцессора не обрабатываются
-iпутьДобавить указанный путь к Include-пути
-MRIОбеспечить MRI-совместимость
-о файлСоздание объектного файла с указанным именем
-RПоместить сегмент данных в сегмент кода
-vВывод версии
-WНе выводить предупреждения

21.3.3. bison

Программа bison — это грамматический разборщик (парсер): она создает C-программу, предназначенную для разбора определенной грамматики. Данная программа вам не понадобится до тех пор, пока вы не захотите написать собственный компилятор. Ключи программы представлены в таблице 21.3. Формат вызова:

bison [ключи] файл


Ключи программы bison Таблица 21.3

КлючНазначение
-b префиксИспользовать указанный префикс для имени входящего файла
-dСоздать заголовочный файл, содержащий информацию о типах грамматических образцов (токенов), которые определены в вашей грамматике
-IНе вставлять код в существующие файлы
-о файлУстановить файл результата
-tВключить отладочную информацию
-vЗаписать созданную программу в файл у.out put

21.3.4. flex

flex [параметры] файл

Это еще одна программа, которая пишет код за нас. Flex может написать программу на языке С, которая будет искать заданные образны текста в текстовых файлах и выполнять определенные действия, заданные программистом. Если вам нужна эта программа, тогда самое время прочитать страницы руководства man flex.

21.3.5. gprof

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

21.3.6. strip

Утилита strip удаляет таблицу символов из объектного файла.

21.4. Пример программы на С

В п. 9.2.3 я сказал о состояниях процесса и перечислил среди них состояние «зомби». Зомби — это процесс, который уже завершился, но его родитель еще не получил сигнала о его завершении и не удалил его структуру из таблицы процессов. Такое может произойти, когда процесс-родитель почему-либо не готов к завершению потомка. Сейчас мы искусственно создадим такого зомби. Процесс-родитель породит потомка и уснет на 10 секунд. Потомок завершится через 2 секунды, а в течение 8 секунд он будет находиться в состоянии зомби. Напоминаю, что состояние процесса можно увидеть по команде top.

Листинг 21.3. Файл zombie.с

#include 

#include 

#include