Sam在程序开发中,经常要用到多层库嵌套。

Sam常在想,一些底层库的符号(symbols),在上层库乃至应用程序中并非全部要使用到。如果这些符号(symbols)实现一层层报喊道上一层库中,并最终添加到应用程序中,这不是既增大了应用程序大小,也造成运行速度的降低?

记得GCC编译选项中有解决这个问题的方法。于是查找之。

0. 总体思想:

网络上有人建议如下设置:

1. 编译阶段使用:

-ffunction-sections

-fdata-sections

2. 链接阶段使用:

-Wl,--gc-sections

在GCC,LD官方文档中如下讲解:

-ffunction-sections

-fdata-sections

Place each function or data item

into its own section in the output file if the target supports

arbitrary sections. The name of the function or the name of the

data item determines the section's name in the output file.

Use these options on systems where the linker can perform

optimizations to improve locality of reference in the instruction

space. Most systems using the ELF object format and SPARC

processors running Solaris 2 have linkers with such optimizations.

AIX may have these optimizations in the future.

Only use these options when there are significant benefits from

doing so. When you specify these options, the assembler and linker

will create larger object and executable files and will also be

slower. You will not be able to use gprof on all

systems if you specify this option and you may have problems with

debugging if you specify both this option and -g.

--gc-sections

--no-gc-sections

Enable garbage collection of unused input sections. It is

ignored on targets that do not support this option. The default

behaviour (of not performing this garbage collection) can be

restored by specifying `--no-gc-sections' on the command

line.

`--gc-sections' decides which

input sections are used by examining symbols and relocations. The

section containing the entry symbol and all sections containing

symbols undefined on the command-line will be kept, as will

sections containing symbols referenced by dynamic objects. Note

that when building shared libraries, the linker must assume that

any visible symbol is referenced. Once this initial set of sections

has been determined, the linker recursively marks as used any

section referenced by their relocations. See `--entry' and

`--undefined'.

