"local symbol '__bss_start' in global part of symbol table" 仅在 Android NDK aarch64 构建中
"local symbol '__bss_start' in global part of symbol table" only in Android NDK aarch64 build
我正在使用 NDK (r19b) 为 arm
、aarch64
、x86
和 x86_64
创建一个 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
是本地的而不是全球的,但我没有(或者至少我认为我没有)为 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
,如果您将 Android Studio 与 Gradle 一起使用,您很可能会使用 CMake
。在这种情况下,添加您的编译器标志如下。
[app/build.gradle]
android {
...
defaultConfig {
externalNativeBuild {
cmake {
cppFlags '-fuse-ld=lld'
}
APP_LDFLAGS := -Wl,-fvisibility=hidden
这有什么作用吗?这个选项没有出现在 bfd 的帮助页面中,但这些符号是由链接器发出的,所以我想知道这是否是导致此问题的原因。
如果失败,请尝试添加 -fuse-ld=gold
(或者 -fuse-ld=lld
,如果您喜欢冒险,但是如果您需要支持的话,还有许多 Windows KI ) 到您的 APP_LDFLAGS
。 arm64和NDK中其他架构最大的区别就是arm64我们仍然使用bfd
由于这些是由链接器发出的符号,这似乎是最有可能的罪魁祸首。
我在使用外部 libExternal.so
文件时遇到了这个问题。
因为我没有源码,所以无法用LLD重新构建。
我最终能够通过在我的项目中禁用 linker 警告来使用 libExternal.so
文件。
这个 link 很有帮助 https://github.com/android/ndk/issues/927
我在 AOSP (Android 10) 中制作了一个 JNI android 应用程序,它使用 sample.cpp
文件,该文件使用 libExternal.so
。
我的应用程序能够使用 mm 命令构建并在设备上正常运行。
这是我在 AOSP 构建中使用的 Android.mk
文件 (Android 10)。
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := External
LOCAL_SRC_FILES := libExternal.so
LOCAL_MODULE_TAGS := samples
#LOCAL_MODULE_TAGS := optional
LOCAL_MODULE_SUFFIX := .so
LOCAL_MODULE_CLASS := SHARED_LIBRARIES
#LOCAL_LDFLAGS += -fuse-ld=gold
#LOCAL_EXPORT_LDFLAGS += -fuse-ld=gold
#LOCAL_DISABLE_FATAL_LINKER_WARNINGS := true
include $(BUILD_PREBUILT)
include $(CLEAR_VARS)
LOCAL_MODULE := c++
LOCAL_SRC_FILES := libc++.so
LOCAL_MODULE_SUFFIX := .so
LOCAL_MODULE_CLASS := SHARED_LIBRARIES
#LOCAL_LDFLAGS += -fuse-ld=gold
#LOCAL_EXPORT_LDFLAGS += -fuse-ld=gold
#LOCAL_DISABLE_FATAL_LINKER_WARNINGS := true
include $(BUILD_PREBUILT)
include $(CLEAR_VARS)
LOCAL_MODULE := libsample
LOCAL_C_INCLUDES := $(LOCAL_PATH)/include
#LOCAL_DISABLE_FATAL_LINKER_WARNINGS := true
#LOCAL_CFLAGS += -Iinclude
LOCAL_SRC_FILES := sample.cpp
LOCAL_REQUIRED_MODULES := External
#LOCAL_SHARED_LIBRARIES := External cdsprpc cutils c++ base log
LOCAL_SHARED_LIBRARIES := External
LOCAL_MODULE_TARGET_ARCH := arm64
#LOCAL_MODULE_TARGET_ARCH := arm64-v8a
#LOCAL_LDLIBS += $(LOCAL_PATH)/libExternal.so
#
LOCAL_CFLAGS += -Wall -std=c99 -g
LOCAL_CPPFLAGS += -Wall -std=c++03 -D_GLIBCXX_USE_CXX11_ABI=0 -g
# Does not build even after commenting below line
#LOCAL_LDLIBS := -lm -lstdc++ -ldl
#LOCAL_LDFLAGS += -fuse-ld=gold
#LOCAL_EXPORT_LDFLAGS += -fuse-ld=gold
#include $(BUILD_EXECUTABLE)
LOCAL_DISABLE_FATAL_LINKER_WARNINGS := true
LOCAL_LDFLAGS := -Wl,--no-fatal-warnings
include $(BUILD_SHARED_LIBRARY)
include $(CLEAR_VARS)
res_dir := res $(LOCAL_PATH)/res
#LOCAL_MODULE_TAGS := optional
LOCAL_MODULE_TAGS := samples
LOCAL_SRC_FILES := $(call all-java-files-under, java)
LOCAL_RESOURCE_DIR := $(addprefix $(LOCAL_PATH)/, $(res_dir))
LOCAL_USE_AAPT2 := true
LOCAL_JAVA_LIBRARIES := com.google.android.material_material
LOCAL_STATIC_ANDROID_LIBRARIES := \
androidx.appcompat_appcompat \
androidx-constraintlayout_constraintlayout \
androidx.preference_preference \
androidx.fragment_fragment \
androidx.core_core
#LOCAL_REQUIRED_MODULES := sample External
LOCAL_REQUIRED_MODULES := External \
libsample \
libc++
LOCAL_SHARED_LIBRARIES := External \
libsample \
libc++
#LOCAL_LDLIBS += -lsample
LOCAL_JNI_SHARED_LIBRARIES := libsample libc++
#LOCAL_JNI_SHARED_LIBRARIES := libsample
#LOCAL_PREBUILT_JNI_LIBS := $(LOCAL_PATH)/libsample.so
LOCAL_PREBUILT_JNI_LIBS := libExternal.so
LOCAL_CERTIFICATE := platform
LOCAL_PRIVILEGED_MODULE := true
LOCAL_PACKAGE_NAME := NativeCPP
LOCAL_PRIVATE_PLATFORM_APIS := true
include $(BUILD_PACKAGE)
我正在使用 NDK (r19b) 为 arm
、aarch64
、x86
和 x86_64
创建一个 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
是本地的而不是全球的,但我没有(或者至少我认为我没有)为 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
,如果您将 Android Studio 与 Gradle 一起使用,您很可能会使用 CMake
。在这种情况下,添加您的编译器标志如下。
[app/build.gradle]
android {
...
defaultConfig {
externalNativeBuild {
cmake {
cppFlags '-fuse-ld=lld'
}
APP_LDFLAGS := -Wl,-fvisibility=hidden
这有什么作用吗?这个选项没有出现在 bfd 的帮助页面中,但这些符号是由链接器发出的,所以我想知道这是否是导致此问题的原因。
如果失败,请尝试添加 -fuse-ld=gold
(或者 -fuse-ld=lld
,如果您喜欢冒险,但是如果您需要支持的话,还有许多 Windows KI ) 到您的 APP_LDFLAGS
。 arm64和NDK中其他架构最大的区别就是arm64我们仍然使用bfd
由于这些是由链接器发出的符号,这似乎是最有可能的罪魁祸首。
我在使用外部 libExternal.so
文件时遇到了这个问题。
因为我没有源码,所以无法用LLD重新构建。
我最终能够通过在我的项目中禁用 linker 警告来使用 libExternal.so
文件。
这个 link 很有帮助 https://github.com/android/ndk/issues/927
我在 AOSP (Android 10) 中制作了一个 JNI android 应用程序,它使用 sample.cpp
文件,该文件使用 libExternal.so
。
我的应用程序能够使用 mm 命令构建并在设备上正常运行。
这是我在 AOSP 构建中使用的 Android.mk
文件 (Android 10)。
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := External
LOCAL_SRC_FILES := libExternal.so
LOCAL_MODULE_TAGS := samples
#LOCAL_MODULE_TAGS := optional
LOCAL_MODULE_SUFFIX := .so
LOCAL_MODULE_CLASS := SHARED_LIBRARIES
#LOCAL_LDFLAGS += -fuse-ld=gold
#LOCAL_EXPORT_LDFLAGS += -fuse-ld=gold
#LOCAL_DISABLE_FATAL_LINKER_WARNINGS := true
include $(BUILD_PREBUILT)
include $(CLEAR_VARS)
LOCAL_MODULE := c++
LOCAL_SRC_FILES := libc++.so
LOCAL_MODULE_SUFFIX := .so
LOCAL_MODULE_CLASS := SHARED_LIBRARIES
#LOCAL_LDFLAGS += -fuse-ld=gold
#LOCAL_EXPORT_LDFLAGS += -fuse-ld=gold
#LOCAL_DISABLE_FATAL_LINKER_WARNINGS := true
include $(BUILD_PREBUILT)
include $(CLEAR_VARS)
LOCAL_MODULE := libsample
LOCAL_C_INCLUDES := $(LOCAL_PATH)/include
#LOCAL_DISABLE_FATAL_LINKER_WARNINGS := true
#LOCAL_CFLAGS += -Iinclude
LOCAL_SRC_FILES := sample.cpp
LOCAL_REQUIRED_MODULES := External
#LOCAL_SHARED_LIBRARIES := External cdsprpc cutils c++ base log
LOCAL_SHARED_LIBRARIES := External
LOCAL_MODULE_TARGET_ARCH := arm64
#LOCAL_MODULE_TARGET_ARCH := arm64-v8a
#LOCAL_LDLIBS += $(LOCAL_PATH)/libExternal.so
#
LOCAL_CFLAGS += -Wall -std=c99 -g
LOCAL_CPPFLAGS += -Wall -std=c++03 -D_GLIBCXX_USE_CXX11_ABI=0 -g
# Does not build even after commenting below line
#LOCAL_LDLIBS := -lm -lstdc++ -ldl
#LOCAL_LDFLAGS += -fuse-ld=gold
#LOCAL_EXPORT_LDFLAGS += -fuse-ld=gold
#include $(BUILD_EXECUTABLE)
LOCAL_DISABLE_FATAL_LINKER_WARNINGS := true
LOCAL_LDFLAGS := -Wl,--no-fatal-warnings
include $(BUILD_SHARED_LIBRARY)
include $(CLEAR_VARS)
res_dir := res $(LOCAL_PATH)/res
#LOCAL_MODULE_TAGS := optional
LOCAL_MODULE_TAGS := samples
LOCAL_SRC_FILES := $(call all-java-files-under, java)
LOCAL_RESOURCE_DIR := $(addprefix $(LOCAL_PATH)/, $(res_dir))
LOCAL_USE_AAPT2 := true
LOCAL_JAVA_LIBRARIES := com.google.android.material_material
LOCAL_STATIC_ANDROID_LIBRARIES := \
androidx.appcompat_appcompat \
androidx-constraintlayout_constraintlayout \
androidx.preference_preference \
androidx.fragment_fragment \
androidx.core_core
#LOCAL_REQUIRED_MODULES := sample External
LOCAL_REQUIRED_MODULES := External \
libsample \
libc++
LOCAL_SHARED_LIBRARIES := External \
libsample \
libc++
#LOCAL_LDLIBS += -lsample
LOCAL_JNI_SHARED_LIBRARIES := libsample libc++
#LOCAL_JNI_SHARED_LIBRARIES := libsample
#LOCAL_PREBUILT_JNI_LIBS := $(LOCAL_PATH)/libsample.so
LOCAL_PREBUILT_JNI_LIBS := libExternal.so
LOCAL_CERTIFICATE := platform
LOCAL_PRIVILEGED_MODULE := true
LOCAL_PACKAGE_NAME := NativeCPP
LOCAL_PRIVATE_PLATFORM_APIS := true
include $(BUILD_PACKAGE)