如果链接器开始满足丢失的符号,直到它到达满足所有需要的符号的点,我们称之为“仅添加所需的内容”。另一方面,从完整的符号集合开始,然后基于某些算法扫描以删除不需要的符号,我们称之为“投掷”。从语义上讲,我们将链接过程的这个方面描述为仅添加所需内容更为正确。
我很好奇stackoverflow社区同意这一点,因为我相信它依赖于这些链接器功能会有更强的论据。
答案 0 :(得分:3)
所有连接子都以添加剂模式工作。最好用图论来解释。
链接器首先标识一个或多个入口点(main
用于库的可执行,导出函数)。必须包含这些入口点。
但是,这些导出点可能包含在较大的段/块中(许多编译器不能或不能打包单个函数和数据)。包含在同一块/段中的任何内容都将自动包含在内。
此外,当函数调用其他函数时,链接器可能也需要添加这些函数 - 再次,编译器限制可能导致在块太大时拖入大量额外的东西。此步骤称为“解析依赖关系”,通常以递归方式完成,直到不再缺少任何函数。
为什么这些块太大了?常见问题是编译器/链接器对无法传递依赖关系。如果不能告诉链接器X依赖于Y,则编译器必须将X和Y放在同一段中。不幸的是,这往往会升级到整个.cpp文件在同一段中结束的程度 - 所有那些不需要的函数都会拖延到不需要的依赖项中。因为这个原因,我看到可执行文件会增加到600 MB。
答案 1 :(得分:2)
链接器解析引用。它们“查看”待链接目标文件的符号表,并解析这些引用 - 或者如果给定的目标文件都不满足所述引用,则吐出“未解析的引用”错误。
所以你有理由说他们正在“加入”。 (你的评论/编辑看到了你来自哪里。)
但是,有一些限制,具体取决于所使用的链接器的功能。您可能(并且可能是......)正在查看只能决定链接整个目标文件的链接器。在这种情况下,代码结构的是 ,链接器是否可以很好地省略不需要的对象代码。如果您只拥有一个大对象文件,那么只要需要该对象文件中的单个符号,它就会被链接。
所以它可能比你想要的“添加”更多 - 或者“无法删除”。这真的只是在狡辩。
答案 2 :(得分:1)
你的问题的答案有很多"它取决于"。
例如,它取决于编译器和链接器的功能。一些链接器可能没有智能来检测未使用的功能。
如果优化级别设置为特定级别,某些编译器可能只会丢弃函数。
该函数可能必须是您正在构建的代码的一部分,或者在静态库中,以便编译器将其删除。
有些编译器可能会抛出库中的所有函数,无论它们是否需要;取决于优化级别。
取决于。
举一个更专业的例子。
答案 3 :(得分:1)
传统上,链接器将首先添加您指定的目标文件的所有。然后它将通过静态链接库,查找定义这些目标文件或早期库所需符号的模块 - 定义符号的任何模块总共链接。未定义所需符号的模块未链接。
今天的链接器更复杂,并且能够执行优化步骤,但细节应该来自您正在使用的特定构建系统的文档。