1

I get 800KB .so file when build this cpp file with android NDK:

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})

It's unacceptable size for me. Correct me if anything wrong about this.


I just realized when I remove new int in test.cpp , then .so file size reduce to 80KB... hmm, how possible???

test.cpp which produce 80KB .so file

int test() {
    return 0;
}

My NDK version:

Android/sdk/ndk-bundle 
➜ cat source.properties 
Pkg.Desc = Android NDK
Pkg.Revision = 19.2.5345600
shizhen
  • 12,251
  • 9
  • 52
  • 88
Khang .NT
  • 1,504
  • 6
  • 24
  • 46

1 Answers1

3

Simply speaking, it is up to how many needed external symbols included into your shared library.

I just realized when I remove new int in test.cpp , then .so file size reduce to 80KB... hmm, how possible???

This is possible. Because, below code

// test.cpp
int *test() {
    return new int;
}

the new operator depends on other C++ libraries, when you build your test.cpp, the shared library, e.g. test_with_new_operator.so file will add those external symbol information for future usage during the linking phase, e.g. the std::xxx symbols needed. When you change it to

// test.cpp which produce 80KB .so file
int test() {
    return 0;
}

it won't depend on the C++ std libraries and those symbol information won't be added into your test_without_new_operator.so and you will see a smaller size.

For example, when you issue command

nm --demangle ./libs/armeabi-v7a/libnative-lib.so

the test_with_new_operator.so includes below symbol information (more external symbol information!!!)

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, 
...

But, test_without_new_operator.so won't have these symbols and the library size is smaller.


Edit #1

It's unacceptable size for me. Correct me if anything wrong about this.

You don't need to worry too much about this, because when you package those shared libraries into the final apk, the unnecessary symbols and debug information will be stripped (gradle task app:transformNativeLibsWithStripDebugSymbolForRelease will do this job) and your final apk size actually is much smaller than what is unacceptable for you.

Also, cross check below references if you have interests:

shizhen
  • 12,251
  • 9
  • 52
  • 88