假设我们正在构建一个共享库 A,它需要链接到 2 个外部静态库 B 和 C。您所拥有的只是 libB.a 和 libC.a,以及它们的头文件。
这是 libA 的简化 Android.mk:
LOCAL_LDLIBS := ../external/libB.a ../external/libC.a
include $(BUILD_SHARED_LIBRARY)
AFAIK,共享库的链接方式是:
- 获取 B 和 C 的所有目标文件
- 去掉 A 没有引用的目标文件
- 解析 B 和 C 中的引用
这会导致链接错误,因为 B 和 C 相互调用,特别是它们调用在步骤 2 中被剥离的函数,因为 A 没有调用它们。
如果我们自己构建静态库,那么只需将 LOCAL_STATIC_LIBRARIES 替换为 LOCAL_WHOLE_STATIC_LIBRARIES,这可以防止代码剥离(以牺牲代码大小为代价)。在引擎盖下,它将 --whole-archive 传递给链接器。
由于我们没有构建 B 和 C(甚至没有重建它们的源代码),有哪些选择?
- 手动引用 A 中缺少的函数,以免它们被剥离
- 弄清楚如何将 --whole-archive 传递给外部静态库的链接器
- 使用 PREBUILT_STATIC_LIBRARY (看到它提到,但从未使用过它,根据文档,它在这种情况下听起来不适用)
- 构建可执行文件而不是共享库(不会以相同的方式剥离代码)
- 移动/重命名外部库以欺骗 NDK 构建系统认为它们是我的,以便我可以将它们添加到 LOCAL_WHOLE_STATIC_LIBRARIES。
我选择了选项 1,因为它是第一个有效的方法,但显然它不是很好。我在问是否有更好的解决方案。
这个问题的答案(Linking issue when prebuilt static and shared libraries with the Android NDK)让我想知道我是否需要重新评估我的构建设置(共享库链接到外部静态库)。我无法在那里发表评论,所以我在这里问了我自己的问题。