我正在使用 NDK(r19b)创建一个 Android 库,支持 arm
、aarch64
、x86
和 x86_64
架构。一切正常,只有在为 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
。
【更新】
本问题中显示的示例正在使用ndk-build
,如果您正在使用带有Gradle的Android Studio,那么您很可能会使用CMake
。在这种情况下,请将编译器标志添加如下。[app/build.gradle]
android {
...
defaultConfig {
externalNativeBuild {
cmake {
cppFlags '-fuse-ld=lld'
}