Я компилирую использование программы C++ g++
и ld
. У меня есть a .so
библиотека я хочу использоваться во время соединения. Однако библиотека того же имени существует в /usr/local/lib
, и ld
предпочитает ту библиотеку той, которую я непосредственно указываю. Как я могу зафиксировать это?
Для примеров ниже, мой файл библиотеки /my/dir/libfoo.so.0
. Вещи, которые я попробовал, которые не работают:
g++ -g -Wall -o my_binary -L/my/dir -lfoo bar.cpp
/my/dir
к началу или концу моего $PATH
en' переменная/my/dir/libfoo.so.0
как аргумент g ++ Добавьте путь к папке с вашей новой библиотекой к LD_LIBRARY_PATH
(у нее немного другое имя на Mac ...)
Ваше решение должно работать с использованием параметров -L / my / dir -lfoo
, во время выполнения используйте LD_LIBRARY_PATH, чтобы указать расположение вашей библиотеки.
Будьте осторожны при использовании LD_LIBRARY_PATH - вкратце (из ссылки):
.. последствия ..:
Безопасность : Помните, что каталоги, указанные в LD_LIBRARY_PATH, ищутся до (!) Стандартных местоположений? Таким способом злой человек может заставить ваше приложение загрузить версию разделяемой библиотеки , которая содержит вредоносный код! Это одна из причин, почему исполняемые файлы setuid / setgid игнорируют эту переменную!
Производительность : загрузчик ссылок должен выполнить поиск во всех указанных каталогах, пока не найдет каталог, в котором находится общая библиотека - для ВСЕХ общих библиотек, с которыми связано приложение! Это означает множество системных вызовов open (), которые завершатся ошибкой с «ENOENT (Нет такого файла или каталога)»! Если путь содержит много каталогов , количество неудачных вызовов будет линейно увеличиваться, и это можно определить по времени запуска приложения. Если некоторые (или все) каталоги находятся в среде NFS, время запуска ваших приложений может действительно увеличиться - и это может замедлить все система!
Несоответствие : это наиболее распространенная проблема. LD_LIBRARY_PATH заставляет приложение загружать разделяемую библиотеку, с которой оно не было связано , и это, скорее всего, несовместимо с исходной версией . Это может быть либо очень очевидным, т. Е. Приложение дает сбой, либо может привести к неверным результатам, если выбранная библиотека не выполняет то, что сделала бы исходная версия. Особенно иногда бывает трудно отладить.
ИЛИ
Использовать параметр rpath через gcc для компоновщика - путь поиска библиотеки времени выполнения, будет использоваться вместо поиска в стандартном каталоге (параметр gcc):
-Wl,-rpath,$(DEFAULT_LIB_INSTALL_PATH)
Это хорошо для временного решения .Компоновщик сначала ищет библиотеки в LD_LIBRARY_PATH, а затем просматривает стандартные каталоги.
Если вы не хотите постоянно обновлять LD_LIBRARY_PATH, вы можете сделать это «на лету» в командной строке:
LD_LIBRARY_PATH=/some/custom/dir ./fooo
Вы можете проверить, какие библиотеки компоновщик знает об использовании (пример):
/sbin/ldconfig -p | grep libpthread
libpthread.so.0 (libc6, OS ABI: Linux 2.6.4) => /lib/libpthread.so.0
И вы можете проверить, какая библиотека ваша приложение использует:
ldd foo
linux-gate.so.1 => (0xffffe000)
libpthread.so.0 => /lib/libpthread.so.0 (0xb7f9e000)
libxml2.so.2 => /usr/lib/libxml2.so.2 (0xb7e6e000)
librt.so.1 => /lib/librt.so.1 (0xb7e65000)
libm.so.6 => /lib/libm.so.6 (0xb7d5b000)
libc.so.6 => /lib/libc.so.6 (0xb7c2e000)
/lib/ld-linux.so.2 (0xb7fc7000)
libdl.so.2 => /lib/libdl.so.2 (0xb7c2a000)
libz.so.1 => /lib/libz.so.1 (0xb7c18000)
Указание абсолютного пути к библиотеке должно работать нормально:
g++ /my/dir/libfoo.so.0 ...
Вы не забыли удалить -lfoo
после добавления абсолютный путь?
В качестве альтернативы вы можете использовать переменные среды LIBRARY_PATH
и CPLUS_INCLUDE_PATH
, которые соответственно указывают, где искать библиотеки и где искать заголовки ( CPATH
также выполнит эту работу), без указания параметров -L и -I.
Изменить:
CPATH
включает заголовок с -I
и CPLUS_INCLUDE_PATH
с -системой
.