Конфликт между динамическим приоритетом связывания в OSX?

Существует конфликт динамического связывания между различными динамическими библиотеками libjpeg в OSX. Во-первых, это стандартный нативный libJPEG.dylib (в /System/Library/Frameworks/ImageIO.framework/Versions/A/Resources/). Но если вы используете MacPorts, у вас также может быть связанная с портом libjpeg.dylib (в /opt/local/lib). Последний мог, например, быть установлен как зависимость для какого-то другого порта.

Это создает проблему, когда вы связываетесь со своей системой libJPEG (что предпочтительнее). Затем, если /opt/local/lib находится в DYLD_LIBRARY_PATH, этот путь будет иметь приоритет при поиске динамической библиотеки, что приведет к ошибке выполнения при загрузке символов:

dyld: Symbol not found: __cg_jpeg_resync_to_restart
 Referenced from:
/System/Library/Frameworks/ImageIO.framework/Versions/A/ImageIO
 Expected in: /opt/local/lib/libJPEG.dylib
in /System/Library/Frameworks/ImageIO.framework/Versions/A/ImageIO
Trace/BPT trap: 5

Итак, у меня есть два вопроса (вероятно, связанных):

  1. Каков хороший способ решения реальной проблемы (удаление /opt/local/lib из DYLD_LIBRARY_PATH, очевидно, решает ее, но создает проблемы для других зависимостей)?

  2. Какие другие пути ищутся для динамических библиотек (например, где указан путь «/System/Library») и почему DYLD_LIBRARY_PATH имеет более высокий приоритет?


person kamjagin    schedule 14.07.2013    source источник


Ответы (6)


Вы не должны устанавливать пути к библиотекам, используя DYLD_LIBRARY_PATH. Как вы обнаружили, это имеет тенденцию взрываться. Требования к исполняемым файлам и библиотекам должны быть встроены в них во время компоновки. Используйте otool -L, чтобы узнать, что ищет файл:

$ otool -L /System/Library/Frameworks/ImageIO.framework/Versions/A/ImageIO
/System/Library/Frameworks/ImageIO.framework/Versions/A/ImageIO:
    /System/Library/Frameworks/ImageIO.framework/Versions/A/ImageIO (compatibility version 1.0.0, current version 1.0.0)
    ...
    /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1197.1.1)

Для примера одной из моих доморощенных программ:

$ otool -L /usr/local/bin/gifcolor
/usr/local/bin/gifcolor:
    /usr/local/Cellar/giflib/4.1.6/lib/libgif.4.dylib (compatibility version 6.0.0, current version 6.6.0)
    /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 159.1.0)

Обратите внимание, что он ссылается на /usr/local. Если вы построили его таким образом, что он ссылается на неправильную библиотеку, я рекомендую перестроить его и указать на правильную библиотеку.

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

Обратите внимание, что есть несколько «специальных» путей, позволяющих находить библиотеки относительно их загрузчика. См. @executable_path/ и его аналоги на справочной странице dyld(1).

person Rob Napier    schedule 15.07.2013
comment
Спасибо за ответ. otoolи install_name_tool действительно полезны. Причина, по которой я не использую полный путь для всех библиотек при компоновке, заключается в том, что двоичный файл будет распространяться на системы без варева или портов. Я хотел бы максимально использовать системные библиотеки, а остальные библиотеки будут упакованы вместе с приложением. Но во время разработки структура каталогов выглядит иначе, чем у установленного приложения, поэтому я связываю несистемные библиотеки с относительными путями (как в распространяемой версии), но имею /opt/local/ в DYLD, пока не буду готов к выпуск/упаковка. - person kamjagin; 15.07.2013
comment
Но кажется, что правильный путь — вообще избегать DYLD_LIBRARY_PATH. - person kamjagin; 15.07.2013
comment
Я также разрабатываю системные исполняемые файлы для Mac, которые требуют определенной древовидной структуры. Решение, которое я использую, двоякое: я устанавливаю в дерево, которое выглядит как мое окончательное дерево, используя INSTALL_PATH, DSTROOT и DEPLOYMENT_LOCATION в Xcode. Для всего, что зависит от относительных путей (@executable_path), этого достаточно. Для вещей, требующих абсолютных путей, у меня есть символическая ссылка в моем окне разработки с моего реального пути установки на мой Xcode DSTROOT. - person Rob Napier; 15.07.2013

