logo search
Подбельский Фомин_Программирование на языке СИ_

Создание и сопровождение собственных библиотек.

Создание и сопровождение собственных библиотек. В UNIX для создания и сопровождения библиотек объектных модулей служит программа ar (archivator - архиватор). Для библиотек в UNIX принят термин "архив"; отсюда в качестве расширения имени библиотеки используется буква 'а'.

При создании библиотеки необходимо иметь в виду, что компоновщик просматривает библиотечный файл только один раз. Если объектный модуль функции ссылается на другие имена из той же библиотеки, то он должен быть расположен в библиотеке до этих объектных модулей. Некоторые версии UNIX содержат программу ranlib, которая создает оглавление библиотеки, что позволяет компоновщику ld обращаться к элементам библиотеки в произвольном порядке. В других версиях UNIX (например, UNIX System V) функция построения оглавления библиотеки встроена в программы аr и ld.

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

аr - ключ [ключ...] [позиционное_имя] архив имя. . .

Параметры в команде отделяются пробелами.

Параметр позиционное_имя не является обязательным. Ключей может быть несколько, тогда они записываются без пробелов и только с одним знаком '-'.

Параметр архив задает имя архивного файла.

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

Ключи программы аr имеют следующий смысл:

-d - исключить указанные (с помощью параметра имя...) файлы из архивного файла;

-r -заменить указанные (параметром имя...) файлы в архивном файле. Если вместе с ключом r задается необязательный ключ u, то заменяются только файлы, имеющие более поздние даты модификации, чем файлы в архиве. Этот же ключ используется для включения в библиотеку новых файлов, т.е. файлы, указанные параметром имя... и отсутствующие в библиотеке, добавляются в архив. Обычно новые файлы помещаются в конец архива. Если указать имя файла из архива в параметре позиционное_имя, то можно новые файлы поместить до или после этого файла. Для этого необходимо соответственно добавить к ключу -r необязательные литеры b (before) или a (after);

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

- вывести в стандартный поток вывода указанные (параметром имя...) файлы из архива;

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

-v - выдавать пояснительные сообщения;

- создать архивный файл. Обычно программа аr при необходимости создает архивный файл сама. Данный ключ подавляет информационное сообщение, выдаваемое при создании архивного файла.

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

Здесь libtree.a - имя библиотеки (архивного файла).

Ключ -r задает режим замены объектных модулей, хранящихся в библиотеке, на объектные модули, список которых приведен в командной строке вызова архиватора аr после имени библиотеки. Так как в момент обработки указанной команды библиотеки не существовало, она будет создана автоматически. Ключ -v определяет режим вывода пояснительных сообщений о работе архиватора аr.

После занесения объектных модулей в библиотеку необходимо при помощи программы ranlib скорректировать (или создать) оглавление библиотеки, выполнив команду

Программа ranlib впервые появилась в версии 7 UNIX фирмы AT&T и существует в таких реализациях операционной системы UNIX, как FreeBSD и Solaris. Рекомендуется при работе в других реализациях UNIX ознакомиться со справочной литературой, в которой описывается работа с библиотеками. Наиболее простой способ получения информации о наличии программы ranlib в составе ОС состоит в поиске этой программы в каталогах /bin, /usr/bin, /etc. Если эта программа найдена, прочтите ее описание, которое можно получить на экране дисплея по "самой полезной" команде ОС UNIX - команде man, позволяющей быстро получить справку по многим компонентам, командам и программам UNIX. Например, справку о программе ranlib можно получить так:

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

Первая строка - вызов программы-архиватора (аr). Последние 4 строки - это результат работы команды аr. Оглавление библиотеки содержится в разделе библиотеки__.SYMDEF. Остальные строки - это имена объектных модулей, находящихся в библиотеке. После того как библиотека объектных модулей создана, можно построить исполняемый модуль программы сортировки на основе бинарного дерева с помощью команды:

Здесь транслируется головной модуль (tree.c), объектные модули на этапе компоновки выбираются из библиотеки libtree.a, и строится исполняемая программа с именем tree. Ключ компоновщика -l позволяет задать имя библиотеки объектных модулей (полное имя библиотеки: libtree.a).

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

На этот раз нет необходимости в повторной трансляции головного модуля (он не подвергался правке), поэтому в последней строке задано имя уже существующего объектного модуля tree.о.

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

Обратите внимание, как указаны зависимость целевого файла tree от библиотеки libtree.a и, в свою очередь, ее зависимость от объектных модулей. Объектный модуль из библиотеки libtree.a указывается так:

имя_библиотеки(имя_модуля).

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

$@ - задает имя текущего целевого файла (в нашем случае - последнего (libtree.a));

$? - значение этого макроса вычисляется командой make - это имена всех модулей, которые подвергались изменениям.

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

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

После внесения изменений, например, в исходный текст функции new_node( ) и при выполнении команды make получим на экране дисплея следующий протокол:

Строка, следующая за командой вызова архиватора аr (r -new_node.o), - это сообщение архиватора о замене объектного модуля new_node.o в библиотеке libtree.a.