使用 ld 将目标文件链接到 C 标准库

问题描述 投票:0回答:1

假设我正在尝试从以下位置创建可执行二进制文件:

// main.c

#include <stdio.h>

int main() {
    printf("Hello, world!");
    return 0;
}

我只需运行

gcc main.c
即可获得可执行二进制文件
a.out
,根据需要打印“Hello, world!”。

有人告诉我

gcc
在这里做了两件事:\

  1. main.c
    编译为目标代码,并且
  2. 将该代码与标准库链接起来,以便
    printf
    可以工作。\

如何手动一一手动完成这两个步骤?

我通过运行

main.c
开始将
gcc -c main.c
编译为目标代码,创建目标文件
main.o
。现在我想做链接步骤。看来我也可以通过
gcc
来做到这一点,只需运行
gcc main.o
,生成可执行二进制文件
a.out

我读到,第二次调用

gcc
实际上是在后台运行链接器
ld
。我如何直接使用
ld
来执行此操作,而不是再次调用
gcc
?如果我运行
ld main.o
,我会收到警告和错误:

ld: warning: cannot find entry symbol _start; defaulting to 00000000004000b0
ld: main.o: in function `main':
main.c:(.text+0x10): undefined reference to `printf'

该错误似乎表明我需要告诉它链接到 C 标准库,以便我可以使用

printf
。我可以使用
-lc
标志
ld main.o -lc
。这会产生
a.out
,但我仍然收到警告:

ld: warning: cannot find entry symbol _start; defaulting to 00000000004002e0

当我运行

a.out
时,它会永远在屏幕上打印
Hello, world!

Hello, world!Hello, world!Hello, world!Hello, world!Hello, world!Hello, world!Hello, world!Hello, world!Hello, world!Hello, world!Hello, world!Hello, world!Hello, world!Hello, world!Hello, world!Hello,

在此处调用

ld
以消除警告并获取正确的可执行文件的正确方法是什么?

c gcc linker ld
1个回答
0
投票

在这里调用 ld 来消除警告并获得正确的可执行文件的正确方法是什么?

链接用户空间 C 二进制文件的唯一正确方法是使用适当的编译器前端:

gcc main.o

直接使用

ld
永远不正确。

您可以通过调用

gcc
来查看
gcc -v main.o
实际执行的操作。但请注意,结果
ld
(或
collect2
命令):

  • 可能会有所不同,具体取决于您的
    gcc
    的配置方式
  • 不同操作系统版本之间可能有所不同
  • 可能会有所不同,具体取决于所使用的
    libc

TL;DR:欢迎您了解

gcc
如何在您的系统上调用
ld
,但您不应该将结果放入任何
Makefile
或构建脚本中。

© www.soinside.com 2019 - 2024. All rights reserved.