gpt4 book ai didi

c - 如何不忽略 dyld 的最大版本

转载 作者:太空宇宙 更新时间:2023-11-04 03:56:39 24 4
gpt4 key购买 nike

我正在尝试在 OS X (10.7.5) 下对共享库进行版本控制,但我无法让 dyld 识别最大兼容版本(最低版本也可以)。考虑下面的测试代码和以下场景:

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

    • binary 按预期工作
      • otool -L binary:libdyldtest.dylib(兼容版本1.0.0,当前版本1.0.0)
      • otool -L libdyldtest.dylib:libdyldtest.dylib(兼容版本1.0.0,当前版本1.0.0)
  2. 库已更新并重新编译,移至版本 2.0,兼容版本 1.0

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

    • binary 应该停止 工作,因为它需要与 1.0 兼容的东西,但 libdyldtest 仅与 3.0 及更高版本兼容。 为什么会这样?
      • otool -L binary:libdyldtest.dylib(兼容版本1.0.0,当前版本1.0.0)
      • otool -L libdyldtest.dylib:libdyldtest.dylib(兼容版本3.0.0,当前版本3.0.0)
      • 设置 DYLD_PRINT_LIBRARIES 显示正在加载 libdyldtest.3.0.dylib

问题是上面的 3 个有效,我认为它不应该。这是预期的行为吗?如果不是,我该如何纠正?

注意:相关的dyld source code for 10.7.5似乎没有使用 LibraryInfo 结构的 maxVersion 成员,只有 minVersion。因此,将最低兼容版本设置得较低可以按预期工作:

  • 库设置为版本 0.9,兼容性 0.0
    • binary 按预期停止工作。
      • otool -L binary:libdyldtest.dylib(兼容版本1.0.0,当前版本1.0.0)
      • otool -L libdyldtest.dylib:libdyldtest.dylib(兼容版本0.0.0,当前版本0.9.0)
        • 运行 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");
}

二进制.c:

#include "library.h"

int
main(
int argc,
char *argv[])
{
functionFromLibrary();
return (0);
}

生成文件:

.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)

最佳答案

这是预期的行为。

dyld 执行的版本号检查仅限于确保正在加载的库的兼容性 版本高于所使用的库的兼容性版本构建时间。该库的当前 版本是可以编程访问的,但在评估是否应加载特定库时,dyld 不会使用该版本。您可以通过查看 ld 手册页的 -compatibility_version-current_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 输出的第二行中的安装名称如何指向名称由版本号限定的 dylib 的版本(在情况 B 中)。如果 Apple 要引入 libSystem.dylib 的向后不兼容修订版,他们可以将其放在 /usr/lib/libSystem.C.dylib 并更新 的符号链接(symbolic link)>libSystem.dylib 指向它。现有程序仍会查找 libSystem.B.dylib,因为这是在链接时写入其 LC_LOAD_DYLIB 加载命令的安装名称。任何新链接 libSystem.dylib 的程序都会找到 libSystem.C.dylib 并将其安装名称写入它们的 LC_LOAD_DYLIB 加载命令。这样的程序将无法在缺少 libSystem.C.dylib 的系统上启动。

关于c - 如何不忽略 dyld 的最大版本,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15905310/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com