2015-11-04 9 views
9

Редактировать: я решил эту проблему, решение ниже.Почему я не могу переопределить путь поиска динамических библиотек с помощью LD_LIBRARY_PATH?

Я создаю код в общем вычислительном кластере, предназначенный для научных вычислений, поэтому я могу управлять файлами только в своей домашней папке. Хотя я использую fftw в качестве примера, я хотел бы понять конкретную причину, почему моя попытка настроить LD_LIBRARY_PATH не работает.

Я построить FFTW и fftw_mpi библиотеки в моей домашней папке, как этот

./configure --prefix=$HOME/install/fftw --enable-mpi --enable-shared 
make install 

Она строит хорошо, но в установке/FFTW/LIB, я считаю, что недавно построенный libfftw3_mpi.so ссылки на неправильную версию библиотека fftw.

$ ldd libfftw3_mpi.so |grep fftw 
    libfftw3.so.3 => /usr/lib64/libfftw3.so.3 (0x00007f7df0979000) 

Если теперь я пытаюсь установить LD_LIBRARY_PATH правильно, указывающий на этот каталог, он по-прежнему предпочитает неправильную библиотеку:

$ export LD_LIBRARY_PATH=$HOME/install/fftw/lib 
$ ldd libfftw3_mpi.so |grep fftw 
    libfftw3.so.3 => /usr/lib64/libfftw3.so.3 (0x00007f32b4794000) 

Только если я явно использовать LD_PRELOAD, я могу переопределить это поведение. Я не думаю, что LD_PRELOAD - это правильное решение.

$ export LD_PRELOAD=$HOME/install/fftw/lib/libfftw3.so.3 
$ ldd libfftw3_mpi.so |grep fftw 
    $HOME/install/fftw/lib/libfftw3.so.3 (0x00007f5ca3d14000) 

Вот что я бы ожидал, небольшой тест сделано в настольных Ubuntu, где я установил FFTW в/USR/Lib, а затем переопределить этот путь поиска LD_LIBRARY_PATH.

$ export LD_LIBRARY_PATH= 
$ ldd q0test_mpi |grep fftw3 
    libfftw3.so.3 => /usr/lib/x86_64-linux-gnu/libfftw3.so.3 
$ export LD_LIBRARY_PATH=$HOME/install/fftw-3.3.4/lib 
$ ldd q0test_mpi |grep fftw3 
    libfftw3.so.3 => $HOME/install/fftw-3.3.4/lib/libfftw3.so.3 

Вкратце: почему библиотека libfft3_mpi все еще находит неправильную динамическую библиотеку fftw3? Где этот путь поиска жестко закодирован таким образом, что он имеет приоритет над LD_LIBARY_PATH? Почему это не так на другом компьютере?

Я использую интеллектуальные компиляторы 13.1.2, mkl 11.0.4.183 и openmpi 1.6.2, если это имеет значение.

Редактировать: Спасибо за все ответы. С помощью этих средств мы смогли изолировать проблему до RPATH, и оттуда поддержка кластера смогла выяснить проблему. Я принял первый ответ, но оба ответа были хорошими.

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

[The] компиляция проходит через нашу оболочку компилятора. Мы делаем RPATH-ing по умолчанию, так как он помогает большинству пользователей правильно выполнять свои задания без загрузки LD-LIBRARY_PATH и т. Д. Однако мы исключаем определенные пути библиотеки от RPATH по умолчанию, который включает в себя/lib,/lib64/proj /home и т. Д. Раньше/usr/lib64 не был исключен по ошибке (в основном). Теперь мы добавили этот путь в список исключений.

ответ

12

От http://man7.org/linux/man-pages/man8/ld.so.8.html

При решении общих зависимостей объектов, динамический компоновщик первого проверяет каждую строку зависимостей, чтобы увидеть, если она содержит косую черту (это может произойти, если общий объект путь, содержащий слэш был указанный во время соединения).Если найдена косая черта, то строка зависимостей интерпретируется как (относительный или абсолютный) путь, а общий объект загружается с использованием этого имени пути.

Если общий объект зависимость не содержит косой черты, то ищется в следующем порядке:

о (только ELF) Используя каталоги, указанные в DT_RPATH динамического атрибута сечения двоичном, если присутствует и DT_RUNPATH атрибут не существует. Использование DT_RPATH устарело.

o Использование переменной окружения LD_LIBRARY_PATH. За исключением случаев, когда исполняемый файл является двоичным идентификатором set-user-ID/set-group-ID, и в этом случае его игнорируют .

o (Только ELF) Использование каталогов, указанных в атрибуте динамической секции DT_RUNPATH , если присутствует.

o Из файла кэша /etc/ld.so.cache, который содержит скомпилированный список общих объектов-кандидатов, ранее найденных в расширенном пути библиотеки . Если, однако, двоичный файл был связан с параметром -z nodeflib linker, общими объектами в путях по умолчанию являются . Общие объекты, установленные в аппаратной возможности, каталоги (см. Ниже) предпочтительнее других общих объектов.

o В пути по умолчанию/lib, а затем/usr/lib. (В некоторых 64-битных архивах пути по умолчанию для 64-разрядных общих объектов: /lib64, а затем/usr/lib64.) Если двоичный файл был связан с опцией -z nodeflib linker, этот шаг пропускается.

  • с readelf readelf -d libfftw3_mpi.so вы можете проверить, если ваш Lib содержит такой атрибут в динамическом разделе.

  • с export LD_DEBUG=libs вы можете отлаживать путь поиска, используемый, чтобы найти LIBS

  • с chrpath -r<new_path> <executable> RPATH может быть изменен

+0

Действительно, с readelf кажется, что действительно/usr/lib64 находится перед/home/USER/install/fftw/lib в переменной RPATH. Теперь проблема остается, что как/usr/lib64 добрался до/fftw/lib. '$ readelf -d libfftw3_mpi.so | grep RPATH 0x000000000000000f (RPATH) Библиотека rpath: [/software/intel/composer_xe_2013.4.183/compiler/lib/intel64:/usr/lib:/usr/lib/gcc/x86_64-redhat-linux/4.4.4:/usr/lib64:/home/USER/install/fftw/lib] ' –

+0

rpath добавляется во время компиляции. Я не знаю fftw lib, но, возможно, существует флаг '--disable-rpath' configure. Чтобы изменить rpath, вы можете использовать 'chrpath -r ' для изменения rpath в библиотеке – bonoparte

2

Я вижу две возможные причины этого.

Первый, libfftw3_mpi.so может быть связан с /usr/lib64/ как RPATH. В этом случае предоставление LD_LIBRARY_PATH не будет иметь никакого эффекта. Чтобы проверить, действительно ли это ваш случай, запустите readelf -d libfftw3_mpi.so | grep RPATH и посмотрите, есть ли у него /usr/lib64/ в качестве пути к библиотеке. Если это так, используйте утилиту chrpath, чтобы изменить или удалить ее.

В качестве альтернативы вы можете использовать систему, которая не поддерживает LD_LIBRARY_PATH (например, HP-UX).