可执行文件裁剪分析方法

目的

在进行软件项目部署时,我们常常会发现编译后的程序尺寸过大。那么,究竟是什么原因导致程序偏大呢?

以下是根据我的经验总结的一些原因和解决方法:

未优化的编译选项

使用默认编译选项时,编译器可能不会进行代码优化,从而导致生成的可执行文件较大。可以尝试使用编译器的优化选项,如 -O2 或 -O3,这些选项可以在不影响性能的情况下减小代码体积

调试信息未移除

编译时包含了调试信息,这些信息会显著增加可执行文件的大小。可以使用 -s 选项来去除符号表信息,或者使用 strip 命令来删除调试信息。

静态链接库

动态链接库可能会增加可执行文件的大小,因为它们需要包含额外的信息来找到和链接动态库。可以尝试使用静态链接,通过 -static 选项来启用静态链接2。

未使用链接时优化

链接时优化(LTO)可以在链接阶段进行进一步的优化,从而减小可执行文件的大小。可以使用 -flto 选项来启用链接时优化2。

使用.map文件

.map 文件记录了链接器在生成可执行文件时的详细信息,包括各个代码段、数据段的地址、大小等。这对于检查程序大小、内存使用和地址分配非常有用。

Linux系统

在 Linux 中,你可以使用以下方法来生成 .map 文件:

方法1

通过编译命令行参数: 在编译命令后添加 -Wl,-Map=your_file.map,这样可以指定 .map 文件的名称和路径。如直接在 gcc 或 g++ 命令行中使用 -Wl,-Map=your_file.map 参数。

方法2

通过 Makefile: 如果你使用 Makefile 来编译,可以在 Makefile 中添加以下行:
LDFLAGS=-Map=your_file.map

windows系统

在 Windows 中,编译器也有类似的功能来生成 .map 文件。你可以使用以下方法:

命令行方式

通过命令行参数: 在编译命令后添加 /MAP[:filename],这样可以指定 .map 文件的名称和路径。默认情况下,链接器会使用程序的基本名称和扩展名 .map 来命名映射文件,但你可以通过指定文件名来覆盖默认名称。

VS配置

通过 Visual Studio: 如果你使用 Visual Studio 进行编译,可以在项目的 Property Pages 对话框中设置“Generate Map File”属性。具体步骤如下:

	打开项目的 Property Pages 对话框。
	选择 Configuration Properties > Linker > Debug 属性页。
	修改 Generate Map File 属性。

这样,编译器就会生成一个包含详细链接信息的 .map 文件,方便你检查程序大小、内存使用和地址分配等信息。

常用命令

当涉及到符号表和文件大小时,nm 和 size 是两个常用的 Linux 命令。让我为你详细解释一下它们的作用

nm 命令

nm 命令用于列出目标文件中的符号(symbol)。这些符号可以是函数、变量、常量等。
基本用法:运行 nm 命令并将目标文件的名称作为输入参数。例如:
nm your_object_file

输出的三列分别表示符号值、符号类型和符号名称。有多种符号类型,常见如下。
这条命令输出的第三列包含以下符号类型的标识:

D:表示数据段中的全局变量(Data)。
d:表示数据段中的局部变量(Data)。
B:表示数据段中的全局未初始化变量(BSS,Block Started by Symbol)。
b:表示数据段中的局部未初始化变量(BSS)。
T:表示代码段中的全局函数或代码(Text)。
t:表示代码段中的局部函数或代码(Text)。

-A 选项来在输出中显示文件名,或使用 -a 选项来显示调试符号(通常不会列出的符号)

示例展示

nm  --print-size --size-sort --radix dec -C nuttx/nuttx

这条命令是用于分析 nuttx/nuttx 目标文件的符号大小的。让我为你解释一下各个选项的含义:

nm:这是一个用于显示目标文件符号表的命令。
--print-size:这个选项会在输出中显示符号的大小(以十进制形式)。
--size-sort:这个选项会按照符号大小进行排序,从最大到最小。
--radix dec:这个选项指定输出中的符号值使用十进制表示法。
-C:这个选项会将 C++ 符号进行修饰,以便更好地区分重载函数和其他符号。

因此,这条命令将显示 nuttx/nuttx 目标文件中的符号,包括它们的大小,并按照大小进行排序。

size 命令

size 命令用于显示目标文件或可执行文件的大小信息。
基本用法:运行 size 命令并将目标文件的名称作为输入参数。例如:
size your_object_file

输出包括三列:文本段(代码段)大小、数据段大小和总大小。
size 命令对于检查程序的大小和内存使用非常有用,特别是在优化代码时。

  • 12
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值