Android NDK会生成仅具有一个功能的海量.so文件

时间:2019-04-16 06:34:56

标签: android c++ android-ndk

使用Android NDK构建此.so文件时,我得到 800KB 文件:

test.cpp

cpp

CMakeLists.txt

int *test() {
    return new int;
}

对我来说这是不可接受的尺寸。如果对此有任何错误,请纠正我。


我刚刚意识到,当我删除cmake_minimum_required(VERSION 3.4.1) set(SOURCE_FILES test.cpp) add_library(native_util SHARED ${SOURCE_FILES}) 中的new int时,test.cpp文件的大小减小到80KB ...嗯,怎么可能的?

test.cpp 会生成 80KB .so文件

.so

我的NDK版本:

int test() {
    return 0;
}

1 个答案:

答案 0 :(得分:3)

简单来说,取决于共享库中包含多少个所需的外部符号。

  

我刚刚意识到,当我在test.cpp中删除新的int时,.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大小实际上比您不可接受的小得多。

此外,如果您有兴趣,请交叉检查以下引用: