我正在为arm
,aarch64
,x86
和x86_64
创建一个带NDK(r19b)的Android库。一切都很好,除了当我为aarch64
架构构建应用程序时,我收到以下错误消息。
ld.lld: error: found local symbol '_edata' in global part of symbol table in file libmystuff.so
ld.lld: error: found local symbol '_end' in global part of symbol table in file libmystuff.so
ld.lld: error: found local symbol '__bss_start' in global part of symbol table in file libmystuff.so
当我用readelf -s libmystuff.so
检查每个构建变体时,我注意到只有aarch64
是不同的。
[arm]
4021: 007a30f0 0 NOTYPE GLOBAL DEFAULT ABS _edata
4022: 007c6b10 0 NOTYPE GLOBAL DEFAULT ABS _end
4023: 007a30f0 0 NOTYPE GLOBAL DEFAULT ABS __bss_start
[x86]
3848: 00c82c88 0 NOTYPE GLOBAL DEFAULT ABS _edata
3849: 00ca4b28 0 NOTYPE GLOBAL DEFAULT ABS _end
3850: 00c82c88 0 NOTYPE GLOBAL DEFAULT ABS __bss_start
[x86_64]
3874: 0000000000c9b890 0 NOTYPE GLOBAL DEFAULT ABS _edata
3875: 0000000000ce5f68 0 NOTYPE GLOBAL DEFAULT ABS _end
3876: 0000000000c9b890 0 NOTYPE GLOBAL DEFAULT ABS __bss_start
[aarch64]
3: 0000000000b4f168 0 NOTYPE LOCAL DEFAULT ABS _edata
4: 0000000000b990e8 0 NOTYPE LOCAL DEFAULT ABS _end
5: 0000000000b4f168 0 NOTYPE LOCAL DEFAULT ABS __bss_start
865: 0000000000b9e3e8 0 NOTYPE GLOBAL DEFAULT ABS __end__
2468: 0000000000b54168 0 NOTYPE GLOBAL DEFAULT ABS __bss_start__
我当然可以看到_edata
,_end
和__bss_start
在LOCAL而不是GLOBAL,但我不(或者至少我认为我没有)为aarch64
做任何特别的事情;它们都使用相同的构建配置。
jni/Application.mk
NDK_TOOLCHAIN_VERSION := clang
APP_STL := c++_static
APP_CFLAGS := -fstack-protector-all -fvisibility=hidden -ffunction-sections -fdata-sections
APP_CPPFLAGS := -fstack-protector-all -std=c++11 -fvisibility=hidden -ffunction-sections -fdata-sections -frtti
APP_LDFLAGS := -Wl,--gc-sections,-fvisibility=hidden,--strip-debug
那么,为什么aarch64
不同?更好的是,我如何将它们移到GLOBAL?
[更新]感谢https://github.com/android-ndk/ndk/issues/927的温柔人士,我发现解决方案效果最好;最后注意“-fuse-ld = lld”。
APP_LDFLAGS := -Wl,--gc-sections,--strip-debug -fvisibility=hidden -fuse-ld=lld
这样,我仍然保持--gc-sections
,--no-fatal-warnings
也没有必要。
APP_LDFLAGS := -Wl,-fvisibility=hidden
这有什么用吗?这个选项没有出现在bfd的帮助页面中,但这些符号是由链接器发出的,所以我想知道是不是这就是造成这种情况的原因。
如果做不到这一点,尝试添加-fuse-ld=gold
(或-fuse-ld=lld
,如果你喜欢冒险,但有许多Windows KI,如果这是你需要支持的东西)到你的APP_LDFLAGS
。 arm64与NDK中其他架构的最大区别在于我们仍然使用bfd for arm64。
由于这些是链接器发出的符号,这似乎是最可能的罪魁祸首。