foo*_*o64 4 android static-libraries android-ndk
假设我们正在构建一个共享库A,它需要链接到2个外部静态库B和C.你所拥有的只是libB.a和libC.a,以及它们的头文件.
这是libA的简化Android.mk:
LOCAL_LDLIBS := ../external/libB.a ../external/libC.a
include $(BUILD_SHARED_LIBRARY)
Run Code Online (Sandbox Code Playgroud)
AFAIK,链接共享库的工作方式是:
这会产生链接错误,因为B和C互相调用,特别是它们调用在步骤2中被删除的函数,因为A没有调用它们.
如果我们自己构建静态库,那么只需用LOCAL_WHOLE_STATIC_LIBRARIES替换LOCAL_STATIC_LIBRARIES就可以防止代码剥离(代码大小).在引擎盖下,它将--whole-archive传递给链接器.
由于我们没有构建B和C(甚至没有重建它们的源),有哪些选择?
我已经选择了1,因为它是第一个有用的东西,但显然它不是很好.我在问是否有更好的解决方案.
这个问题的答案(当使用Android NDK预构建静态和共享库时链接问题)让我想知道是否需要重新评估我的构建设置(链接到外部静态库的共享库).我无法在那里发表评论,所以我在这里问自己的问题.
答案可以在如何使用binutils链接器处理静态库之间的递归依赖关系中找到答案?.
LOCAL_LDLIBS := -L ../external/ -lB -lC -lB
Run Code Online (Sandbox Code Playgroud)
我采用了两个库的NDK样本,并进行了微小的改动以在GitHub上演示该技术.
更新(2017年):自2012年以来,NDK的规则变得更加严格,现在它会抱怨LOCAL_LDLIBS
包含非系统库:
Android NDK:警告:Android.module:链接器标志中的非系统库:-la -lb
Android NDK:这可能导致不正确的构建.尝试使用LOCAL_STATIC_LIBRARIES
Android NDK:或LOCAL_SHARED_LIBRARIES来列出
Android NDK 的库依赖项:当前模块
这只是一个警告,所以你可以忽略它.
或者在-l
智能NDK保护后增加空间:
LOCAL_LDLIBS := -L ../external/ -l B -l C -l B
Run Code Online (Sandbox Code Playgroud)
或者,您可以使用
LOCAL_LDLIBS += -L ../external -Wl,--start-group -l B -l C -Wl,--end-group
Run Code Online (Sandbox Code Playgroud)
如果涉及的库不是预构建的,则无需猜测它们的位置(使用Android Studio NDK集成时可能特别棘手).使用
LOCAL_LDLIBS := -L $(TARGET_OUT) …
Run Code Online (Sandbox Code Playgroud)
存在一种替代方法,其不使用"递归"链接.但它涉及迭代.首先,尝试以通常的方式构建共享库.如果此操作因未解析的符号而失败,请将所有这些符号复制到剪贴板,然后将其粘贴到Android.mk中.假设这些符号是extBa
,, extBb
和extBc
(在上面的场景中,我相信libC的某个对象没有找到在libB中定义的这些符号,这就是链接失败的原因).你现在需要什么,补充一下
LOCAL_LDFLAGS += -Wl,-u'extBa' -Wl,-u'extBb' -Wl,-u'extBc'
Run Code Online (Sandbox Code Playgroud)
您可以进行下一步,并将所有内容与libC捆绑在一起:
LOCAL_EXPORT_LDFLAGS += -Wl,-u'extBa' -Wl,-u'extBb' -Wl,-u'extBc'
Run Code Online (Sandbox Code Playgroud)
现在任何使用libC的共享库都不会错过这些符号.
归档时间: |
|
查看次数: |
9788 次 |
最近记录: |