簡體   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