Android NDK产生大量只有一个功能的.so文件
Android NDK produce massive .so file which has only one function
当使用 android NDK 构建此 cpp
文件时,我得到 800KB .so
文件:
test.cpp
int *test() {
return new int;
}
CMakeLists.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...嗯,这怎么可能???
test.cpp 产生 80KB .so
文件
int test() {
return 0;
}
我的 NDK 版本:
Android/sdk/ndk-bundle
➜ cat source.properties
Pkg.Desc = Android NDK
Pkg.Revision = 19.2.5345600
简单来说,取决于你的共享库中包含多少需要的外部符号。
I just realized when I remove new int in test.cpp , then .so file size reduce to 80KB... hmm, how possible???
这是可能的。因为,下面的代码
// 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
It's unacceptable size for me. Correct me if anything wrong about this.
这个你不用太担心,因为当你将那些共享库打包到最终的apk中时,不需要的符号和调试信息将被剥离(gradle任务app:transformNativeLibsWithStripDebugSymbolForRelease
将完成这项工作)并且您最终的 apk 大小实际上比您无法接受的小得多。
此外,如果您有兴趣,请交叉检查以下参考资料:
- how to prevent cmake from stripping the created shared library
当使用 android NDK 构建此 cpp
文件时,我得到 800KB .so
文件:
test.cpp
int *test() {
return new int;
}
CMakeLists.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...嗯,这怎么可能???
test.cpp 产生 80KB .so
文件
int test() {
return 0;
}
我的 NDK 版本:
Android/sdk/ndk-bundle
➜ cat source.properties
Pkg.Desc = Android NDK
Pkg.Revision = 19.2.5345600
简单来说,取决于你的共享库中包含多少需要的外部符号。
I just realized when I remove new int in test.cpp , then .so file size reduce to 80KB... hmm, how possible???
这是可能的。因为,下面的代码
// 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
It's unacceptable size for me. Correct me if anything wrong about this.
这个你不用太担心,因为当你将那些共享库打包到最终的apk中时,不需要的符号和调试信息将被剥离(gradle任务app:transformNativeLibsWithStripDebugSymbolForRelease
将完成这项工作)并且您最终的 apk 大小实际上比您无法接受的小得多。
此外,如果您有兴趣,请交叉检查以下参考资料:
- how to prevent cmake from stripping the created shared library