繁体   English   中英

Mach-O平台上的库版本控制

[英]Library versioning on Mach-O platforms

SOVERSION目标属性的文档提到在Mach-O系统(例如OS X和iOS)上,它对应于“兼容版本”,而VERSION对应于“当前版本”。

在Linux上,它与VERSION 5.4.2SOVERSION 5类似,表明该库与5.0版及更高版本兼容,并且VERSION在Windows上以<major>.<minor>形式用作DLL映像版本(I我不确定SOVERSION在Windows上有何不同)。

但是, 文档中所引用的FRAMEWORK目标属性的示例说明了如何在Mach-O平台上VERSION 16.4.0SOVERSION 1.0.0 (我对构建框架不感兴趣,只是想知道外部版本控制方案。)

在Mach-O世界中版本控制是如何工作的? 如果删除某些功能(如果会破坏兼容性),我习惯于碰到主要版本,那么16.4.0版的库如何与该库的1.0.0版保持兼容? “兼容”是什么意思?

首先,只是为了解决这个问题,框架只是被命名为Something.framework/Something而不是libsomething.dylib 但是,文件格式完全相同,因此在本篇文章中,我仅将它们称为dylib。

现在,让我们从mach-o/loader.h标头(Mach-O文件格式的实际权威源)摘录开始:

/*
 * Dynamicly linked shared libraries are identified by two things.  The
 * pathname (the name of the library as found for execution), and the
 * compatibility version number.  The pathname must match and the compatibility
 * number in the user of the library must be greater than or equal to the
 * library being used.  The time stamp is used to record the time a library was
 * built and copied into user so it can be use to determined if the library used
 * at runtime is exactly the same as used to built the program.
 */
struct dylib {
    union lc_str  name;         /* library's path name */
    uint32_t timestamp;         /* library's build time stamp */
    uint32_t current_version;       /* library's current version number */
    uint32_t compatibility_version; /* library's compatibility vers number*/
};

/*
 * A dynamically linked shared library (filetype == MH_DYLIB in the mach header)
 * contains a dylib_command (cmd == LC_ID_DYLIB) to identify the library.
 * An object that uses a dynamically linked shared library also contains a
 * dylib_command (cmd == LC_LOAD_DYLIB, LC_LOAD_WEAK_DYLIB, or
 * LC_REEXPORT_DYLIB) for each library it uses.
 */
struct dylib_command {
    uint32_t    cmd;        /* LC_ID_DYLIB, LC_LOAD_{,WEAK_}DYLIB,
                       LC_REEXPORT_DYLIB */
    uint32_t    cmdsize;    /* includes pathname string */
    struct dylib    dylib;      /* the library identification */
};

如评论中所述, struct dylib既嵌入在库中,又嵌入到与其链接的二进制文件中,都包含current_versioncompatibility_version的副本。 后者的工作方式已在此处进行了说明,但前者未解决。
可以在dyld手册页上找到有关该文档的信息(源在这里 ,但是在man之外看起来并不漂亮):

DYLD_VERSIONED_FRAMEWORK_PATH
    This  is a colon separated list of directories that contain potential override frame-
    works.  The dynamic linker searches  these  directories  for  frameworks.   For  each
    framework  found  dyld  looks  at  its  LC_ID_DYLIB  and gets the current_version and
    install name.  Dyld then looks for the framework at the install name path.  Whichever
    has the larger current_version value will be used in the process whenever a framework
    with that install name is required.  This is similar  to  DYLD_FRAMEWORK_PATH  except
    instead  of  always overriding, it only overrides is the supplied framework is newer.
    Note: dyld does not check the framework's Info.plist to find its version.  Dyld  only
    checks the -current_version number supplied when the framework was created.

[...]

DYLD_VERSIONED_LIBRARY_PATH
    This is a colon  separated  list  of  directories  that  contain  potential  override
    libraries.  The dynamic linker searches these directories for dynamic libraries.  For
    each library found dyld looks at its LC_ID_DYLIB and  gets  the  current_version  and
    install  name.   Dyld then looks for the library at the install name path.  Whichever
    has the larger current_version value will be used in the  process  whenever  a  dylib
    with  that  install  name  is  required.  This is similar to DYLD_LIBRARY_PATH except
    instead of always overriding, it only overrides is the supplied library is newer.

简而言之:

  • compatibility_version用于确定库是否对于要加载的二进制文件来说“足够新”。
  • 当多个库可用时,使用current_version选择库。

关于您对当前版本为16.4.01.0.0兼容版本的困惑:从某些资料来源看 ,只要引入任何功能,Apple似乎16.4.0主要版本,并使用次要版本( s)仅适用于错误修复,即AFAIK。
所以他们称之为16.4.0 ,我可能会称之为1.16.4 ;)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM