假设我正在尝试创建一个可执行的二进制文件:
// main.c
#include <stdio.h>
int main() {
printf("Hello, world!");
return 0;
}
字符串
我可以运行gcc main.c
,然后得到可执行的二进制文件a.out
,它会根据需要打印“Hello,world!"。
有人告诉我gcc
在这里做了两件事:
1.将main.c
编译为目标代码,
1.将该代码与标准库链接,以便printf
工作。
我如何手动完成这两个步骤手动,一个接一个?
我开始通过运行gcc -c main.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
的正确方法是什么,才能消除警告,得到正确的可执行文件?
1条答案
按热度按时间to94eoyn1#
在这里调用ld以消除警告并获得正确的可执行文件的正确方法是什么?
链接用户空间C二进制文件的唯一正确方法是使用适当的编译器前端:
gcc main.o
。直接使用
ld
是 * 永远 * 不正确的。通过调用
gcc -v main.o
,可以看到gcc
实际上做了什么。但是请注意,结果ld
(或collect2
命令):gcc
的配置libc
而异TL;医生:欢迎您学习
gcc
如何在您的系统上调用ld
,但您不应该将结果放入任何Makefile
或构建脚本中。