C++ OSX中动态链接优先级之间的冲突?

C++ OSX中动态链接优先级之间的冲突?,c++,macos,macports,dylib,C++,Macos,Macports,Dylib,OSX上不同的libjpeg动态库之间存在动态链接冲突。首先是一个标准的原生libJPEG.dylib(位于/System/Library/Frameworks/ImageIO.framework/Versions/a/Resources/)。但是,如果您使用的是MacPorts,也可以在(in/opt/local/lib)中使用与端口相关的libjpeg.dylib。例如,后者可能已作为某个其他端口的依赖项安装 当您针对系统libJPEG(首选)进行链接时,会产生问题。 然后,如果/opt/l

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

当您针对系统libJPEG(首选)进行链接时,会产生问题。 然后,如果
/opt/local/lib
位于DYLD_LIBRARY_路径中,则在搜索动态lib时将优先考虑该路径,从而在加载符号时导致运行时错误:

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
所以我有两个问题(可能相关):

  • 解决实际问题的好方法是什么(从
    DYLD\u LIBRARY\u PATH
    中删除
    /opt/local/lib
    显然可以解决问题,但会给其他依赖项带来问题)

  • 为动态库搜索哪些其他路径(即指定的“/System/Library”路径在哪里),为什么DYLD_Library_路径的优先级更高


  • 不应使用
    DYLD\u library\u 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
    。如果您以引用错误库的方式构建它,我建议重新构建并将其指向正确的库

    如果这是不可能的,可以使用
    安装名称工具
    编辑使用的路径,但在某些情况下,这不起作用,例如如果新路径比旧路径长,并且您没有将其链接到
    -header\u pad\u max\u install\u names
    。最好使用正确的路径重建


    请注意,有一些“特殊”路径可供使用,允许相对于其加载程序查找库。请参阅
    @executable\u path/
    及其亲属在
    dyld(1)
    手册页中。

    我遇到了一个类似的错误,我解决了将以下变量放入bash\u配置文件中的问题:

    export DYLD_LIBRARY_PATH=/usr/lib/:$DYLD_LIBRARY_PATH
    

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

    解决方案是删除/usr/local/lib目录中的一些dlylib,并创建指向相关文件/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
    

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

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


    在macOS Sierra上尝试运行Apache Celix时,我遇到了类似的错误 如果使用自制软件安装libjpeg、libtiff、libpng,可能会使链接器无法使用macOS imageIO库。简单修复是取消链接那些LIB:

    brew unlink libpng
    brew unlink libtiff
    brew unlink libjpeg
    
    在我们需要时重新链接这些LIB:

    brew link libpng
    brew link libtiff
    brew link libjpeg
    

    如果使用
    Qt Creator
    ,则必须从
    项目
    选项卡中的
    运行
    部分取消选中
    将构建库搜索路径添加到DYLD\u library\u路径和DYLD\u FRAMEWORK\u路径
    选项:


    谢谢您的回复
    otool
    install\u name\u工具
    确实很有用。我之所以在链接时不使用所有库的完整路径,是因为二进制文件将分发到没有brew或端口的系统。我希望尽可能多地使用系统库,其余的库将随应用程序打包。但在开发过程中,目录结构看起来与已安装的应用程序不同,因此我将非系统库与相对路径链接(如要分发的版本),但是,在我准备发布/打包之前,请在DYLD中使用/opt/local/in。但似乎正确的方法是尝试完全避免使用DYLD\u LIBRARY\u路径。我还为Mac开发了需要特定树结构的系统可执行文件。我使用的解决方案有两个方面:我使用Xcode中的
    install\u PATH
    DSTROOT
    、和
    DEPLOYMENT\u LOCATION
    安装到一个类似于最终树的树中。对于依赖相对路径(
    @executable\u path
    )的任何东西,这就足够了。对于需要绝对路径的东西,我在我的开发盒上有一个符号链接,从我的“真实”安装路径到我的Xcode
    DSTROOT
    。救命!!!!谢谢。顺便说一句,在我的系统中,没有libgif.dylib可删除。谢谢<代码>libgif在我的系统上。这很危险。链接到该位置的实际macOS应用程序期望苹果提供的dylibs会中断。答案中的链接已失效(请原谅双关语)。我在使用Qt creator时遇到了这个问题。以上是一个很好的解决方案,很容易逆转。此外,如果您对libgif有问题,您还需要
    brew取消giflib的链接
    。这比按照另一个答案建议手动设置符号链接要好/更安全。感谢您的回复,这对我帮助很大!我猜这个复选框是在QtCreator的最新版本中引入的。@Steakfly,有趣的是,它在发布这个之后也帮助了我。