使用-section等参数实现对库的裁剪,从而减小程序体积
在实际的项目里面,产品中除去系统加载使用的空间外,留给具体的功能应用程序的空间较小,因此需要对应用程序用到的库进行裁剪。比如在实际的项目中,应用程序和库一共14M,最后进行裁剪,减少了6-7M对于空间有限,使用的库较多(依赖的第三方开源库openssl等)占用体积较大,我们如果使用动态库(.so)显然不适合,因此我们可以使用静态库(.a),但是这样还不够,依赖的库中有很多实现的函数,但是应用...
在实际的项目里面,产品中除去系统加载使用的空间外,留给具体的功能应用程序的空间较小,因此需要对应用程序用到的库进行裁剪。比如在实际的项目中,应用程序和库一共14M,最后进行裁剪,减少了6-7M
对于空间有限,使用的库较多(依赖的第三方开源库openssl等)占用体积较大,我们如果使用动态库(.so)显然不适合,因此我们可以使用静态库(.a),但是这样还不够,依赖的库中有很多实现的函数,但是应用程序并没有使用,没用的函数就应该不链接进来,占用宝贵的空间。
对此就需要修改编译选项:
(1)编译时加入:-ffunction-sections, -fdata-sections 选项,这样编译的时候,把每个函数作为一个section,每个数据(应该是指全局变量之类的吧)也作为一个section。如果不加-ffunction-sections选项,则默认似乎是每个源文件为一个section进行链接,这样子只要这个文件中用到了一个函数,那么所有的函数都会被链接进来。
(2)链接时加入:--gc-sections选项 ,这样链接的时候,--gc-sections会把没用到的section丢弃掉,最终的可执行文件就只包含用到了的函数和数据。链接的单位,是函数级别,这样就能丢弃没使用的函数。
当我们依赖静态库,编译和链接选项加如上所示后,应用程序变小,但是查看符号表等,发现一些库中的函数依然存在,于是经过一些时间的排查,当添加上-fvisibility=hidden
在linux下,源文件中的所有函数都有一个默认的visibility属性为public,在编译命令中加入-fvisibility=hidden参数,会将所有默认的public的属性变为hidden。此时,如果对函数设置__attribute__ ((visibility("default")))参数,使特定的函数仍然按默认的public属性处理,则-fvisibility=hidden参数不会对该函数起作用。所以,设置了-fvisibility=hidden参数之后,只有设置了__attribute__ ((visibility("default")))的函数才是对外可见的,如此则效果等同于Visual Studio下的__declspec(dllexport)定义。
综上:
修改了CMakeLists.txt:
ADD_DEFINITIONS("-Wall")
ADD_DEFINITIONS("-fPIC")
ADD_DEFINITIONS("-Wl,-Bsymbolic -lm")
ADD_DEFINITIONS("-std=c++11")
SET(CMAKE_CXX_FLAGS "-Wall -fPIC -s -fvisibility=hidden -ffunction-sections -fdata-sections -Wl,-rpath-link=$(../../../Library/ISVP_T20Z/lib) -Wl,-Bsymbolic -lm -D__STDC_CONSTANT_MACROS -D__STDC_LIMIT_MACROS -DISVP")
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)