Android NDK生成海量只有一个功能的.so文件
Android NDK produce massive .so file which has only one function
使用 android NDK 构建此cpp
文件时,我得到800KB.so
文件:
测试.cpp
int *test() {
return new int;
}
CMakeList.txt
cmake_minimum_required(VERSION 3.4.1)
set(SOURCE_FILES test.cpp)
add_library(native_util SHARED ${SOURCE_FILES})
这对我来说是不可接受的尺寸。如果有任何错误,请纠正我。
我刚刚意识到当我在test.cpp
中删除new int
时,.so
文件大小减小到 80KB......嗯,怎么可能???
测试.cpp生成80KB.so
文件
int test() {
return 0;
}
我的 NDK 版本:
Android/sdk/ndk-bundle
➜ cat source.properties
Pkg.Desc = Android NDK
Pkg.Revision = 19.2.5345600
简单地说,这取决于您的共享库中包含多少所需的外部符号。
我刚刚意识到当我在测试中删除新的 int 时.cpp ,然后 .so 文件大小减小到 80KB......嗯,怎么可能???
这是可能的。因为,下面的代码
// test.cpp
int *test() {
return new int;
}
new
运算符依赖于其他C++库,当您构建test.cpp
时,共享库,例如test_with_new_operator.so
文件将添加这些外部符号信息,以供将来在链接阶段使用,例如所需的std::xxx
符号。当您将其更改为
// test.cpp which produce 80KB .so file
int test() {
return 0;
}
它不依赖于 C++ STD 库,这些符号信息不会添加到您的test_without_new_operator.so
并且您将看到更小的大小。
例如,当您发出命令时
nm --demangle ./libs/armeabi-v7a/libnative-lib.so
test_with_new_operator.so
包括以下符号信息(更多外部符号信息!!)
0001ba44 r GCC_except_table0
0001b668 r GCC_except_table0
0001b698 r GCC_except_table1
0001ba98 r GCC_except_table1
0001b568 r GCC_except_table1
0001b9b8 r GCC_except_table1
...
0000622c T std::bad_array_length::bad_array_length()
0000623c T std::bad_array_length::~bad_array_length()
000061c8 T std::bad_array_length::~bad_array_length()
000061c8 T std::bad_array_length::~bad_array_length()
...
00017222 t std::__ndk1::__vector_base<std::__ndk1::vector<__cxxabiv1::(anonymous namespace)::string_pair<std::__ndk1::basic_string<char, std::__ndk1::char_traits<char>, __cxxabiv1::(anonymous namespace)::malloc_alloc<char> > >, __cxxabiv1::(anonymous namespace)::short_alloc<__cxxabiv1::(anonymous namespace)::string_pair<std::__ndk1::basic_string<char, std::__ndk1::char_traits<char>, __cxxabiv1::(anonymous namespace)::malloc_alloc<char> > >, 4096u> >, __cxxabiv1::(anonymous namespace)::short_alloc<std::__ndk1::vector<__cxxabiv1::(anonymous namespace)::string_pair<std::__ndk1::basic_string<char, std::__ndk1::char_traits<char>, __cxxabiv1::(anonymous namespace)::malloc_alloc<char> > >, __cxxabiv1::(anonymous namespace)::short_alloc<__cxxabiv1::(anonymous namespace)::string_pair<std::__ndk1::basic_string<char, std::__ndk1::char_traits<char>, __cxxabiv1::(anonymous namespace)::malloc_alloc<char> > >, 4096u> >, 4096u> >::~__vector_base()
0001867a t std::__ndk1::__vector_base<std::__ndk1::vector<std::__ndk1::vector<__cxxabiv1::(anonymous namespace)::string_pair<std::__ndk1::basic_string<char, std::__ndk1::char_traits<char>, __cxxabiv1::(anonymous namespace)::malloc_alloc<char> > >, __cxxabiv1::(anonymous namespace)::short_alloc<__cxxabiv1::(anonymous namespace)::string_pair<std::__ndk1::basic_string<char, std::__ndk1::char_traits<char>, __cxxabiv1::(anonymous namespace)::malloc_alloc<char> > >, 4096u> >, __cxxabiv1::(anonymous namespace)::short_alloc<std::__ndk1::vector<__cxxabiv1::(anonymous namespace)::string_pair<std::__ndk1::basic_string<char, std::__ndk1::char_traits<char>, __cxxabiv1::(anonymous namespace)::malloc_alloc<char> > >, __cxxabiv1::(anonymous namespace)::short_alloc<__cxxabiv1::(anonymous namespace)::string_pair<std::__ndk1::basic_string<char, std::__ndk1::char_traits<char>, __cxxabiv1::(anonymous namespace)::malloc_alloc<char> > >, 4096u> >, 4096u> >, __cxxabiv1::(anonymous namespace)::short_alloc<std::__ndk1::vector<std::__ndk1::vector<__cxxabiv1::(anonymous namespace)::string_pair<std::__ndk1::basic_string<char, std::__ndk1::char_traits<char>, __cxxabiv1::(anonymous namespace)::malloc_alloc<char> > >, __cxxabiv1::(anonymous namespace)::short_alloc<__cxxabiv1::(anonymous namespace)::string_pair<std::__ndk1::basic_string<char, std::__ndk1::char_traits<char>, __cxxabiv1::(anonymous namespace)::malloc_alloc<char> > >, 4096u> >, __cxxabiv1::(anonymous namespace)::short_alloc<std::__ndk1::vector<__cxxabiv1::(anonymous namespace)::string_pair<std::__ndk1::basic_string<char, std::__ndk1::char_traits<char>, __cxxabiv1::(anonymous namespace)::malloc_alloc<char> > >, __cxxabiv1::(anonymous namespace)::short_alloc<__cxxabiv1::(anonymous namespace)::string_pair<std::__ndk1::basic_string<char, std::__ndk1::char_traits<char>, __cxxabiv1::(anonymous namespace)::malloc_alloc<char> > >, 4096u> >, 4096u> >, 4096u> >::~__vector_base()
0000e304 t std::__ndk1::__split_buffer<__cxxabiv1::(anonymous namespace)::string_pair<std::__ndk1::basic_string<char,
...
但是,test_without_new_operator.so
不会有这些符号,并且库大小更小。
编辑 #1
这对我来说是不可接受的尺寸。如果有任何错误,请纠正我。
您不需要太担心这一点,因为当您将这些共享库打包到最终的 apk 中时,不必要的符号和调试信息将被剥离(gradle 任务app:transformNativeLibsWithStripDebugSymbolForRelease
将完成这项工作),并且您的最终 apk 大小实际上比您无法接受的大小小得多。
另外,如果您有兴趣,请交叉检查以下参考资料:
- 如何减小安卓原生共享库(.so 文件)的大小?
- CMake 构建工具链中"strip"命令的 Android NDK 路径变量
- 如何防止 CMAKE 剥离创建的共享库
- 在执行其他功能的同时播放动画(LED矩阵和Arduino/ESP8266)
- 多态性和功能结合
- 如何使用ndk-build.cmd构建Android.so文件
- 带内存和隔离功能的SQLite
- 在CMakeLists.txt的安装功能中使用.cmake文件有什么用
- 类模板的成员功能的定义在单独的TU中完全专业化
- 有没有一种方法可以创建一个带有哈希表的数据库,该哈希表具有恒定时间查找功能
- 如何在C++中获得"静态纯虚拟"功能?
- 两个文件使用彼此的功能-如何解决
- 我应该实现右值推送功能吗?我应该使用std::move吗
- QML按钮点击功能执行顺序
- 在C++代码中包含opencv时,使用ctypes创建.so文件
- 无法理解此 return 语句的功能,没有它就会发生运行时错误
- 有没有可能有一个只有ADL才能找到的非好友功能
- 功能样式转换从 'int' 到 'ItemType' 的匹配转换
- 文件系统:复制功能的速度秘诀是什么
- 在用于格式4的arm模拟器中实现功能时的一个问题
- 如何在Directwrite中获得给定字体的可用OpenType功能
- 来自Pascal DLL/SO中的C 加载和调用功能
- Android NDK生成海量只有一个功能的.so文件