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

Я создаю приложение C++, использующее библиотеку 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

person Kjir    schedule 20.03.2010    source источник
comment
Возможно, мне нужно изменить вопрос на что-то другое, но мне нужны предложения, у меня мало идей   -  person Kjir    schedule 20.03.2010
comment
Хм, интересно, совпадение ли это, что у него также отсутствует расширение номера версии - возможно, IPP просто не устанавливает себя правильно?   -  person Cascabel    schedule 20.03.2010
comment
Интересно, на пропущенную библиотеку ссылается не ваша программа, а библиотеки, на которые вы ссылаетесь?   -  person Richard Pennington    schedule 21.03.2010
comment
@Richard: это действительно хорошая мысль. Возможно, вы могли бы скомпилировать IPP (или другие библиотеки, зависящие от IPP), используя LD_RUN_PATH или соответствующие параметры компоновщика.   -  person Cascabel    schedule 22.03.2010
comment
@Richard: Вероятно, вы правы, я помню, что читал что-то подобное, и libiomp5.so — это библиотека потоков от Intel (часть IIRC MKL). Беда в том, что я не могу перекомпилировать IPP, потому что они не OSS...   -  person Kjir    schedule 22.03.2010
comment
Вы ни в коем случае не должны изменять файл configure.ac/Makefile.am вашего приложения, чтобы отразить нестандартное расположение библиотеки. Вместо этого используйте файл CONFIG_SITE, чтобы установить LD_LIBRARY_PATH для вас во время настройки (или просто поместите его в среду вашей оболочки входа в систему, что также решает проблему времени выполнения).   -  person William Pursell    schedule 15.04.2010
comment
Путь расширяется с помощью переменных, заданных пользовательскими макросами m4, которые ищут библиотеку. В моем файле configure.ac нет фиксированного пути.   -  person Kjir    schedule 21.04.2010


Ответы (7)


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

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

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

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

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

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

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

person Cascabel    schedule 20.03.2010
comment
Я изменил вопрос, чтобы лучше указать, что я действительно указываю на каталог. Добавление этой опции на этапе связывания фактически решило проблему во время компиляции, но время выполнения по-прежнему не работает. Конечно, я сделал make clean && make, чтобы убедиться, что я обновил двоичные файлы... - person Kjir; 20.03.2010
comment
На всякий случай можно попробовать маршрут LD_RUN_PATH? - person Cascabel; 20.03.2010

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

person Kjir    schedule 22.03.2010

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

person abc    schedule 20.03.2010

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

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

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

person Joe    schedule 20.03.2010
comment
Вы смотрели уже опубликованную информацию? OP использует опцию -R; проблема в том, что он не работает, как ожидалось. И изменение ld.so.conf похоже на настройку LD_LIBRARY_PATH, за исключением того, что это еще хуже - это применимо ко всему когда-либо, а не только к этой программе, и развертывание таким образом, что всегда требуется root, не проще. - person Cascabel; 21.03.2010
comment
Кроме того, хотя скрипт-оболочка будет работать, он не только неэлегантен, но и в некоторых маловероятных, но возможных случаях может быть проблематичным — если рассматриваемая программа запускает другие программы, они наследуют эту переменную среды, и вы снова открыты к обычным проблемам с LD_LIBRARY_PATH снова. - person Cascabel; 21.03.2010
comment
Я не говорю, что это хорошие решения, но если конечный пользователь устанавливает компоненты среды выполнения, которые являются зависимостями и которые явно не добавляются в методы поиска системы, то ваши возможности крайне ограничены. По сути, есть только два способа найти динамические библиотеки за пределами значений по умолчанию: вы обновляете ld.so или используете LD_LIBRARY_PATH (или LD_RUN_PATH) в той или иной форме. - person Joe; 21.03.2010

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

person lorenzog    schedule 20.03.2010

удар:

export LD_LIBRARY_PATH=/path/to/lib

ткш:

setenv LD_LIBRARY_PATH /path/to/lib
person Richard Pennington    schedule 20.03.2010
comment
Вопрос в том, как не устанавливать LD_LIBRARY_PATH, а не в том, как его установить. Это очень разумный вопрос, так как установка LD_LIBRARY_PATH может быть довольно злой. - person Cascabel; 20.03.2010

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

person jpalecek    schedule 20.03.2010
comment
Это нежизнеспособный вариант, это похоже на установку LD_LIBRARY_PATH, но, возможно, менее переносимую. Также потребуется административная задача, которая не решает основной проблемы, заключающейся в том, чтобы сделать программное обеспечение как можно более безболезненным для следующего пользователя/разработчика. - person Kjir; 20.03.2010