链接器如何决定包含哪些部分?[英] How do linkers decide what parts of libraries to include?

本文是小编为大家收集整理的关于链接器如何决定包含哪些部分?的处理方法,想解了链接器如何决定包含哪些部分?的问题怎么解决?链接器如何决定包含哪些部分?问题的解决办法?那么可以参考本文帮助大家快速定位并解决问题。

问题描述

假设库A具有A()和B().如果我将程序B与a链接并调用A(),那么B()是否包含在二进制中?编译器是否查看程序中的任何功能call b()(也许是a()调用b()或其他lib调用b())?如果是这样,编译器如何获取此信息?如果不是,如果我要链接到大图书馆,那么这不是浪费最终编译尺寸的大小吗?

推荐答案

看一下链接时间优化.这一定是供应商依赖的.这也将取决于您如何构建二进制文件. MS编译器(至少2005年)提供了一种称为功能级别链接 - 这是剥离您不需要的符号的另一种方式. 帖子解释了如何与GCC一起实现相同(GCC必须是旧的,GCC必须' ve继续前进,但内容与您的问题有关).

还要看一下 llvm 实现(和示例部分)./p>

我建议您还要看一下链接和装载机<>/a>约翰·莱文(John Levine) - 出色的阅读.

其他推荐答案

这取决于

如果库是共享对象或DLL,则库中的所有内容都会加载,但在运行时. (希望)通过在使用该库中的所有过程之间共享库(实际上是代码页)来抵消额外内存中的成本.对于libc.但是您可能并没有问共享对象.

静态库只是单个对象文件的集合,每个对象文件的结果是单独的汇编(或汇编)的结果,甚至可能没有用相同的源语言编写.每个对象文件都有许多导出的符号,几乎总是多个导入的符号.

链接器的作业是创建一个没有剩余未定义导入符号的可执行文件. (当然,我在说谎,如果允许动态链接,但请忍受我.明确命名必须是完成的可执行文件的一部分.然后,它试图找到所有未定义符号的定义.

通常,命名的对象模块期望从某些库中获得符号,例如libc.a.

在您的示例中,您有一个调用函数a()的单个模块,这将导致链接器寻找导出a()的模块.

您说库命名为A(在Unix上,可能libA.a)提供a()和b(),但您没有指定如何.您暗示a()和b()不要互相打电话,我会假设.

如果libA.a是由a.o和b.o构建的,其中每个>定义相应的单个函数,则链接器将包括a.o并忽略b.o.

但是,如果libA.a包括ab.o同时定义a()和b()的ab.o,则它将在链接中包含ab.o,满足a()的需求,并包括未使用的函数b() .

正如其他人提到的那样,有些链接器能够从模块中拆分单个功能,仅包括实际使用的链接.在许多情况下,这是一件安全的事情.但是通常,除非您有特定的文档,否则通常可以最安全地假设您的链接器不执行此操作.

其他要注意的东西是,大多数链接器通过在命令行上命名的文件和库尽可能少的通行证进行,并在其上构建其符号表.实际上,这意味着在链接命令行上所有对象模块之后始终指定库是很好的做法.

其他推荐答案

它取决于链接器.

Microsoft Visual C ++具有"启用功能级别链接"选项,因此您可以手动启用它.

(我认为他们有一个不仅启用它的原因...也许链接较慢或其他)

本文地址:https://www.itbaoku.cn/post/359028.html