Compilation ld在编译时和运行时都被调用吗?

Compilation ld在编译时和运行时都被调用吗?,compilation,linker,Compilation,Linker,我试图了解链接和加载是如何工作的。我的理解是Unix程序“ld”包含链接和加载功能。当调用gcc时,在预处理、编译和组装之后,将调用链接器,该链接器将所有对象文件和.a文件链接到可执行文件中,并提供运行时如何“连接”共享库的最低说明(这里的正确术语是什么?)。此链接器是ld 在运行时,我的理解是可执行文件被加载到内存中,尽管我不确定如何加载。我的具体问题如下: 1) 共享对象文件是在编译时被“链接”的,还是对正在发生的事情有另一个说法? 2) 在运行时,是否第二次调用ld?我如何在我的可执行文件

我试图了解链接和加载是如何工作的。我的理解是Unix程序“ld”包含链接和加载功能。当调用gcc时,在预处理、编译和组装之后,将调用链接器,该链接器将所有对象文件和.a文件链接到可执行文件中,并提供运行时如何“连接”共享库的最低说明(这里的正确术语是什么?)。此链接器是ld

在运行时,我的理解是可执行文件被加载到内存中,尽管我不确定如何加载。我的具体问题如下:

1) 共享对象文件是在编译时被“链接”的,还是对正在发生的事情有另一个说法? 2) 在运行时,是否第二次调用ld?我如何在我的可执行文件(Linux和MacOS上)中看到这方面的证据? 3) 共享对象文件是在运行时被“链接”的,还是在运行时从LD_LIBRARY_路径中的位置读取共享对象时,该过程有另一个词


谢谢

否。ld与创建库或exe时一样链接,ld*。加载部分也是如此。ld*.so也是操作系统的一部分,而不是gcc套件afaik。在基于gcc的系统上,ld通常是(GNU)binutils的一部分(但在基于LLVM的系统中通常是LLVM lld)

ld*.so是linux上的ld linux-{arch}.so.2和/libexec/ld-elf.so,例如FreeBSD

ld在编译时和运行时都被调用吗

否:在编译或运行时都不会调用ld

调用gcc时,在预处理、编译和组装之后,将调用链接器,该链接器将所有对象文件和.a文件链接到可执行文件中

大多数中等复杂的程序使用单独的编译和链接步骤

在编译时,生成一组可重新定位的对象文件(在该步骤中调用预处理、编译和组装)。可以选择将
.o
文件归档到归档库(
libsomething.a
)中

然后执行链接步骤(通常称为“静态链接”,以将此步骤与运行时发生的“动态加载”区分开来),生成可执行文件或共享库。只有在这一步,才会调用
/usr/bin/ld
。在Linux上,
ld
是binutils包的一部分

以及如何“连接”共享库的最低说明

链接器记录运行时需要哪些共享库,以及可能需要哪些版本的库或符号

它还记录应使用哪个运行时加载程序加载所需的共享库

在运行时,我的理解是可执行文件被加载到内存中,尽管我不确定如何加载

内核将可执行文件加载到内存中,并检查是否在静态链接时请求了运行时加载程序。如果是,动态加载程序也会加载到内存中,并将执行控制传递给它(而不是主可执行文件)

然后,动态加载器的工作是检查可执行文件中是否需要其他库的指令,检查是否可以找到正确的版本,将它们加载到内存中,并安排一些事情,以便在主可执行文件和共享库之间进行符号解析。这是运行时加载步骤,通常也称为动态链接


动态加载程序可以是操作系统的一部分,但在Linux上它是libc的一部分(GLIBC、uClibc和musl都有自己的加载程序)。

ld Linux不是Linix上操作系统的一部分。您可以在同一系统上同时安装多个不同的设备。这似乎是glibc的一部分。然而,这种知识在逻辑上是没有意义的。然而,我的观点是,它不是可移植到其他操作系统(如binutils和gcc)的部分。