Android 在最终SO文件中获取调试符号,即使在CMake中构建版本

Android 在最终SO文件中获取调试符号,即使在CMake中构建版本,android,c++,gcc,android-ndk,g++,Android,C++,Gcc,Android Ndk,G++,我正在使用CMake(生成器是ninja)使用NDK工具链(g++4.9)构建一个共享库。下面是我使用ninja构建时在库中构建单个CPP文件的详细输出: [34/164]/usr/local/bin/android ndk/toolschains/arm-linux-androideabi-4.9/prebuild/linux-x86_64/bin/arm-linux-androideabi-g++-DANDROID-DBOOST_ALL_NO_LIB-feexceptions-frti-fp

我正在使用CMake(生成器是ninja)使用NDK工具链(g++4.9)构建一个共享库。下面是我使用ninja构建时在库中构建单个CPP文件的详细输出:

[34/164]/usr/local/bin/android ndk/toolschains/arm-linux-androideabi-4.9/prebuild/linux-x86_64/bin/arm-linux-androideabi-g++-DANDROID-DBOOST_ALL_NO_LIB-feexceptions-frti-fpic-Wno psabi-sysroot=/usr/local/bin/android ndk/platforms/android-15/arch arm-funwind tables-finline limit=64-fsigned char-NO规范前缀-march=arm-a-mfloat abi=softfp-mfpu=vfpv3-d16-fdata段-F功能段-Wa,--noexecstack-mthumb-fomit帧指针-fno严格别名-O3-DNDEBUG-isystem/usr/local/bin/android ndk/platforms/android-15/arch arm/usr/include-isystem/usr/local/bin/android ndk/sources/cxx stl/gnu libstdc++/4.9/include-isystem/usr/local/bin/android ndk/cxx stl/gnu libstdc++/4.9/libs-v7a/include-isystem/usr/local/bin/android ndk/sources/cxx stl/gnu libstdc++/4.9/include/backward-I/usr/local/bin/android ndk/sources/android/cpufeatures-I/usr/local/bin/android ndk/sources/android/native_app_glue-ICore/Artifacts/android-IApplications/Survey/Source-ICore/UI/-ICore/UI/Source-ICore/ThirdParty/PowerVR/sdk/Include-ICore/ThirdParty/PowerVR/tools/Include-ICore/ThirdParty/PowerVR/tools/Include/OGLES2-ICore/ThirdParty/boost/Include-ICore/ThirdParty/openssl/Include-ICore/ThirdParty/sqlite/Include-ICore/WebServices/Source-std=gnu++-14-MMD-MT应用程序/Survey/CMakeFiles/Survey.dir/Source/View/RadioGroup.cpp.o-MF应用程序/Survey/CMakeFiles/Survey.dir/Source/View/RadioGroup.cpp.o-o应用程序/Survey/View/RadioGroup.cpp.o-c应用程序/Survey/Source/View/RadioGroup.cpp

请注意,我在生成时指定了
-DCMAKE\u BUILD\u TYPE=Release

命令行调用中不存在
-g
选项,但最终二进制文件为19MB:

-rwxrwxr-x 1 bamboo bamboo 19173588 Jul 15 10:30 libzApp.so*
我在它上面运行了
size
,以确定是什么使它如此巨大,但我得到了以下结果:

$ size libzApp.so
   text    data     bss     dec     hex filename
7097019  201268   53488 7351775  702ddf libzApp.so
这只占了7mb的数据。所以我运行了这个:

$ objdump --debugging libzApp.so | head -25

libzApp.so:     file format elf32-little

Contents of the .debug_abbrev section:

  Number TAG (0x0)
   1      DW_TAG_compile_unit    [has children]
    DW_AT_producer     DW_FORM_strp
    DW_AT_language     DW_FORM_data1
    DW_AT_name         DW_FORM_strp
    DW_AT_comp_dir     DW_FORM_strp
    DW_AT_low_pc       DW_FORM_addr
    DW_AT_entry_pc     DW_FORM_addr
    DW_AT_ranges       DW_FORM_data4
    DW_AT_stmt_list    DW_FORM_data4
    DW_AT value: 0     DW_FORM value: 0
   2      DW_TAG_typedef    [no children]
    DW_AT_name         DW_FORM_strp
    DW_AT_decl_file    DW_FORM_data1
    DW_AT_decl_line    DW_FORM_data1
    DW_AT_type         DW_FORM_ref4
    DW_AT value: 0     DW_FORM value: 0
   3      DW_TAG_base_type    [no children]
    DW_AT_byte_size    DW_FORM_data1
    DW_AT_encoding     DW_FORM_data1
我认为这基本上证实了它有调试符号。有谁能帮我理解为什么。这么大?假设这是因为调试符号,那么命令行调用会导致什么呢

编辑
正如注释部分所建议的,在SO文件上运行
strip
肯定会将其大小降低到预期值(基本上就是我们从
size
命令的结果中看到的)。然而,当我特别告诉GCC不要构建调试符号时,为什么要将调试符号构建到共享对象中?我在这里遗漏了什么吗?

我可以建议您使用
strip
删除调试信息,例如:

strip libzApp.so
这样做并不坏,因为,例如,Qt的构建系统
qmake
总是在生成的Makefile的
install
目标中这样做

默认情况下,编译器总是将重新定位信息和符号表添加到二进制文件中。它还添加了许多其他可能被删除的信息(参见下面答案的链接)

您还可以对编译器使用
-s
参数:

g++ -s ...
根据文件:

-s:


此标志应与
条带
完全相同。这也是。

你能确认在
剥离之后尺寸仍然相同吗?
是的,剥离将其缩小到预期尺寸:
$ll libzApp.so
--
-rwxr-x 1竹竿7301876年7月15日11:18 libzApp。那么*
这解决了你的问题吗?您还可以尝试删除“-DNDEBUG”吗?为什么我需要
strip
符号?如果我没有告诉gcc构建调试符号,为什么它们首先存在?我将尝试删除NDEBUG并让您知道它是如何运行的,但我认为我们可能有依赖于此设置的预处理器条件。事实上,我无法删除NDEBUG,这是我从这里提取的android工具链文件中定义的:
Remove all symbol table and relocation information from the executable.