У меня возникла аналогичная проблема при использовании OpenCV в MacOS El Capitan. Проблема решена с помощью решения в ссылка

Решение состоит в том, чтобы удалить некоторые dlylibs в каталоге /usr/local/lib и создать символические ссылки на связанные файлы /System/Library/Frameworks/ImageIO.framework/Resources/

cd /usr/local/lib
rm libgif.dylib
ln -s /System/Library/Frameworks/ImageIO.framework/Resources/libGIF.dylib libGIF.dylib
rm libjpeg.dylib
ln -s /System/Library/Frameworks/ImageIO.framework/Resources/libJPEG.dylib libJPEG.dylib
rm libtiff.dylib
ln -s /System/Library/Frameworks/ImageIO.framework/Resources/libTIFF.dylib libTIFF.dylib
rm libpng.dylib
ln -s /System/Library/Frameworks/ImageIO.framework/Resources/libPng.dylib libPng.dylib
person mdemirst    schedule 28.01.2016
comment
СПАСЕНИЕ ЖИЗНИ!!!! Большое спасибо. Кстати, в моей системе не было libgif.dylib для удаления. - person Diego Pamio; 07.05.2016
comment
Спасибо! libgif был в моей системе. - person kilojoules; 18.07.2017
comment
Это опасно. Фактические приложения macOS, которые ссылаются на это место, ожидают, что dylibs, предоставленные Apple, сломаются. - person jennykwan; 11.09.2018
comment
Ссылка в ответе мертва (извините за каламбур) - person jtlz2; 07.02.2019

При использовании Qt Creator необходимо снять флажок с параметра Add build library search path to DYLD_LIBRARY_PATH and DYLD_FRAMEWORK_PATH в разделе Run на вкладке Projects:

qtcreator

person Iulian Onofrei    schedule 30.05.2018
comment
Спасибо за этот ответ, он мне очень помог! Я предполагаю, что этот флажок был введен в последней версии QtCreator. - person Steakfly; 17.06.2018
comment
@Steakfly, достаточно забавно, мне это тоже помогло после публикации этого. - person Iulian Onofrei; 04.12.2018

У меня была аналогичная ошибка при попытке запустить Apache Celix в macOS Sierra. Если вы используете Homebrew для установки libjpeg, libtiff, libpng, что может сбить компоновщика с использованием библиотеки macOS imageIO. Простое исправление - отключить эти библиотеки:

brew unlink libpng
brew unlink libtiff
brew unlink libjpeg

Повторно связывайте эти библиотеки всякий раз, когда нам нужно:

brew link libpng
brew link libtiff
brew link libjpeg
person Thien Pham    schedule 10.03.2017
comment
У меня была эта проблема при работе с создателем Qt. Вышеизложенное является хорошим решением, которое легко обратимо. Если у вас есть проблемы с libgif, вам также понадобится brew unlink giflib. - person Albin Stigo; 21.10.2017
comment
Это намного лучше/безопаснее, чем ручная установка символических ссылок, как предполагает другой ответ. - person ms611; 21.10.2019

У меня была аналогичная ошибка, и я решил добавить следующую переменную в свой bash_profile:

export DYLD_LIBRARY_PATH=/usr/lib/:$DYLD_LIBRARY_PATH
person Franzé Jr.    schedule 03.09.2014

Я следовал инструкциям, предложенным mdemirst, и это решило мою проблему. Я использую ОС Х Сьерра.

Я создал суть на всякий случай, если кто-то еще столкнется с той же проблемой.

Суть исправления ошибок Spidermonkey

person Chris Wessells    schedule 06.03.2017