C 如何使用dyld不忽略最大版本
我正在尝试在OS X(10.7.5)下对共享库进行版本设置,但在让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版,
dyld
识别最大兼容版本(最低版本可以)时遇到了问题。考虑下面的测试代码和下面的场景:
按预期工作binary
:otool-L二进制文件
libdyldtest.dylib(兼容版本1.0.0,当前版本1.0.0)
:otool-L libdyldtest.dylib
libdyldtest.dylib(兼容版本1.0.0,当前版本1.0.0)
应该仍然有效,而且确实有效,因为库的兼容性已经足够老了binary
:otool-L二进制文件
libdyldtest.dylib(兼容版本1.0.0,当前版本1.0.0)
:otool-L libdyldtest.dylib
libdyldtest.dylib(兼容版本1.0.0,当前版本2.0.0)
应该停止工作,因为它希望与1.0兼容,但binary
仅与3.0及更高版本兼容。为什么这样做有效?libdyldtest
: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
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:~$