减小可执行文件大小的过程 [英] Process for reducing the size of an executable

查看:32
本文介绍了减小可执行文件大小的过程的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在生成一个在 ARM 处理器上运行的十六进制文件,我希望将其保持在 32K 以下.目前它比那个大得多,我想知道是否有人可以就什么是缩小它的最佳方法提供一些建议?

I'm producing a hex file to run on an ARM processor which I want to keep below 32K. It's currently a lot larger than that and I wondered if someone might have some advice on what's the best approach to slim it down?

这是我到目前为止所做的

Here's what I've done so far

  1. 所以我在它上面运行了size"来确定 hex 文件有多大.
  2. 然后再次大小"以查看创建十六进制文件的链接的每个目标文件有多大.似乎大部分大小来自外部库.
  3. 然后我使用readelf"来查看哪些函数占用的内存最多.
  4. 我搜索了代码,看看是否可以消除对这些函数的调用.

这是我卡住的地方,有些函数我不直接调用(例如_vfprintf),我找不到调用它的函数,所以我可以删除调用(因为我认为我不需要它).

Here's where I get stuck, there's some functions which I don't call directly (e.g. _vfprintf) and I can't find what calls it so I can remove the call (as I think I don't need it).

接下来的步骤是什么?

对答案的回应:

  • 正如我所看到的,有一些函数被调用,它们占用了大量内存.然而,我无法找到它的名字.
  • 我想省略这些函数(如果可能),但我找不到调用它们的内容!我猜可以从任意数量的库函数中调用.
  • 链接器按预期工作,我认为它只包含相关的库文件.你怎么知道是否只包含了相关的功能?你能为此设置一个标志或其他东西吗?
  • 我正在使用 GCC

推荐答案

一般列表:

  • 确保您已禁用编译器和链接器调试选项
  • 编译并链接所有大小选项(gcc 中的 -Os)
  • 在可执行文件上运行 strip
  • 生成地图文件并检查您的函数大小.您可以让链接器生成映射文件(使用 ld 时为 -M),或者您可以在最终可执行文件上使用 objdump(请注意,这仅适用于未剥离的可执行文件!)这赢了实际上并不能解决问题,但它会让您知道最严重的违规者.
  • 使用 nm 调查从每个目标文件调用的符号.这应该有助于找出谁在调用您不想调用的函数.
  • Make sure that you have the compiler and linker debug options disabled
  • Compile and link with all size options turned on (-Os in gcc)
  • Run strip on the executable
  • Generate a map file and check your function sizes. You can either get your linker to generate your map file (-M when using ld), or you can use objdump on the final executable (note that this will only work on an unstripped executable!) This won't actually fix the problem, but it will let you know of the worst offenders.
  • Use nm to investigate the symbols that are called from each of your object files. This should help in finding who's calling functions that you don't want called.

在原始问题中是一个关于仅包含相关功能的子问题.gcc 将包含使用的每个目标文件中的所有函数.换句话说,如果您有一个包含 10 个函数的目标文件,则所有 10 个函数都包含在您的可执行文件中,即使其中一个函数被实际调用.

In the original question was a sub-question about including only relevant functions. gcc will include all functions within every object file that is used. To put that another way, if you have an object file that contains 10 functions, all 10 functions are included in your executable even if one 1 is actually called.

标准库(例如 libc)会将函数拆分为许多单独的目标文件,然后将这些文件归档.然后将可执行文件链接到存档.通过拆分成许多目标文件,链接器能够只包含实际调用的函数.(这假设您是静态链接)

The standard libraries (eg. libc) will split functions into many separate object files, which are then archived. The executable is then linked against the archive. By splitting into many object files the linker is able to include only the functions that are actually called. (this assumes that you're statically linking)

你没有理由不能做同样的把戏.当然,您可能会争辩说,如果不调用这些函数,您可能可以自己删除它们.

There is no reason why you can't do the same trick. Of course, you could argue that if the functions aren't called the you can probably remove them yourself.

如果您静态链接到其他库,您也可以对它们运行上面列出的工具,以确保它们遵循类似的规则.

If you're statically linking against other libraries you can run the tools listed above over them too to make sure that they're following similar rules.

这篇关于减小可执行文件大小的过程的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