Использование библиотек объектных файлов
Каждый элемент такой библиотеки (например, библиотеки libc.a) является полноценным объектным файлом. Команда ar(1) создает библиотеки из объектных файлов, генерируемых компиляторами. Библиотеки обрабатываются редактором связей избирательно: используются только те элементы, которые разрешают внешние ссылки. Библиотеки могут упоминаться как внутри предложений, определяющих секции, так и вне их. В обоих случаях объектный файл - элемент библиотеки используется для редактирования внешних связей, если выполнены следующие два условия:
- Существует неразрешенная ссылка на имя, определенное в этом файле.
- Такая ссылка обнаружена ld(1) до завершения просмотра библиотеки.
При использовании элемента библиотеки, просматриваемой в процессе обработки предложения SECTIONS, все входные секции из этого объектного файла помещаются в ту выходную секция, которая создается в этом предложении. Если же элемент используется при просмотре библиотеки, упомянутой вне предложения SECTIONS, то каждая входная секция из этого объектного файла помещается в одноименную выходную. В последнем случае, если это необходимо, создаются новые выходные секции.
Необходимо запомнить следующее:
- В предложениях управляющего языка редактора связей можно указать только библиотеку целиком, но не отдельные элементы.
- Не существует способа изменить изложенные выше подразумеваемые правила редактирования связей элементов библиотек объектных файлов и их секций.
Опция -l используется как средство сокращения записи при спецификации входных файлов, принадлежащих предопределенному набору каталогов и имеющих предопределенные имена. Обычно таким образом задаются библиотеки, хотя это и не обязательно. Библиотеки объектных файлов могут быть указаны и без опции -l просто путем задания их маршрутных имен.
Важен порядок указания библиотек, так как из них извлекаются лишь те элементы, на которые есть неразрешенные ссылки к моменту просмотра библиотеки. ld(1) просматривает находящуюся в начале библиотеки объектных файлов таблицу имен несколько раз, пока не обнаружит, что никакие внешние ссылки не могут более быть разрешены за счет элементов этой библиотеки.
Рассмотрим следующий пример:
- В каждом из входных файлов file1.o и file2.o есть ссылки на внешнюю функцию FCN.
- Входной файл file1.o содержит ссылку на внешнее имя ABC.
- Входной файл file2.o содержит ссылку на внешнее имя XYZ.
- Элемент 0 библиотеки liba.a содержит определение имени XYZ.
- Элемент 0 библиотеки libc.a содержит определение имени ABC.
- В обеих библиотеках в элементе 1 определяется функция FCN.
Пусть командная строка с вызовом ld(1) выглядит следующим образом:
ld file1.o -la file2.o -lc
Тогда ссылки на FCN разрешаются элементом 1 библиотеки liba.a, ссылка на ABC - элементом 0 библиотеки libc.a, а ссылка на XYZ
остается неразрешенной, так как библиотека liba.a просматривается раньше редактирования связей файла file2.o. Если же команда ld вводится таким образом:
ld file1.o file2.o -la -lc
то ссылки на FCN и ABC разрешаются как в предыдущем примере, а ссылка на XYZ разрешается элементом 0 библиотеки liba.a. Пусть, наконец, команда ld(1) введена так:
ld file1.o file2.o -lc -la
Отличие от предыдущего примера выразится в том, что для разрешения ссылки на FCN будет извлечен элемент 1 библиотеки libc.a, а не liba.a.
Опция -u используется, чтобы вызвать принудительное редактирование связей тех элементов библиотек, на которые, быть может, нет реально существующих внешних ссылок. Например, в случае вызова
ld -u rout1 -la
создается неопределенное имя rout1 и, если в каком-либо объектном файле библиотеки liba.a это имя определяется, то этот файл (а с ним, быть может, и некоторые другие) извлекается для редактирования связей. Без опции -u ld(1) не просматривал бы библиотеку вообще ввиду отсутствия неразрешенных ссылок и неопределенных имен.