книги / Программирование на языке Си
..pdf454 |
Программирование на языке Си |
Примечание. Если список имен файлов, от которых зависит целевой файл, не умещается на одной строке, для обозначе ния переноса части списка на другую строку можно восполь зоваться символом 'V, например:
tree: tree.о \ add_node.o \ ne\v_node.o \ print.o
команды UNIX
Формат команды make. Команда make имеет следующий формат:
make [-f таке/11е][ключи\[имена\[макро_определения\
Квадратные скобки, выделяющие параметры, означают их необязательность. Параметры в команде отделяются друг от друга пробелами.
Первый параметр с ключом - f задает имя файла зависимо стей модулей, если это имя отлично от makefile или Makefile.
Из множества ключей, определяющих режим работы коман ды make, упомянем следующие, необходимые для отладки wafe-файла:
-р - вывести в стандартный поток вывода полный список зависимостей модулей;
-i - игнорировать коды возврата выполненных команд (позволяет отладить сложный make-фанп);
-п - вывести в стандартный поток вывода строки с коман дами UNIX, не выполняя их.
Параметр имена позволяет задавать имена целевых файлов. Коротко остановимся на некоторых возможностях команды
make, которые не используются в нашем примере.
Макроопределения. Команда make позволяет использовать при записи спецификаций взаимозависимостей макроопределе ния. Это дает возможность добиться большей наглядности фай ла описаний взаимозависимостей и использовать один и тот же файл описаний для различных имен целевых файлов и файлов, от которых зависит целевой файл.
Глава 9. Подготовка и выполнение программ |
455 |
Макроопределения записываются в соответствии со сле дующим форматом:
имямакроса = значение
где имя макроса - имя макроса команды make;
значение - строка символов, которая подставляется вме сто конструкции %(имя_макроса) при ее использовании в стро ках файла взаимозависимостей.
Пример макроопределения:
СС=сс
После такого макроопределения контекст вида $(СС) будет заменен в строках таке-файла на сс.
Введем в качестве первой строки в приведенный выше файл описаний взаимозависимостей для целевого файла tree следую щее макроопределение:
OBJECTS=tree.о add_node.о new_node.о print.о
Тогда позже в том же файле для указания объектных моду лей, перечисленных справа от знака равенства, можно приме нять конструкцию $(OBJECTS).
Теперь файл взаимозависимостей для программы сортировки на основе бинарного дерева будет выглядеть так:
OBJECTS=add_node.о new_node.о print.о
tree: tree.о $ (OBJECTS)
сс-о tree tree.с S(OBJECTS)
Встроенные правила. В процессе выполнения команда make использует набор так называемых встроенных правил. Одним из подмножеств этого набора являются правила автома тического установления взаимосвязей между файлами по суф фиксам их имен. Например, когда в команде make в качестве параметра задано имя файла с суффиксом '.с', автоматически выполняется вызов компилятора языка Си, который строит ис полняемый модуль из исходного модуля, находящегося в задан ном файле. Таблицу встроенных правил команды make, соответствующих конкретной реализации UNIX, можно найти в
456 |
Программирование на языке Си |
документации по операционной системе. Здесь стандартные встроенные правила мы рассматривать не будем.
Программист может изменить встроенное правило, для чего новый вариант правила необходимо включить в файл описаний зависимостей, т.е. во входные данные для make.
Простейшее правило, описывающее процедуру подготовки исполняемого модуля из исходного модуля (расширение имени 'с', суффикс имени '.с'), будет выглядеть так:
. с :
сс |
-о |
$@ |
$*.с |
где |
$@ |
- внутренний макрос команды make, предназначен |
|
ный для спецификации полного имени целевого файла; |
|||
|
$* |
- внутренний макрос, определяющий префикс име |
ни файла.
Это правило, включенное в файл описаний зависимостей мо дулей, заменит внутреннее правило команды make для суффик са '.с'
Если теперь ввести команду make с указанием имени целе вого файла (исполняемой программы)
%mak.e prog
то исходный файл prog.c будет скомпилирован, а исполняемый модуль получит имя prog.
С помощью команды make может быть решено множество задач, связанных с программированием как на языках высокого уровня, так и на командных языках, например, на командном языке UNIX (sh, csh, ksh,...). Однако основное применение make - учет взаимозависимостей между исходными текстами модулей в больших программных комплексах.
9.1.2. Библиотеки объектны х модулей
При разработке программной системы объектные модули функций, входящих в ее состав, целесообразно размещать в библиотеках объектных модулей, а в командной строке вызова компилятора указывать эти библиотеки. Использование библио-
Глава 9. Подготовка и выполнение программ |
457 |
тек позволяет не задавать непосредственно в командной строке все необходимые для построения исполняемой программы объ ектные модули. Компоновщик на этапе построения исполняе мой программы будет выбирать из библиотеки только те объек тные модули функций, которые необходимы.
Стандартные библиотеки. Стандартные библиотеки UNIX хранятся в каталогах /ИЬ или /usr/lib. Ссылка на библиотеки осуществляется при помощи ключа компоновщика -1, который задается в команде сс вызова компилятора языка Си после всех ключей и параметров компилятора. Непосредственно за ключом (без пробела) указывается идентификатор библиотеки, например
%с с |
. . . . |
- 1 х |
где х - |
часть имени библиотеки (полное имя библиотеки в дан |
ном случае libx.a; стандартный префикс для библиотеки "lib"; стандартное расширение имени для библиотеки 'а'). Обратите внимание, что libx.a есть название библиотеки, а не отдельного модуля, поэтому суффикс '.а' не обозначает "модуль на ассемб лере", как, например, на рис. 9.2.
Стандартная библиотека языка Си просматривается компо новщиком автоматически, т.е. указание этой библиотеки в ко мандной строке вызова компилятора Си не требуется. Эта биб лиотека хранится в файле /НЬ/ИЬс.а.
Библиотека математических функций хранится в файле /НЬ/ПЬш.а, поэтому указание библиотеки в команде вызова ком пилятора будет таким: -1т. Напомним, что ключ -1, являющий ся ключом компоновщика, необходимо разместить в командной строке вызова компилятора Си после всех других ключей и па раметров, так как просмотр библиотеки должен происходить после компиляции, когда становится известно, какие функции из библиотеки нужны для построения исполняемого модуля.
Создание и сопровождение собственных библиотек. В UNIX для создания и сопровождения библиотек объектных мо дулей служит программа ar (atchivator - архиватор). Для биб лиотек в UNIX принят термин "архив"; отсюда в качестве расширения имени библиотеки используется буква 'а'.
458 |
Программирование на языке Си |
При создании библиотеки необходимо иметь в виду, что компоновщик просматривает библиотечный файл только один раз. Если объектный модуль функции ссылается на другие име на из той же библиотеки, то он должен быть расположен в биб лиотеке до этих объектных модулей. Некоторые версии UNIX содержат программу ranlib, которая создает оглавление биб лиотеки, что позволяет компоновщику Id обращаться к элемен там библиотеки в произвольном порядке. В других версиях UNIX (например, UNIX System V) функция построения оглав ления библиотеки встроена в программы аг и Id.
Главное назначение программы аг - создание и обновление библиотечных файлов, используемых компоновщиком, однако ее можно применять и для любых других аналогичных целей. Формат команды аг:
аг -ключ [ключ...] [позиционное имя] архив имя. . .
Параметры в команде отделяются пробелами.
Параметр позиционное имя не является обязательным. Клю чей может быть несколько, тогда они записываются без пробе лов и только с одним знаком
Параметр архив задает имя архивного файла.
Параметр имя... является списком имен объектных модулей, которые либо находятся в архиве, либо должны быть туда по мещены.
Ключи программы аг имеют следующий смысл:
-d -исключить указанные (с помощью параметра имя...) файлы из архивного файла;
-г -заменить указанные (параметром имя...) файлы в ар хивном файле. Если вместе с ключом г задается необя зательный ключ и, то заменяются только файлы, имеющие более поздние даты модификации, чем фай лы в архиве. Этот же ключ используется для включе ния в библиотеку новых файлов, т.е. файлы, указанные параметром имя... и отсутствующие в библиотеке, до бавляются в архив. Обычно новые файлы помещаются
вконец архива. Если указать имя файла из архива в
Глава 9. Подготовка и выполнение программ |
459 |
параметре позиционное имя, то можно новые файлы поместить до или после этого файла. Для этого необ ходимо соответственно добавить к ключу -г необяза тельные литеры b (before) или a (after);
-t - вывести в стандартный поток вывода оглавление ар хивного файла. При задании параметра имя... печата ется информация только об указанных этим парамет ром файлах. Этот же ключ используется для включе ния в библиотеку новых файлов, т.е. файлы, указанные параметром имя... и отсутствующие в библиотеке, до бавляются в архив;
-р - вывести в стандартный поток вывода указанные (параметром имя...) файлы из архива;
-х - извлечь из архива указанные (параметром имя...) фай лы. Если не задан параметр имя..., из архива извлека ются все файлы. В любом случае собственно архивный файл не изменяется;
-v - выдавать пояснительные сообщения;
-с - создать архивный файл. Обычно программа аг при необходимости создает архивный файл сама. Данный ключ подавляет информационное сообщение, выда ваемое при создании архивного файла.
Для размещения в личной библиотеке объектных модулей функций программы сортировки на основе бинарного дерева (из гл. 8) необходимо выполнить следующую команду:
%ar -rv libtree.a add_node.o new_node.o print.о
Здесь libtree.a - имя библиотеки (архивного файла).
Ключ -г задает режим замены объектных модулей, храня щихся в библиотеке, на объектные модули, список которых приведен в командной строке вызова архиватора аг после имени библиотеки. Так как в момент обработки указанной команды библиотеки не существовало, она будет создана автоматически. Ключ -v определяет режим вывода пояснительных сообщений о работе архиватора аг.
462 |
Программирование на языке Си |
Обратите внимание, как указаны зависимость целевого файла tree от библиотеки Iibtree.a и, в свою очередь, ее зависимость от объектных модулей. Объектный модуль из библиотеки Iibtree.a указывается так:
имя_библиотеки(имямодуля).
Для окончательного оформления таке-$гмп& используем два встроенных макроса команды make:
$@ - задает имя текущего целевого файла (в нашем случае - последнего (Iibtree.a));
$? - значение этого макроса вычисляется командой make - это имена всех модулей, которые подвергались изменениям.
Приведем один из вариантов полного текста таке-файла (напомним, что его имя по умолчанию - makefile), позволяю щего обновлять целевые файлы (исполняемую программу и библиотеку объектных модулей) в соответствии с изменениями в исходных текстах функций, входящих в состав программы сортировки на основе бинарного дерева:
tree: tree.о \ add_node.о \ new_node.о \ print.о \ libtree.а
Iibtree.a: libtree.a(add_node.о) \ libtree.a(new_node.о) \ libtree.a(print.о)
ar |
-rv |
$@ |
$? |
|
ranlib |
$0 |
tree.с |
-ltree |
|
сс |
-о |
tree |
Теперь для того, чтобы построить исполняемый модуль, учи тывающий все внесенные изменения в любые функции про граммы сортировки, необходимо просто набрать на клавиатуре команду make.
После внесения изменений, например, в исходный текст функции new_node() и при выполнении команды make получим на экране дисплея следующий протокол: