【问题标题】:Conflict between dynamic linking priority in OSX?OSX中动态链接优先级之间的冲突?
【发布时间】:2013-07-12 16:25:04
【问题描述】:

OSX 上不同的 libjpeg 动态库之间存在动态链接冲突。首先有一个标准的原生 libJPEG.dylib(在 /System/Library/Frameworks/ImageIO.framework/Versions/A/Resources/ 中)。但是如果你使用的是 MacPorts,你也可以在(在 /opt/local/lib 中)有一个与端口相关的 libjpeg.dylib。例如,后者可能已作为其他端口的依赖项安装。

当您链接到系统 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. 什么是解决实际问题的好方法(从DYLD_LIBRARY_PATH 中删除/opt/local/lib 显然可以解决它,但会给其他依赖项带来问题)?

  2. 搜索动态库的其他路径(即“/System/Library”路径在哪里指定)以及为什么 DYLD_LIBRARY_PATH 的优先级更高?

【问题讨论】:

    标签: c++ macos macports dylib


    【解决方案1】:

    我在 MacOS El Capitan 中使用 OpenCV 时遇到了类似的问题。使用link中的解决方案解决了问题

    解决方法是删除/usr/local/lib目录下的一些dlylibs,并创建到相关文件/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
    

    【讨论】:

    • 拯救生命!!!!非常感谢。顺便说一句,在我的系统中,没有要删除的 libgif.dylib。
    • 谢谢! libgif 在我的系统上。
    • 这很危险。链接到该位置的实际 macOS 应用程序期望 Apple 提供的 dylib 将中断。
    • 答案中的链接已失效(请原谅双关语)
    • @jennykwan 非常危险-但有效-您有解决方案吗,尤其是例如在 *nix 升级期间?
    【解决方案2】:

    您不应使用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。优先使用正确的路径进行重建。

    请注意,有一些可用的“特殊”路径允许相对于它们的加载器找到库。请参阅 dyld(1) 手册页中的 @executable_path/ 及其亲属。

    【讨论】:

    • 感谢您的回复。 otoolinstall_name_tool确实很有用。链接时我不使用所有库的完整路径的原因是因为二进制文件将分发到没有 brew 或端口的系统。我想尽可能多地使用系统库,其余库将与应用程序一起打包。但是在开发过程中,目录结构看起来与安装的应用程序不同,所以我将非系统库与相对路径链接(如要分发的版本中),但在 DYLD 中有 /opt/local/ 直到我准备好发布/包装。
    • 但似乎正确的方法是尝试完全避免 DYLD_LIBRARY_PATH。
    • 我还为需要特定树结构的 Mac 开发系统可执行文件。我使用的解决方案有两个:我在 Xcode 中使用INSTALL_PATHDSTROOTDEPLOYMENT_LOCATION 安装到一个看起来像我的最终树的树中。对于任何依赖于相对路径 (@executable_path) 的东西,这就足够了。对于需要绝对路径的东西,我的开发盒上有一个符号链接,从我的“真实”安装路径到我的 Xcode DSTROOT
    【解决方案3】:

    如果使用Qt Creator,您必须取消选中Projects 选项卡中Run 部分中的Add build library search path to DYLD_LIBRARY_PATH and DYLD_FRAMEWORK_PATH 选项:

    【讨论】:

    • 感谢您的回复,这对我帮助很大!我猜这个复选框是在最新版本的 QtCreator 中引入的。
    • @Steakfly,很有趣,发布后它也帮助了我。
    【解决方案4】:

    我在尝试在 macOS Sierra 上运行 Apache Celix 时遇到了类似的错误 如果您使用 Homebrew 安装 libjpeg、libtiff、libpng,这可能会使链接器混淆使用 macOS imageIO 库。简单的解决方法是取消链接这些库:

    brew unlink libpng
    brew unlink libtiff
    brew unlink libjpeg
    

    在需要时重新链接这些库:

    brew link libpng
    brew link libtiff
    brew link libjpeg
    

    【讨论】:

    • 我在使用 Qt creator 时遇到了这个问题。以上是一个很好的解决方案,很容易逆转。如果你还有 libgif 的问题,你还需要brew unlink giflib
    • 这比其他答案建议的手动设置符号链接更好/更安全。
    【解决方案5】:

    我遇到了类似的错误,我解决了将以下变量放入我的 bash_profile 的问题:

    export DYLD_LIBRARY_PATH=/usr/lib/:$DYLD_LIBRARY_PATH
    

    【讨论】:

      【解决方案6】:

      我按照 mdemirst 建议的说明进行操作,它解决了我的问题。我正在使用 OS X Sierra。

      我创建了一个要点,以防其他人遇到同样的问题。

      Gist to fix Spidermonkey errors

      【讨论】:

        猜你喜欢
        • 2014-07-23
        • 2011-02-06
        • 1970-01-01
        • 2021-12-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-01-18
        相关资源
        最近更新 更多