代码之家  ›  专栏  ›  技术社区  ›  Jay

如何确保未使用的符号不会链接到最终的可执行文件中?

  •  0
  • Jay  · 技术社区  · 14 年前

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

    所以,我的问题是:

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

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

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

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

    有没有其他方法来解决这个问题?

    注意:重新组织我的代码几乎被排除在外,因为它是一个遗留代码和大型代码。

    我主要处理VxWorks和GCC。

    谢谢你的帮助!

    1 回复  |  直到 14 年前
        1
  •  3
  •   Jonathan Leffler    14 年前

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

    如果你看Plauger's“ The Standard C Library “,您会发现每个函数都是在一个单独的文件中实现的,即使文件最后有4行长(一个头、一个函数行、一个左大括号、一行代码和一个右大括号)。


    杰伊问:

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

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

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

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