假设我正在尝试从以下位置创建可执行二进制文件:
// main.c
#include <stdio.h>
int main() {
printf("Hello, world!");
return 0;
}
我只需运行
gcc main.c
即可获得可执行二进制文件 a.out
,根据需要打印“Hello, world!”。
有人告诉我
gcc
在这里做了两件事:\
main.c
编译为目标代码,并且 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
以消除警告并获取正确的可执行文件的正确方法是什么?
在这里调用 ld 来消除警告并获得正确的可执行文件的正确方法是什么?
链接用户空间 C 二进制文件的唯一正确方法是使用适当的编译器前端:
gcc main.o
。
直接使用
ld
永远不正确。
您可以通过调用
gcc
来查看 gcc -v main.o
实际执行的操作。但请注意,结果 ld
(或 collect2
命令):
gcc
的配置方式libc
TL;DR:欢迎您了解
gcc
如何在您的系统上调用 ld
,但您不应该将结果放入任何 Makefile
或构建脚本中。