0

首先,我向那些关注我在过去几天发布的问题的人道歉。这听起来可能有点重复,因为我一直在问与 -ffunction-sections 和 -fdata-sections 相关的问题,而这个问题在同一行。这些问题和他们的答案并没有解决我的问题,所以我意识到最好在这里陈述完整的问题并让 SO 专家思考它。很抱歉没有早点这样做。

所以,这是我的问题:

我构建了一组提供许多功能的静态库。这些静态库将提供给许多产品。并非所有产品都会使用我的库提供的所有功能。问题是库的大小非常大,产品希望减少它。主要目标是减少最终的可执行文件大小,而不是库大小本身。

现在,我做了一些研究,发现如果源文件中有 4 个函数并且应用程序只使用其中一个函数,链接器仍会将其余 3 个函数包含到最终的可执行文件中,因为它们都是属于同一个目标文件。我进一步分析发现 -ffunction-sections、-fdata-sections 和 -gc-sections(这是一个链接器选项)将确保只有一个函数被链接。

但是,由于某些我无法控制的原因,这些选项现在无法使用。

有没有其他方法可以确保链接器只链接严格要求的函数并排除所有其他函数,即使它们在同一个目标文件中?

有没有其他方法来处理这个问题?

注意:几乎排除了重新组织我的代码的可能性,因为它是遗留代码并且很大。

我在这里主要处理 VxWorks 和 GCC。

谢谢你的帮助!

4

1 回答 1

3

最终,确保仅链接您想要的函数的唯一方法是确保库中的每个源(对象)文件仅导出一个函数符号 - 每个文件一个(可见)函数。通常,有些文件会导出几个总是一起使用的函数——例如,一个包的初始化和终结函数。此外,导出函数使用的函数通常不需要在源(对象)文件之外可见 - 确保它们是static.

如果您查看 Plauger 的“标准 C 库”,您会发现每个函数都在一个单独的文件中实现,即使该文件最终有 4 行长(一个标题、一个函数行、一个左大括号、一行代码和一个右大括号)。


杰问:

在一个大项目的情况下,这么多文件是不是很难管理?此外,我没有发现很多遵循这种模式的开源项目。OpenSSL 就是一个例子。

我没有说它被广泛使用——它不是。但这是确保二进制文件最小化的方法。编译器(链接器)不会为您进行最小化 - 至少,我不知道有任何这样做。在大型项目中,您设计源文件,以便将通常一起使用的密切相关的功能组合在单个源文件中。仅偶尔使用的功能应放在单独的文件中。理想情况下,很少使用的函数应该在各自的文件中;如果做不到这一点,请将它们中的少量分组到小(但非最小)文件中。这样,如果使用了很少使用的函数之一,您只会获得有限数量的额外未使用的代码链接。

至于文件数量 - 是的,所支持的技术确实意味着很多文件。您必须权衡管理(命名)大量文件的工作量与最小代码大小的好处。自动构建系统消除了大部分痛苦;VCS 系统处理大量文件。

另一种选择是将库代码放入共享对象 - 或动态链接库 (DLL)。然后程序与共享对象链接,该共享对象只加载到内存中一次并在使用它的程序之间共享。为每个进程复制(非常量)数据。这减少了磁盘上程序的大小,但代价是加载过程中的修复。但是,您不必担心可执行文件的大小;可执行文件不包括共享对象。并且您可以更新库(如果您小心的话),而无需重新编译使用它的主程序。可执行文件的大小减小是共享库流行的原因之一。

于 2010-11-26T05:10:43.800 回答