我正在尝试在Linux下编译一个C程序.然而,出于好奇,我正在尝试手动执行一些步骤:我使用:
现在我被连接部分困住了.
该程序是一个非常基本的"Hello world":
#include <stdio.h>
int main() {
printf("Hello\n");
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我使用以下命令来生成汇编代码:
gcc hello.c -S -masm=intel
Run Code Online (Sandbox Code Playgroud)
我告诉gcc在编译后退出并使用Intel语法转储汇编代码.
然后我使用GNU汇编程序来生成目标文件:
as -o hello.o hello.s
Run Code Online (Sandbox Code Playgroud)
然后我尝试使用ld生成最终的可执行文件:
ld hello.o /usr/lib/libc.so /usr/lib/crt1.o -o hello
Run Code Online (Sandbox Code Playgroud)
但我不断收到以下错误消息:
/usr/lib/crt1.o: In function `_start':
(.text+0xc): undefined reference to `__libc_csu_fini'
/usr/lib/crt1.o: In function `_start':
(.text+0x11): undefined reference to `__libc_csu_init'
Run Code Online (Sandbox Code Playgroud)
符号__libc_csu_fini/init似乎是glibc的一部分,但我无法在任何地方找到它们!我尝试/usr/lib/libc.a使用相同的结果静态链接libc(反对).
问题是什么?
Mat*_*ery 34
/usr/lib/libc.so是一个链接器脚本,它告诉链接器引入共享库/lib/libc.so.6和非共享部分/usr/lib/libc_nonshared.a.
__libc_csu_init并且__libc_csu_fini从何而来/usr/lib/libc_nonshared.a.它们未被发现,因为非共享库中符号的引用需要出现在链接器行上定义它们的归档之前.在你的情况下,/usr/lib/crt1.o(引用它们)出现在 /usr/lib/libc.so(将它们拉入)之后,因此它不起作用.
修复链接线上的订单会让你更进一步,但是你可能会遇到一个新问题,在哪里__libc_csu_init和__libc_csu_fini(现在找到的)无法找到_init和_fini.为了调用C库函数,您还应该链接/usr/lib/crti.o(在C库之后crt1.o但在 C库之前)和/usr/lib/crtn.o(在 C库之后),其中包含初始化和最终化代码.
添加它们应该为您提供成功链接的可执行文件 它仍然无法工作,因为它使用动态链接的C库而不指定动态链接器是什么.您还需要告诉链接器,例如-dynamic-linker /lib/ld-linux.so.2(至少32位x86;标准动态链接器的名称因平台而异).
如果你做了所有这些(基本上按照Rob的回答),你会得到一些在简单情况下有效的东西.但是,您可能会遇到更复杂代码的问题,因为GCC提供了一些自己的库例程,如果您的代码使用某些功能,可能需要这些例程.这些将被埋在GCC安装目录的深处......
您可以gcc通过-v选项(它将显示它在运行时调用的命令)或-###选项(它只是打印它将运行的命令,以及所有参数引用,但不会运行它)来查看正在执行的操作.实际上运行任何东西).除非你知道它通常ld通过它自己的一个组件间接调用collect2(它用于在正确的点上粘合C++构造函数调用),否则输出会令人困惑.
我发现另一篇文章包含了一个线索:-dynamic-linker /lib/ld-linux.so.2。
尝试这个:
$ gcc hello.c -S -masm=intel
$ as -o hello.o hello.s
$ ld -o hello -dynamic-linker /lib/ld-linux.so.2 /usr/lib/crt1.o /usr/lib/crti.o hello.o -lc /usr/lib/crtn.o
$ ./hello
hello, world
$
Run Code Online (Sandbox Code Playgroud)
假设正常调用gcc -o hello hello.c产生一个工作构建,运行以下命令:
gcc --verbose -o hello hello.c
Run Code Online (Sandbox Code Playgroud)
gcc 会告诉你它是如何链接事物的。这应该让您对在链接步骤中可能需要考虑的所有事情有一个很好的了解。
| 归档时间: |
|
| 查看次数: |
22631 次 |
| 最近记录: |