Как мне избавиться от LD_LIBRARY_PATH во время выполнения?

Я создаю приложение на С++, которое использует библиотеку Intel IPP. Эта библиотека устанавливается по умолчанию в /opt и требует, чтобы вы установили LD_LIBRARY_PATH как для компиляции, так и для запуска вашего программного обеспечения (если вы выбрали ссылку на разделяемую библиотеку, что я и сделал). Я уже изменил свой configure.ac/Makefile.am, так что мне не нужно устанавливать эту переменную при компиляции, но я до сих пор не могу найти общую библиотеку во время выполнения; как это сделать?

Я компилирую с флагом -Wl, -R/path/to/libdir, используя g++

Обновление 1: На самом деле моя двоичная программа имеет некоторые IPP-библиотеки, правильно связанные, но только одно не:

$ ldd myprogram
linux-vdso.so.1 =>  (0x00007fffa93ff000)
libippacem64t.so.6.0 => /opt/intel/ipp/6.0.2.076/em64t/sharedlib/libippacem64t.so.6.0 (0x00007f22c2fa3000)
libippsem64t.so.6.0 => /opt/intel/ipp/6.0.2.076/em64t/sharedlib/libippsem64t.so.6.0 (0x00007f22c2d20000)
libippcoreem64t.so.6.0 => /opt/intel/ipp/6.0.2.076/em64t/sharedlib/libippcoreem64t.so.6.0 (0x00007f22c2c14000)
[...]
libiomp5.so => not found
libiomp5.so => not found
libiomp5.so => not found

Конечно, библиотека есть:

$ locate libiomp5.so
/opt/intel/ipp/6.0.2.076/em64t/sharedlib/libiomp5.so

Ответ 1

Как было предложено Ричардом Пеннингтоном, недостающая библиотека не используется напрямую моим приложением, но используется совместно используемыми библиотеками. Поскольку я не могу перекомпилировать IPP, решение моей проблемы состоит в том, чтобы добавить -liomp5 при компиляции, используя параметр -R для компоновщика. Это фактически добавляет rpath для libiomp5.so, исправляя проблему!

Ответ 2

Под /path/to/lib вы имеете в виду путь к каталогу, содержащему библиотеку, или к пути к фактическому файлу?

Параметр -R, заданный аргументом каталога, рассматривается как -rpath на ld, что является вариантом, который вы действительно хотите здесь. Он добавляет данный каталог в путь поиска библиотеки времени выполнения. Это должно работать, если вы дадите ему каталог, а не имя файла. Я довольно уверен в этом, сделав это сам, и потому что это один из намеков, предоставленных libtool:

Библиотеки были установлены в:

/путь/к/библиотеки-каталог

Если вам когда-либо захотелось установить связь с установленными библиотеками в данном каталоге LIBDIR вы должны либо использовать libtool, либо указать полный путь к библиотеке или использовать `-LLIBDIR ' флаг во время связывания и выполнить хотя бы одно из следующих действий:

  • добавить LIBDIR в переменную окружения `LD_LIBRARY_PATH ' во время выполнения
  • добавить LIBDIR в переменную окружения `LD_RUN_PATH '  при связывании
  • используйте флаг компоновщика `-Wl, -rpath -Wl, LIBDIR '
  • ваш системный администратор добавит LIBDIR в `/etc/ld.so.conf '

(Я вставляю это здесь, так как, возможно, один из других вариантов может быть более желательным - например, LD_RUN_PATH может сохранить вашу модификацию makefile)

Ответ 3

Вы можете проверить, выбран ли путь к библиотеке из вашего флага -R, запустив команду ldd или команду readelf в вашем двоичном файле. Переменная среды LD_LIBRARY_PATH является переопределяющей, поэтому ее не должно быть необходимым.

Ответ 4

Если возможно, вам следует использовать опцию -R.

Если нет, переименуйте свой исполняемый файл и создайте запуск script, который запускает ваш исполняемый файл, и там устанавливается LD_LIBRARY_PATH только для этой области.

В зависимости от платформы вы можете изменить ld.so.conf через /etc/ld.so.conf.d(Redhat/Fedora приходят на ум), что делает развертывание изменений в ld.so "проще" из сценария развертывания.

Ответ 5

Помимо всех полезных советов, размещенных здесь. Вы не пытаетесь использовать 64-битную специальную библиотеку в 32-разрядной системе (или наоборот, в зависимости от других условий), не так ли?

Ответ 6

bash:

export LD_LIBRARY_PATH=/path/to/lib

Tcsh:

setenv LD_LIBRARY_PATH /path/to/lib

Ответ 7

Попробуйте настроить ldconfig через ld.so.conf, чтобы он по умолчанию искал ваш каталог /opt/....