Нормально ли использовать DYLD_LIBRARY_PATH в Mac OS X? И какой у него алгоритм динамического поиска в библиотеке?

#language-agnostic #macos #dynamic-linking #dll

#не зависит от языка #macos #динамическая компоновка #dll

Вопрос:

Я прочитал несколько статей, в которых не рекомендуется использовать DYLD_LIBRARY_PATH, поскольку путь к динамической библиотеке должен быть исправлен с помощью -install_name, @rpath и @loader_path.

С точки зрения создания программы, которая работает как в Linux, так и в Mac OS X, DYLD_LIBRARY_PATH в Mac OS X выполняет именно то, что LD_LIBRARY_PATH в Linux. И мы можем использовать (почти) один и тот же make-файл, в котором нет -install_name и @rpath.

  • Можно ли использовать DYLD_LIBRARY_PATH в Mac OS X?
  • Каков алгоритм динамического поиска в библиотеке в Mac OS X, когда двоичный файл не может найти динамическую библиотеку? текущий каталог -> Каталоги DYLD_LIBRARY_PATH … ?

Комментарии:

1. Моей рекомендацией было бы избегать использования как DYLD_LIBRARY_PATH, так и LD_LIBRARY_PATH одинаково. Иногда их использование удобно, но, по моему опыту, они обычно используются неправильно или в качестве пластыря, что в конечном итоге приводит к поломке. Я недостаточно разбираюсь в способах поиска и указания динамически связанных библиотек на Mac, чтобы полностью ответить на ваш вопрос. Man gcc и man dyld должны помочь вам с правильными методами для использования на платформе Mac. Make -f поможет, если в конечном итоге вам придется написать 2 Make-файла, по одному для каждой платформы.

Ответ №1:

Как вы заметили, DYLD_LIBRARY_PATH ведет себя так же LD_LIBRARY_PATH , как и в других * nix. Однако есть другая переменная среды, на которую вам следует обратить внимание, которая называется DYLD_FALLBACK_LIBRARY_PATH .

В общем, они (как в osx, так и в Linux) предлагаются только для использования в разработке, поскольку они могут вызывать ошибки поиска символов при переопределении библиотекой, которая не имеет такой же таблицы символов. Хорошим примером этого является попытка переопределить установку vecLib по умолчанию (например, blas lapack) пользовательской установкой. Это приведет к ошибкам «символ не найден» в приложениях, связанных с системным vecLib, если DYLD_LIBRARY_PATH установлен параметр и обратное (ошибки поиска символов в пользовательских приложениях), если это не так. Это связано с тем, что system blas / lapack не является полной реализацией библиотек ATLAS.

DYLD_FALLBACK_LIBRARY_PATH не вызовет этих проблем.

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

Преимущество заключается в том, что этот процесс не вызовет ошибок поиска символов в приложениях, скомпилированных с использованием библиотек по умолчанию.

В общем случае, когда библиотеки устанавливаются в нестандартные местоположения, следует указывать абсолютные пути, что сводит на нет двусмысленность динамического поиска.

Комментарии:

1. Еще одно преимущество — если вы установите DYLD_LIBRARY_PATH , X11 откажется запускаться. Но если вы установите DYLD_FALLBACK_LIBRARY_PATH , у вас могут быть ваши пользовательские библиотеки и X11 одновременно. Отличный ответ!

2. Здесь что-то кажется подозрительным: согласно документам, путь поиска в библиотеке по умолчанию используется, если DYLD_FALLBACK_LIBRARY_PATH он не задан. Его установка приведет к игнорированию путей по умолчанию, что вызовет множество проблем. (По крайней мере, я нахожу, что это происходит с Mountain Lion.) Если вы измените DYLD_FALLBACK_LIBRARY_PATH , то, похоже, вам следует быть осторожным, добавляя значения по умолчанию вручную. (См. man dlopen .) Я что-то упускаю?

3. Доморощенные люди не ценят DYLD_FALLBACK_LIBRARY_PATH : github.com/mxcl/homebrew/issues/13463