This option can be set when doing a partial link (enabled with

option `-r'). In this case the root of

symbols kept must be explicitly specified either by an

`--entry' or `--undefined'

option or by a ENTRY command in the linker script.

因为GCC链接操作以section作为最小的处理单元,只要一个section中有某个符号被引用,该section就会被加入。

如果我们的某个.c程序中所有function都加入同一个section.则如果用到这个.c生成的.o的其中任何一个function.则必须将所有function(符号)加入其中。如此,则使用-ffunction-sections

和 -fdata-sections将每个符号创建为一个sections.

sections名与function,data名保持一致。

则在link阶段,-Wl,--gc-sections

申明去掉不用的section。就可以去掉没用的function(符号)了。

总体思想就是这样,Sam决定以验证之。

1. 验证过程:

Sam决定以Hi3716C平台中,Graphics_Base,libSTBUtils,3D_Example_HIGO此层次结构为例,研究之。

Graphics_Base是个底层库,架设在HiAPI之上,Sam当时选择将其编译为静态库。

libSTBUtils则是中间层,它架设在Graphics_Base层之上,作为3D应用程序的支持库,Sam选择其为动态库。

3D_Example_HIGO是个3D应用程序。依赖于libSTBUtils.so.

首先于Graphics_Base开始。它由多个.c文件组成。最终编译为静态库---libGraphics_Base.a

1.1 : 静态库中的分别:

即:产生静态库时,是否使用-ffunction-sections,

-fdata-sections产生的不同后果。

1.1.1: 不使用-ffunction-sections,

-fdata-sections

#arm-hisiv200-linux-gcc -c -O2 ...

#arm-hisiv200-linux-ar rv libGraphics_Base.a $?

此时,我们会希望看到以下2中信息:

1. .a中包含的符号。

2. .a中包含的sections.

首先看符号:

#arm-hisiv200-linux-readelf -s

libGraphics_Base.a

其次看section:

#arm-hisiv200-linux-readelf -t

libGraphics_Base.a

结果如下:

#arm-hisiv200-linux-readelf -s

libGraphics_Base.a

以下是节选:

140:

00000000 160

FUNC GLOBAL

DEFAULT 1

HIADP_AVPlay_SetVdecAttr

141:

00000000 0 NOTYPE GLOBAL DEFAULT UND

HI_UNF_AVPLAY_GetAttr

142:

00000000 0 NOTYPE GLOBAL DEFAULT UND

HI_UNF_AVPLAY_SetAttr

143:

00000000 0 NOTYPE GLOBAL DEFAULT UND

puts

144:

00000000 0 NOTYPE GLOBAL DEFAULT UND

printf

145:

00000000 0 NOTYPE GLOBAL DEFAULT UND

_GLOBAL_OFFSET_TABLE_

146:

000000a0 168

FUNC GLOBAL

DEFAULT 1

HIADP_AVPlay_SetVdecAdvAt

147:

00000148 1432

FUNC GLOBAL

DEFAULT 1

HIADP_AVPlay_SetAdecAttr

148:

00000000 0 NOTYPE GLOBAL DEFAULT UND

HIADP_HDMI_SetAdecAttr

149:

00000000 0 NOTYPE GLOBAL DEFAULT UND

HI_UNF_SND_SetSampleRate

150:

00000004 1024 OBJECT GLOBAL

DEFAULT COM u8DecOpenBuf

151:

00000000 0 NOTYPE GLOBAL DEFAULT UND

__aeabi_uidivmod

152:

000006e0 264

FUNC GLOBAL

DEFAULT 1

HIADP_AVPlay_PlayAud

153:

00000000 0 NOTYPE GLOBAL DEFAULT UND

HI_UNF_AVPLAY_Stop

154:

00000000 0 NOTYPE GLOBAL DEFAULT UND

HI_UNF_AVPLAY_Start

155:

000007e8 524

FUNC GLOBAL

DEFAULT 1

HIADP_AVPlay_PlayProg

156:

000009f4 504

FUNC GLOBAL

DEFAULT 1

HIADP_AVPlay_Create

157:

00000000 0 NOTYPE GLOBAL DEFAULT UND

HI_UNF_AVPLAY_GetDefaultC

158:

00000000 0 NOTYPE GLOBAL DEFAULT UND

HI_UNF_AVPLAY_Create

159:

00000000 0 NOTYPE GLOBAL DEFAULT UND

HI_UNF_AVPLAY_ChnOpen

160:

00000bec 220

FUNC GLOBAL

DEFAULT 1

HIADP_AVPlay_RegADecLib

161:

00000000 0 NOTYPE GLOBAL DEFAULT UND

HI_UNF_AVPLAY_RegisterAco

162:

00000cc8 24

FUNC GLOBAL

DEFAULT 1

HIADP_AVPlay_Init

163:

00000000 0 NOTYPE GLOBAL DEFAULT UND

HI_UNF_AVPLAY_Init

164:

00000ce0 56

FUNC GLOBAL

DEFAULT 1

HIADP_SLIC_Close

165:

00000000 0 NOTYPE GLOBAL DEFAULT UND

close

166:

00000d18 92

FUNC GLOBAL

DEFAULT 1

HIADP_AIAO_DeInit

167:

00000000 0 NOTYPE GLOBAL DEFAULT UND

HI_MPI_AI_DisableChn

168:

00000000

Linux进程中Dec04什么意思,Linux下缩小可执行程序 (一) 非使用符号的去除相关推荐

  1. linux 编译符号 u,Linux下缩小可执行程序 (一) 非使用符号的去除

    作者: Sam (甄峰) Sam在程序开发中,经常要用到多层库嵌套. Sam常在想,一些底层库的符号(symbols),在上层库乃至应用程序中并非全部要使用到.如果这些符号(symbols)实现一层层 ...

  2. Linux进程中Dec04什么意思,用last命令时会总显示些crash,

    各位高手: 我们系统内核是2.6.9,最近经常出现死机情况. 用last命令看时,会有一些crash显示,如下: yanj     pts/32                        Fri  ...

  3. linux进程中的内存分布

    很多小伙伴在调试C代码的时候非常痛苦,C语言不像java那样可以给你指出具体的错误地方和错误原因,C语音因为指针的特殊性和C语言版本的兼容性的需要,很难直接定位到错误的地方.特别是各种段错误.溢出等. ...

  4. Linux进程中的RSS和VSZ

    Linux进程中的RSS和VSZ 64位Linux系统中虚拟内存空间大小 我们都知道32位系统的虚拟内存空间大小是2^32B,也就是4GB.但是,64位系统的虚拟内存空间的大小并不是2^64B,而是2 ...

  5. linux系统创建操作系统用户,linux系统中用户组创建管理linux操作系统 -电脑资料...

    用户组管理包括对用户组创建,删除,修改及查看组操作命令,下面我们一起来看看希望本文章对各位同学会有所帮助哦, 1,创建组 groupadd test 增加一个test组 2,修改组 groupmod ...

  6. linux进程tss和ldt,x86体系下linux中的任务切换与TSS

    tss的作用举例:保存不同特权级别下任务所使用的寄存器,特别重要的是esp,因为比如中断后,涉及特权级切换时(一个任务切换),首先要切换栈,这个栈显然是内核栈,那么如何找到该栈的地址呢,这需要从tss ...

  7. linux进程中对信号的屏蔽,linux进程中的信号屏蔽

    在linux的进程中可以接收到各种的信号,并且如果你不对信号进行处理,linux中的进程就会采用默认的处理方式处理,比如ctrl-c的信号,进程对它的处理就是终止进程的执行. 在linux中,我们也可 ...

  8. linux进程看门狗使用方式,Linux系统中基于看门狗的精细化进程监控方法及系统的制作方法...

    Linux系统中基于看门狗的精细化进程监控方法及系统的制作方法 [技术领域] [0001] 本发明涉及Linux系统的进程监控技术领域,特别是涉及一种Linux系统中基于看 门狗的精细化进程监控方法及 ...

  9. linux查看进程中的线程名,linux 怎么样查看一个进程的线程

    一.linux系统支持的最大进程数 限制1:既然系统使用pid_t表示进程号,那么最大进程数不能超过pid_t类型的最大值吧 限制2:使用命令ulimit -u查看系统中限制的最大进程数,我的机器上是 ...

最新文章

  1. perl中的几个模块使用.
  2. GPU — Overview
  3. unity双面显示在哪_双面屏努比亚Z20售3499起 4800万三摄+855Plus+4K电池
  4. Android中的Context理解
  5. 【ElasticSearch】es 面试题 视频 笔记
  6. 如何在Mac上创建和引导Linux USB驱动器
  7. html让视频自动循环播放,javascript – HTML5视频 – 如何进行无缝播放和/或循环播放多个视频?...
  8. (转)文件名后缀大全
  9. 将图片(HDC)打印出来
  10. python爬取猫眼电影评分
  11. 信息检索(IR)——索引与检索
  12. 语音情感识别中的音频检测算法学习
  13. C++实现栈的基本操作(入栈,出栈,取栈顶)
  14. Ubuntu16.04 和 Win7 双系统启动顺序更改
  15. prism DelegateCommand的使用
  16. 是未来所在还是昙花一现:共享汽车颠覆谁?
  17. python算法工程师-从材料硕士到算法工程师的转行之路,有三不建议
  18. 360影视大全下载|360影视大全电脑版下载
  19. mybatisplus代码生成报错:Exception in thread “main“ java.lang.NoClassDefFoundError: org/apache/velocity
  20. 详解ISO13400文档-3

热门文章

  1. Eclipse对html和js代码自动提示
  2. 2021年年末全国男女比例数据公布
  3. 七牛云直播推流php,七牛云直播Android推流端之开速开发
  4. linux用户、组的创建
  5. [leetcode] 116. Populating Next Right Pointers in Each Node @ python
  6. pySerial使用初步
  7. ettercap+urlsnarf+driftnet+wireshark监听妹子上网
  8. SnowNLP使用自定义语料进行模型训练(情感分析)
  9. Python爬虫之——爬取妹子图片
  10. I06-python菜鸟教程查漏补缺