C 如何使用dyld不忽略最大版本

C 如何使用dyld不忽略最大版本,c,macos,versioning,dyld,dynamic-library,C,Macos,Versioning,Dyld,Dynamic Library,我正在尝试在OS X(10.7.5)下对共享库进行版本设置,但在让dyld识别最大兼容版本(最低版本可以)时遇到了问题。考虑下面的测试代码和下面的场景: 二进制链接到1.0版的库,兼容版本1.0 binary按预期工作 otool-L二进制文件:libdyldtest.dylib(兼容版本1.0.0,当前版本1.0.0) otool-L libdyldtest.dylib:libdyldtest.dylib(兼容版本1.0.0,当前版本1.0.0) 库已更新并重新编译,已移动到2.0版,

我正在尝试在OS X(10.7.5)下对共享库进行版本设置,但在让
dyld
识别最大兼容版本(最低版本可以)时遇到了问题。考虑下面的测试代码和下面的场景:

  • 二进制链接到1.0版的库,兼容版本1.0

    • binary
      按预期工作
      • otool-L二进制文件
        libdyldtest.dylib(兼容版本1.0.0,当前版本1.0.0)
      • otool-L libdyldtest.dylib
        libdyldtest.dylib(兼容版本1.0.0,当前版本1.0.0)
  • 库已更新并重新编译,已移动到2.0版,兼容版本1.0

    • binary
      应该仍然有效,而且确实有效,因为库的兼容性已经足够老了
      • otool-L二进制文件
        libdyldtest.dylib(兼容版本1.0.0,当前版本1.0.0)
      • otool-L libdyldtest.dylib
        libdyldtest.dylib(兼容版本1.0.0,当前版本2.0.0)
  • 库已更新并重新编译为不兼容的版本。将版本和兼容版本都设置为3.0。二进制文件不会重新编译

    • binary
      应该停止工作,因为它希望与1.0兼容,但
      libdyldtest
      仅与3.0及更高版本兼容。为什么这样做有效?
      • otool-L二进制文件
        libdyldtest.dylib(兼容版本1.0.0,当前版本1.0.0)
      • otool-L libdyldtest.dylib
        libdyldtest.dylib(兼容版本3.0.0,当前版本3.0.0)
      • 设置
        DYLD\u PRINT\u库
        显示正在加载
        libdyldtest.3.0.dylib
  • 问题是上面的3个是有效的,我认为它不应该。这是预期的行为吗?如果没有,我如何更正

    注意:相关文档似乎没有使用
    LibraryInfo
    结构的
    maxVersion
    成员,仅使用
    minVersion
    。因此,将最低兼容版本设置为较低版本将按预期工作:

    • 库设置为0.9版,兼容性为0.0
      • binary
        按预期停止工作。
        • otool-L二进制文件
          libdyldtest.dylib(兼容版本1.0.0,当前版本1.0.0)
        • otool-L libdyldtest.dylib
          libdyldtest.dylib(兼容版本0.0.0,当前版本0.9.0)
          • 运行
            binary
            会导致
            原因:库版本不兼容:binary需要版本1.0.0或更高版本,但libdyldtest.0.9.dylib
            ,正如预期的那样
    谢谢!

    示例代码 图书馆h:

    #ifndef __LIBRARY_H__
    #define __LIBRARY_H__
    
    void functionFromLibrary();
    
    #endif /* __LIBRARY_H__ */
    
    c.图书馆:

    #include "library.h"
    
    #include <stdio.h>
    
    void
    functionFromLibrary()
    {
        printf("functionFromLibrary()\n");
    }
    
    生成文件:

    .PHONY: all library binary
    
    MAJOR=1
    MINOR=0
    COMPAT=1.0
    LIBNAME=dyldtest
    BINNAME=binary
    
    all: library binary
    
    binary: binary.o
        $(CC) $< -L. -l$(LIBNAME) -o $(BINNAME)
    
    library: library.o
        $(CC) -dynamiclib $< -Wl,-current_version,$(MAJOR).$(MINOR) \
            -Wl,-compatibility_version,$(COMPAT) -Wl,-macosx_version_min,10.6 \
            -Wl,-install_name,lib$(LIBNAME).dylib \
            -o lib$(LIBNAME).$(MAJOR).$(MINOR).dylib
        ln -f -s lib$(LIBNAME).$(MAJOR).$(MINOR).dylib \
            lib$(LIBNAME).$(MAJOR).dylib
        ln -f -s lib$(LIBNAME).$(MAJOR).dylib lib$(LIBNAME).dylib
    
    clean:
        $(RM) *.o lib$(LIBNAME)*.dylib $(BINNAME)
    
    .PHONY:所有库二进制文件
    专业=1
    小调=0
    COMPAT=1.0
    LIBNAME=dyldtest
    BINNAME=binary
    全部:库二进制文件
    二进制文件:binary.o
    $(CC)$<-L.-L$(LIBNAME)-o$(BINNAME)
    图书馆:图书馆
    $(CC)-dynamiclib$<-Wl,-当前版本,$(主要)。$(次要)\
    -Wl,-兼容版本,$(兼容)-Wl,-macosx版本最低,10.6\
    -Wl,-install_name,lib$(LIBNAME).dylib\
    -o lib$(LIBNAME)。$(MAJOR)。$(MINOR).dylib
    ln-f-s lib$(LIBNAME)。$(MAJOR)。$(MINOR).dylib\
    lib$(LIBNAME)。$(MAJOR).dylib
    ln-f-s lib$(LIBNAME)。$(MAJOR).dylib$(LIBNAME).dylib
    清洁:
    $(RM)*.o lib$(LIBNAME)*.dylib$(BINNAME)
    
    看一下->“管理客户端与依赖库的兼容性”->“指定版本信息”。您可以使用主版本和命名设置正确的兼容性。

    请参阅->“管理客户端与依赖库的兼容性”->“指定版本信息”。您可以使用主版本和命名设置正确的兼容性。

    这是预期的行为

    dyld
    执行的版本号检查仅限于确保加载库的兼容版本高于生成时使用的库的兼容版本。库的当前版本是可以通过编程访问的,但在评估是否应该加载特定库时,
    dyld不使用它。通过查看
    ld
    手册页的
    -compatibility\u version
    -current\u version
    部分,您可以了解有关这两个版本号的更多信息

    您可以通过使用库的安装名称来实现所需的效果。您可以通过查看如何使用
    libSystem.dylib
    来了解这一点:

    mrowe@angara:~$ ls -lha /usr/lib/libSystem.{,B.}dylib
    -rwxr-xr-x  1 root  wheel    53K Jul  9  2012 /usr/lib/libSystem.B.dylib
    lrwxr-xr-x  1 root  wheel    17B Jul  9  2012 /usr/lib/libSystem.dylib -> libSystem.B.dylib
    mrowe@angara:~$ otool -L /usr/lib/libSystem.dylib | head -2
    /usr/lib/libSystem.dylib:
        /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 169.3.0)
    mrowe@angara:~$ 
    

    请注意,
    otool
    输出的第二行中的安装名称如何指向名称与版本号一致的动态库版本(在案例B中)。如果苹果要引入一个向后不兼容的
    libSystem.dylib
    版本,他们可以把它放在
    /usr/lib/libSystem.C.dylib
    上,并更新
    libSystem.dylib
    上的符号链接来指向它。现有程序仍然会查找
    libSystem.B.dylib
    ,因为这是链接时写入其
    LC\u LOAD\u dylib
    LOAD命令的安装名称。任何新链接到
    libSystem.dylib
    的程序都会找到
    libSystem.C.dylib
    ,并将其安装名称写入其
    LC\u LOAD\u dylib
    LOAD命令。这样的程序将无法在缺少libSystem.C.dylib的系统上启动,这是预期的行为

    dyld
    执行的版本号检查仅限于确保加载库的兼容版本高于生成时使用的库的兼容版本。库的当前版本是somet
    mrowe@angara:~$ ls -lha /usr/lib/libSystem.{,B.}dylib
    -rwxr-xr-x  1 root  wheel    53K Jul  9  2012 /usr/lib/libSystem.B.dylib
    lrwxr-xr-x  1 root  wheel    17B Jul  9  2012 /usr/lib/libSystem.dylib -> libSystem.B.dylib
    mrowe@angara:~$ otool -L /usr/lib/libSystem.dylib | head -2
    /usr/lib/libSystem.dylib:
        /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 169.3.0)
    mrowe@angara:~$