4. DYLD_FALLBACK_LIBRARY_PATH, похоже, непригоден для использования в El Capitan по соображениям безопасности. Есть идеи?

5. при установке cuda нам говорят установить export DYLD_LIBRARY_PATH=/Developer/NVIDIA/CUDA-7.0/lib:$DYLD_LIBRARY_PATH

Ответ №2:

DYLD_LIBRARY_PATH ведет себя не так LD_LIBRARY_PATH . dlopen Документация OS X ( https://developer.apple.com/legacy/library/documentation/Darwin/Reference/ManPages/man3/dlopen.3.html ) указывает, что при указании абсолютного пути он сначала будет просматриваться в местах, указанных DYLD_LIBRARY_PATH :

Когда path содержит косую черту, но не является путем к фреймворку (т. Е. полным путем или частичным путем к dylib), dlopen() выполняет поиск следующего, пока не найдет совместимый файл Mach-O: $DYLD_LIBRARY_PATH (с конечным именем из path ), затем указанный путь (используя текущий рабочий каталог для относительных путей), затем $ DYLD_FALLBACK_LIBRARY_PATH (с именем листа из path ).

Другими словами, если вы установите DYLD_LIBRARY_PATH значение /Hello , следующие два dlopen вызова:

 dlopen("/Hello/libfoo.so", RTLD_NOW);
dlopen("/World/libfoo.so", RTLD_NOW);
  

будут ли оба разрешены /Hello/libfoo.so . Это довольно нелогично и представляет собой уязвимость в системе безопасности. Использующее программное обеспечение dlopen не может гарантировать загрузку правильных библиотек (возможно, переопределить DYLD_LIBRARY_PATH в своей собственной среде?).

Ответ №3:

Для получения документации по переменным среды редактора dynamic link и тому, как они влияют на поиск динамических библиотек, man dyld .

DYLD_LIBRARY_PATH

Это список каталогов, содержащих библиотеки, разделенный двоеточием. Динамический компоновщик выполняет поиск в этих каталогах, прежде чем искать библиотеки в расположениях по умолчанию. Это позволяет вам тестировать новые версии существующих библиотек.

Для каждой библиотеки, используемой программой, динамический компоновщик ищет ее в каждом каталоге в DYLD_LIBRARY_PATH по очереди. Если он по-прежнему не может найти библиотеку, он поочередно выполняет поиск DYLD_FALLBACK_FRAMEWORK_PATH и DYLD_FALLBACK_LIBRARY_PATH.

Используйте опцию -L для otool(1). чтобы обнаружить фреймворки и разделяемые библиотеки, с которыми связан исполняемый файл.

DYLD_FALLBACK_LIBRARY_PATH

Это список каталогов, содержащих библиотеки, разделенный двоеточием. Он используется в качестве расположения по умолчанию для библиотек, не найденных в их пути установки. По умолчанию для него установлено значение $ (HOME)/lib:/usr/local/lib:/lib:/usr/lib.

DYLD_VERSIONED_LIBRARY_PATH

Это список каталогов, разделенных двоеточием, которые содержат потенциальные библиотеки переопределения. Динамический компоновщик выполняет поиск динамических библиотек в этих каталогах. Для каждой найденной библиотеки dyld просматривает ее LC_ID_DYLIB и получает current_version и имя установки. Затем Dyld ищет библиотеку по пути к имени установки. То, что имеет большее значение current_version, будет использоваться в процессе всякий раз, когда требуется dylib с этим именем установки. Это похоже на DYLD_LIBRARY_PATH, за исключением того, что вместо того, чтобы всегда переопределять, оно переопределяет только в том случае, если поставляемая библиотека новее.

Комментарии:

1. Обратите внимание, что это otool -L указывает вам, с какими библиотеками связан исполняемый файл, не обязательно с теми, которые фактически будут загружены при его запуске. Вы можете убедиться в этом, установив DYLD_LIBRARY_PATH и запустив otool (пути, отображаемые для библиотек, не учитывают DYLD_LIBRARY_PATH ).