Почему опция -r (перемещаемая) заставляет ld не находить библиотеки? - PullRequest
5 голосов
/ 04 июля 2011

Запуск Debian / Linux x86_64 с GNU ld 2.21.

Проще говоря, если я связываюсь с

ld -o main main.o /usr/lib/crti.o /usr/lib/crt1.o /usr/lib/crtn.o -lc -lm

Это работает, но когда я связываюсь с

ld -r -o main1.o main.o /usr/lib/crti.o /usr/lib/crt1.o /usr/lib/crtn.o -lc -lm

Он жалуется

ld: cannot find -lc
ld: cannot find -lm

На самом деле я не пытаюсь скомпилировать код таким образом, а скорее пытаюсь выяснить, почему не работает чужой тест, чтобы увидеть, существует ли библиотека.(Таким образом, я не совсем понимаю, что происходит с ld ... обычно я просто использую GCC для связи)

Почему при указании ld для ссылки перемещаемым способом он внезапно не может найтибиблиотеки?Если я просто хочу проверить, существует ли -lm, что я должен делать, кроме

ld -r -lm

, чтобы он нашел библиотеку?

Если вы хотите увидеть источник, который я 'Имея дело с этим, вы можете скачать его здесь: https://github.com/jeremysalwen/ESPS (обратите внимание, что первый коммит - это исходный исходный код, а последующие - изменения, которые я лично сделал).

Ответы [ 2 ]

3 голосов
/ 07 июля 2011

MacOS X

В MacOS X справочная страница для ld довольно явно описывает параметр -r:

-r Объединяет объектные файлы для создания другогообъектный файл mach-o с типом файла MH_OBJECT.

Итак, если вы работаете в MacOS X, проблема в том, что -lm не является объектным файлом Mach-O и не является -lc,Тем не менее, теоретически, если у вас есть объектные файлы main.o, obj1.o и obj2.o и вы делаете:

cp obj1.o ./-lm
cp obj2.o ./-lc
ld -r -o main1.o main.o -lm -lc

, тогда это может работать.На практике это не так, и среди ошибок, которые вы получаете:

ld: warning: unexpected dylib (/usr/lib/libm.dylib) on link line
ld: warning: unexpected dylib (/usr/lib/libc.dylib) on link line

Однако, запуск:

ld -r -o main1.o -arch x86_64 main.o obj1.o obj2.o

работал без каких-либо колебаний со стороны загрузчика.

Linux

В Linux справочная страница для ld менее явна, но говорит:

-i Выполнить инкрементную ссылку (аналогично опции -r).

-r
--relocatable

Генерировать перемещаемый вывод - т.е. генерировать выходной файл, который в свою очередь может служить входом для ld.Это часто называют частичной связью.Как побочный эффект, в средах, которые поддерживают стандартные магические числа Unix, эта опция также устанавливает магическое число выходного файла на «OMAGIC».Если эта опция не указана, создается абсолютный файл.При связывании программ на C ++ эта опция не разрешает ссылки на конструкторы;для этого используйте -Ur.

Если входной файл не имеет тот же формат, что и выходной файл, частичное связывание поддерживается только в том случае, если этот входной файл не содержит перемещений.Различные выходные форматы могут иметь дополнительные ограничения;например, некоторые форматы на основе «a.out» вообще не поддерживают частичное связывание с входными файлами в других форматах.

Эта опция делает то же самое, что и -i.

Чтение между строк, это также берет объектные файлы и преобразует их в объектные файлы;это не добавляет библиотеки в смесь.Если подумать, объектные файлы не создаются, содержащие ссылки на библиотеки.

Итак, хотя могут быть платформы, на которых можно указывать библиотеки для компоновщика (загрузчика) при использовании опции -r,Есть другие, где это не так.

Временные решения

Первоначальная проблема состоит в том, чтобы установить, присутствуют ли библиотеки.Почему бы не подражать тому, что делает autoconf, и создать main.c, который, для предпочтения, содержал бы ссылку на символ, определенный в библиотеке, но который мог бы просто содержать:

int main(void){return 0;}

и компилировать исвяжите его с компилятором C:

cc -o main main.c -lm -lc

Если это не работает, то одна из библиотек отсутствует.Если вы уже проверили наличие -lc, вы можете сделать вывод, что -lm отсутствует.

0 голосов
/ 07 июля 2011

Что echo $LD_PRELOAD показывает вам?

Возможно, в сообщении об ошибке говорится, что ld не может найти .so связанных библиотек. Вы можете помочь, установив LD_PRELOAD для указания на эти .so файлы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...