У меня есть проблемы с LD_LIBRARY_PATH
во время ссылки (этот вопрос не имеет никакого отношения ко времени выполнения).
Строка ссылки похожа на это, когда я работаю, делают (это - система Linux с помощью g ++ версия 4.1.x):
g++ a.o b.o c.o -o myapp \
-L/long/path/to/libs/ \
-L/another/long/path/ \
-labc -ldef -lghi
-l
ссылка опций совместно использовала библиотеки (например, libabc.so), которые существуют в каталогах, определенных -L
опции. Те каталоги также появляются в LD_LIBRARY_PATH
. С той конфигурацией ссылка успешна, и я могу запустить приложение.
Если я удаляю каталоги из LD_LIBRARY_PATH
, тогда я получаю единственную ошибочную строку, такую как:
/usr/bin/ld: cannot find -labc
С другой стороны, если я удаляю каталоги из списка -L
опции, тогда я получаю много предупреждений, таких как:
/usr/bin/ld: warning: libabc.so, needed by /long/path/to/libs/libxyz.so,
not found (try using -rpath or -rpath-link)
и затем намного больше ошибок, таких как:
/long/path/to/libs/libdef.so: undefined reference to `Foo::Bar<Baz>::junk(Fred*)'
Может кто-то объяснять различие между LD_LIBRARY_PATH
и -L
? Я хотел бы понять этот материал подробно, таким образом, ссылки значительно ценятся!
Кроме того, что я должен добавить к строке ссылки для избегания использования LD_LIBRARY_PATH
?
Править: Когда каталоги отсутствовали в -L
, компилятор, предложенный "пытаться использовать-rpath или - rpath-ссылка". Я не думаю, что когда-либо видел те опции в make-файле прежде. Вы имеете? Не уверенный, если это помогло бы LD_LIBRARY_PATH
проблема все же.
Настройки LD_LIBRARY_PATH
имеют наивысший приоритет, поэтому, когда он установлен, набор каталогов, упомянутых LD_LIBRARY_PATH
, ищется первым даже до стандартный набор
каталогов. Итак, в вашем случае настройка LD_LIBRARY_PATH
влияет на поиск
библиотеки, указанные в параметре -l
. Без LD_LIBRARY_PATH
некоторых зависимостей
могло быть разрешено из стандартного набора каталогов.
Хотя установка LD_LIBRARY_PATH
помогает с отладкой и опробовать более новую версию
использование библиотеки в общей настройке и развертывании среды разработки считается плохим.
Также см. этот HOWTO из документации Linux для получения более подробной информации об общих библиотеках
На этот вопрос есть два ответа, часть ответа заключается в компоновке во время компиляции (т.е. gcc -lfoo -L / usr / lib
... в свою очередь вызывает ld
) и поиск компоновщика во время выполнения.
Когда вы компилируете свою программу, компилятор проверяет синтаксис, а затем компоновщик, помимо прочего, гарантирует, что символы, необходимые для выполнения (т. Е. Переменные / методы / и т.д.), существуют. LD_LIBRARY_PATH
, как уже отмечалось, имеет побочный эффект, заключающийся в изменении способа поведения gcc
/ ld
, а также поведения компоновщика времени выполнения. путем изменения пути поиска.
Когда вы запускаете свою программу, компоновщик времени выполнения фактически выбирает разделяемые библиотеки (на диск или из памяти, если это возможно) и загружает совместно используемые символы / код / и т.д. LD_LIBRARY_PATH
влияет на этот путь поиска неявно (иногда не очень хорошо, как уже упоминалось.)
Правильное исправление для этого без использования LD_LIBRARY_PATH
в большинстве систем Linux - добавить путь, содержащий ваши общие библиотеки, к /etc/ld.so.conf
(или в некоторых дистрибутивах создайте файл в /etc/ld.so.conf.d/
с путь в нем) и запустите ldconfig
( / sbin / ldconfig
как root), чтобы обновить кэш привязок компоновщика времени выполнения.
Пример в Debian:
jewart@dorfl:~$ cat /etc/ld.so.conf.d/usrlocal.conf
/usr/local/lib
Затем, когда программа запускается, компоновщик времени выполнения будет искать в этих каталогах библиотеки, с которыми был скомпонован ваш двоичный файл.
Если вы хотите знать, с какими библиотеками запускается - время, о котором знает компоновщик, вы можете использовать:
jewart@dorfl:~$ ldconfig -v
/usr/lib:
libbfd-2.18.0.20080103.so -> libbfd-2.18.0.20080103.so
libkdb5.so.4 -> libkdb5.so.4.0
libXext.so.6 -> libXext.so.6.4.0
И, если вы хотите знать, с какими библиотеками связан двоичный файл, вы можете использовать ldd
как такой, который сообщит вам, какую библиотеку выберет ваш компоновщик времени выполнения:
jewart@dorfl:~$ ldd /bin/ls
linux-vdso.so.1 => (0x00007fffda1ff000)
librt.so.1 => /lib/librt.so.1 (0x00007f5d2149b000)
libselinux.so.1 => /lib/libselinux.so.1 (0x00007f5d2127f000)
libacl.so.1 => /lib/libacl.so.1 (0x00007f5d21077000)
libc.so.6 => /lib/libc.so.6 (0x00007f5d20d23000)
LD_LIBRARY_PATH
предназначен для поиска разделяемых библиотек при запуске приложения. Это побочный эффект, который влияет на вашу ссылку, и вам не следует полагаться на это.
Как часто нежелательный побочный эффект, LD_LIBRARY_PATH также будет искать на этапе ссылки (ld) после каталогов указывается с помощью -L (также, если нет флага -L дано).
Если бы я угадал, я бы сказал, что компоновщик возвращается к использованию LD_LIBRARY_PATH
для разрешения библиотеки, с которыми динамически связаны ваши прямые ссылки (например, libabc.so
, libdef.so
и libghi.so
). Глядя на страницу руководства для ld
, похоже, что ссылка на .so
, созданная с использованием -rpath
, повлияет на работу поиска динамически связанных символов. .