MKSHLIB(1) MKSHLIB(1) НАЗВАНИЕ mkshlib - создание разделяемой библиотеки СИНТАКСИС |mkshlib -s файл_спецификаций [-t библ_выполнения] [-h библ_сборки] | [-n] [-L каталог] [-q] ОПИСАНИЕ Команда mkshlib создает как разделяемые библиотеки вы- полнения, так и разделяемые библиотеки сборки. Разделя- емая библиотека очень похожа на обычную, неразделяемую объектную библиотеку, но отличается тем, что программы, собранные с разделяемой библиотекой, будут во время вы- полнения пользоваться одним и тем же экземпляром секций команд библиотечных подпрограмм, тогда как в случае не- разделяемых библиотек в каждом процессе имеется своя копия библиотечных подпрограмм. Разделяемая библиотека сборки - это архив, который ис- пользуется при редактировании связей между программами пользователя и разделяемой библиотекой [см. ar(4)]. С разделяемой библиотекой сборки можно работать точно так же, как и с неразделяемой, она может обычным образом включаться в команду cc(1). Кроме того, все операции, которые можно выполнять над архивом, могут быть выпол- нены и над разделяемой библиотекой сборки. Разделяемая библиотека выполнения - это выполняемый мо- дуль, который присоединяется к процессу пользователя во время выполнения программы, использующей разделяемую библиотеку. Разделяемая библиотека выполнения содержит секции команд всех подпрограмм библиотеки; в ней не должно быть неразрешенных ссылок. Разделяемая библиоте ка выполнения будет загружена в память во время выпол нения программы, использующей разделяемую библиотеку, и другие процессы, использующие ту же библиотеку, будут разделять уже загруженные в память секции команд, но каждый процесс будет иметь свою копию секции данных. Интерфейс пользователя с командой mkshlib состоит из опций командной строки и файла спецификаций, описываю- щего содержимое разделяемой библиотеки. Команда mkshlib производит вызов других программ, таких как ar(1), as(1), ld(1). Обращение к другим программам происходит с помощью системного вызова execvp [см. exec(2)], который ищет нужную программу в каталогах из списка поиска, хранящегося в переменной PATH. Команда mkshlib обрабатывает префиксы так же, как и команда cc(1); все программы, к которым производится обращение, получают тот же префикс. Например, pfxmkshlib вызовет pfxld. Команда mkshlib распознает следующие опции: -s файл_спецификаций Указывает файл спецификаций разделяемой ки. Этот файл содержит информацию, необходимую для построения разделяемой библиотеки. В нем находятся спецификации таблицы переходов для разделяемой библиотеки выполнения, маршрутное имя файла, в ко- тором должна находиться разделяемая библиотека вы- полнения, начальные адреса секции команд и секции данных для разделяемой библиотеки выполнения, спе- цификации инициализации для разделяемой библиотеки сборки и список объектных файлов, которые должны быть включены в разделяемую библиотеку (подробнос- ти см. ниже). -t библ_выполнения Указывает файл, в который будет помещена создавае- мая разделяемая библиотека выполнения. Для того, чтобы воспользоваться разделяемой библиотекой вы- полнения, ее необходимо переместить в то место которое указано в файле спецификации (см. ниже ди- рективу #target). Если используется опция -n, ге- нерации разделяемой библиотеки выполнения не про- изводится. -h библ_сборки Указывает файл, в который будет помещена создава мая разделяемая библиотека сборки. Если эта опци не указана, генерации разделяемой библиотеки сбор- ки не производится. -n Не генерировать разделяемую библиотеку выполнения. Эта опция используется для того, чтобы создать только разделяемую библиотеку сборки. Тем не м нее, следует обязательно указывать и опцию -t, так как для создания разделяемой библиотеки сборки требуется версия разделяемой библиотеки выполне ния. -L каталог ... Изменить алгоритм поиска для разделяемых библиотек сборки, указанных директивой #objects noload, так что поиск вначале производится в указанном катало ге, а только потом в каталогах по умолчанию. Опция -L может быть указана в командной строке несколько раз, при этом каталоги просматриваются в указанном порядке перед поиском в каталогах по умолчанию. -q Не выдавать предупреждающих сообщений. Эта опция используется, если известно, что будет выдано мно- жество ненужных предупреждений. Файл спецификаций разделяемой библиотеки содержит ин формацию, необходимую для создания как разделяемой биб- лиотеки сборки, так и разделяемой библиотеки выполне- ния. Содержимое и формат файла спецификаций задается директивами, перечисленными ниже. Каждая директива, за которой может следовать несколько строк спецификаций, действует до тех пор, пока не за- кончится файл или не встретится другая директива. #address секция адрес Указывает начальный адрес секции разделяемой биб- лиотеки выполнения. Эта директива обычно использу- ется для задания начальных адресов секций .text и .data. #target маршрутное_имя Задает маршрутное_имя разделяемой библиотеки вы- полнения во время ее использования. Указанное имя записывается в файлы типа a.out(4), обращающиеся к разделяемой библиотеке, и служит операционной сис- теме для поиска разделяемой библиотеки, когда она требуется выполняемому файлу. #branch Указывает на начало спецификаций таблицы перехо дов. Строки, следующие за этой директивой, тракту ются как строки спецификации таблицы переходов. Строки спецификации таблицы переходов имеют следу- ющий формат: |имя_функции пробел_или_табуляция позиция где имя_функции - это имя, для которого задается точка входа в таблицу переходов, а позиция задает позицию этой точки входа. Позиция может быть целым числом или диапазоном целых чисел в формате пози ция1-позиция2. Каждая позиция должна быть не мень- ше 1; одна и та же позиция не может быть указана дважды; в таблице переходов не должно быть пропу- щенных позиций (каждое число от 1 до некоторого максимального должно быть обязательно задействова но). Если для имени выделяется более одной точки входа путем спецификации для него диапазона позиций или путем указания одного и того же имени в разных строках спецификации таблицы переходов, то исполь- зуется максимальная из выделенных позиций. Все ос- тальные позиции таблицы переходов могут рассматри ваться как пустые, в которые в новых версиях раз деляемой библиотеки могут быть занесены новые функции. #objects Указывает имена объектных модулей, составляющих разделяемую библиотеку выполнения. Строки, следую- щие за этой директивой, рассматриваются как список объектных файлов, в том порядке, в котором они должны быть загружены в разделяемую библиотеку вы- полнения. Список состоит из имен файлов, разделяе мых пробелами или табуляциями. Этот же список ис пользуется для определения объектных файлов для разделяемой библиотеки сборки, но порядок их в разделяемой библиотеке сборки определяется пропус- ком списка через lorder(1) и tsort(1). Эта дирек тива может встретиться в файле спецификаций разде- ляемой библиотеки только однажды. #objects noload За данной директивой следует список имен разделяе- мых библиотек сборки. Эти библиотеки просматрива ются в том порядке, в котором они указаны, для разрешения ссылок из создаваемой разделяемой биб лиотеки. При этом ситуация, когда неразделяемая версия объекта обнаруживается раньше разделяемой, трактуется как ошибочная. Имя разделяемой библиотеки сборки задается как маршрутное имя файла или как аргумент вида -lX, где libX.a является именем файла в каталоге LIBDIR или LLIBDIR. Описываемая ситуация аналогична ситу- ации с ld(1), и для задания других каталогов поис- ка библиотек можно воспользоваться опцией -L. Отметим, что если с помощью директивы #objects noload указана разделяемая библиотека сборки, то в каждой команде cc, редактирующей связи с создавае- мой разделяемой библиотекой, нужно также задавать упомянутую разделяемую библиотеку сборки. #hide linker [*] Эта директива делает внешние имена локальными для создаваемой разделяемой библиотеки. В последующих строках могут задаваться регулярные выражения [см. sh(1), find(1)], и если внешнее имя соответствует хотя бы одному из выражений, оно становится ло- кальным. Оставить некоторые имена внешними можно с помощью директивы #export (см. ниже). Необязатель- ный аргумент * эквивалентен последовательности |#hide linker | * и приводит к тому, что все внешние имена становят- ся локальными. Все имена, использованные в директивах #init и #branch, всегда являются внешними и не могут быть сделаны локальными с помощью директивы #hide. #export linker [*] В последующих строках могут задаваться внешние имена, которые из-за соответствия регулярным выра- жениям директивы #hide могли бы стать локальными. Например, последовательность директив |#hide linker * |#export linker |one |two приводит к тому, что все имена, кроме one и two, а также тех, которые упомянуты в директивах #init и #branch, становятся локальными. #init объектный_файл Указывает объектный файл, который требует инициа- лизации. Строки, следующие за этой директивой, рассматриваются как строки спецификации инициали- зации, которые должны иметь следующий формат: |указатель пробел_или_табуляция имя где указатель - это указатель на внешнее имя; ука- затель должен быть определен в объектном_файле. Для каждой такой строки генерируются команды ини- циализации вида: |указатель=&имя; Повторная инициализация указателей не допускается, так же, как и повторное использование директивы #init для того же объектного_файла. #ident цепочка_символов Задает цепочку_символов, которая будет включена в секцию комментариев (.comment) разделяемой библио- теки выполнения. ## Комментарий. Строки, начинающиеся с ##, игнориру- ются. ФАЙЛЫ LIBDIR Обычно /lib. LLIBDIR Обычно /usr/lib. TMPDIR/* Временные файлы. Обычно каталог TMPDIR - это /usr/tmp, однако данное соглашение можно изменить, присвоив переменной окруже- ния TMPDIR другое значение [см. tempnam( ) в tmpnam(3S)]. СМ. ТАКЖЕ ar(1), as(1), cc(1), ld(1), lorder(1), tsort(1). a.out(4), ar(4) в Справочнике программиста. ОГРАНИЧЕНИЯ Опцию -n нельзя использовать одновременно с директивой #objects noload. Если указать разделяемую библиотеку сборки, которая уже существует, то mkshlib обновит ее с помощью команды ar -ru. Следовательно, если удаляется или переименовывается объектный файл, включенный в раз- деляемую библиотеку сборки, то перед обновлением нужно обязательно удалить разделяемую библиотеку сборки.@