【发布时间】:2023-04-03 14:00:01
【问题描述】:
问题:
是否可以弱链接静态库(Obj-C)?
简短的细节
我确实希望我的自定义静态框架 (MyFramework.framework) 弱链接我的其他自定义静态库 (libMyLibrary.a)。
libMyLibrary.a 背后的功能是可选的,如果 NO libMyLibrary.a 被任何第 3 方应用程序链接,则可以省略使用 MyFramework.framework。
I am using -weak_library。我的测试应用程序抱怨静态链接器无法在 MyFramework 的 ABCTracker.o 符号中找到 MyLibrary 的符号 MyClass:
Undefined symbols for architecture arm64:
"_OBJC_CLASS_$_MyClass", referenced from:
objc-class-ref in MyFramework(ABCTracker.o)
ld: symbol(s) not found for architecture arm64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
如何正确设置弱链接?
详细信息
设置
- Xcode 项目构建静态 Mach-O 二进制文件并将其捆绑到静态框架中。结果是 MyFramework.framework 包。
- 其他项目构建一个静态 Mach-O 二进制文件,结果是一个静态 lib 文件 libMyLibrary.a,其标题为 MyLib.h
- libMyLibrary.a 已从 MyFramework.framework 目标的 Build Phases > Link Binary With Libraries 中移除 (as suggested here) .只有 MyLib.h 可用于使用框架类中的库 API
- 框架和库中均未使用任何位码
- MyFramework.framework、libMyLibrary.a 和自定义应用程序都是用 Objective-C 编写的
-
MyLib.h 只定义了一个 Objective-C 类
MyClass -
MyFramework.framework 使用自己的类
ABCTracker中的MyClass在运行时有条件地检查符号可用性,例如NSClassFromString(@"MyClass") == NULL -
从 MyFramework 目标的 Build Settings 我已将
Other Librarian Flags和Other Linker Flags设置为相同的值-weak_library MyLibrary:OTHER_LDFLAGS = ( "-weak_library", MyLibrary, ); OTHER_LIBTOOLFLAGS = "-weak_library MyLibrary";
结果
- MyFramework.framework 构建正常
-
构建后,我检查了生成的二进制文件中的符号,输出为 emty(静态库中没有符号被内置到静态框架二进制文件中):
$ otool -L MyFramework.framework/MyFramework | grep MyClass -
尽管如此,我没有与 MyLibrary 链接的测试应用程序在构建时出现
ld错误:Undefined symbols for architecture arm64: "_OBJC_CLASS_$_MyClass", referenced from: objc-class-ref in MyFramework(ABCTracker.o) ld: symbol(s) not found for architecture arm64 clang: error: linker command failed with exit code 1 (use -v to see invocation)
我在这里做错了什么?
其他观察
在 MyFramework 目标中,我将 Other Librarian Flags 和 Other Linker Flags 设置为相同的值:
-
-lMyLibrary。结果:otool显示库的符号已内置到框架中(预期)。 -
-weak-lMyLibrary。结果与lMyLibrary相同(是预期的吗?)
在我的应用程序目标中,我将Other Linker Flags 设置为-force_load MyLibrary。结果:链接器错误略有变化:
ld: file not found: MyClass
clang: error: linker command failed with exit code 1 (use -v to see invocation)
【问题讨论】:
-
你有没有想过如何做到这一点?我曾多次为同样的问题而苦苦挣扎。我有一个解决方法,我将在下面发布作为答案,但它不如让 XCode 实际上弱链接静态库那么干净
-
我解决了最初的问题(为了简单起见,我没有在这里发布)。问题是符号重复,当 MyFramework.framework 和 my application staticky 与 libMyLibrary.a 链接时。我认为弱链接库可以解决符号重复问题。不过,我采取了另一种方式,在静态库编译期间重新定义符号:将
OTHER_CFLAGS设置为-DMyClass =MyPrefixMyClass。 MyFramework.framework 和 my application 需要单独的构建目标。 -
听起来您从未完全解决过
-weak-lMyLibrary导致与-lMyLibrary相同(错误)包含符号的问题? -
@Danny 正确。
标签: ios objective-c xcode linker static-libraries