Можно ли использовать DYLD_LIBRARY_PATH для Mac OS X? И что с ним работает алгоритм поиска динамической библиотеки?
Я прочитал несколько статей, которые препятствуют использованию 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
в другом * nix. Однако есть еще одна переменная среды, на которую вы должны посмотреть: DYLD_FALLBACK_LIBRARY_PATH
.
В общем, это (как на osx, так и linux), предлагаемые только для использования разработки, поскольку они могут вызывать ошибки поиска символов при переопределении с библиотекой, которая не имеет одинаковой таблицы символов. Хорошим примером этого является попытка переопределить стандартную установку VecLib (например, blas lapack) с пользовательской установкой. Это приведет к появлению ошибок, которые не обнаружены символом в приложениях, связанных с системой VecLib, если параметр DYLD_LIBRARY_PATH
установлен и обратный (ошибки поиска символов в пользовательских приложениях), если это не так. Это связано с тем, что системный blas/lapack не является полной реализацией библиотек ATLAS.
DYLD_FALLBACK_LIBRARY_PATH
не вызовет этих проблем.
При установке библиотек в нестандартное расположение DYLD_FALLBACK_LIBRARY_PATH
гораздо более разумно. Это будет искать символы в библиотеках, предоставляемых по умолчанию, и если символ там не найден, вернитесь к указанному пути.
Преимущество состоит в том, что этот процесс не приведет к ошибкам поиска символов в приложениях, скомпилированных против библиотек по умолчанию.
В общем, когда библиотеки установлены в нестандартных местах, должны быть указаны абсолютные пути, которые отрицают неоднозначность динамического поиска.
Ответ 2
DYLD_LIBRARY_PATH
не ведет себя как LD_LIBRARY_PATH
. Документация OS X dlopen
(https://developer.apple.com/legacy/library/documentation/Darwin/Reference/ManPages/man3/dlopen.3.html) указывает, что при предоставлении абсолютного пути он сначала будет искать в местах, указанных DYLD_LIBRARY_PATH
:
Когда путь содержит косую черту, но не является контуром каркаса (то есть полный путь или частичный путь к dylib), dlopen() ищет следующее, пока не найдет совместимый файл Mach-O: $DYLD_LIBRARY_PATH (с листом имя из пути), затем предоставленный путь (используя текущий рабочий каталог для относительных путей), затем $ DYLD_FALLBACK_LIBRARY_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
Для документации по переменным окружения динамического редактора ссылок и тому, как они влияют на поиск динамических библиотек, 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 и install. Затем Dyld ищет библиотеку по пути установки. В зависимости от того, какое большее значение current_version будет использоваться в процессе, когда требуется dylib с этим именем установки. Это похоже на DYLD_LIBRARY_PATH, но вместо того, чтобы всегда переопределять, он только переопределяет, то есть поставляемая библиотека более новая.