这是 C 语言的 Hello World 代码:
// a.c
#include <stdio.h>
int main() {
printf("Hello world\n");
return 0;
}
我将其编译为 gcc a.c
,它按预期生成 a.out
并且 ./a.out
打印 Hello world
...正如预期的那样。
现在,如果我分别进行编译和链接:
gcc -c a.c; ld -lc a.o
,它运行生成为 ./a.out
的 a.out
我收到消息:
bash: ./a.out: No such file or directory
我用 Google 搜索了那个错误,似乎当生成的可执行文件是 32 位 ELF 而机器架构是 64 位时会发生这种情况。
我正在运行 64 位机器并运行 file a.out
给出:
a.out: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), not stripped
为什么会这样?
编辑:
uname -m
的输出
$ uname -m
x86_64
ldd a.out
的输出
$ ldd a.out
linux-vdso.so.1 => (0x00007ffeeedfb000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fa13a7b8000)
/lib64/ld-linux-x86-64.so.2 (0x00007fa13abab000)
gcc a.c
生成正确运行的 a.out
。
最佳答案
ld -lc a.o
这个命令行有几个问题:
一般来说,用户级代码应该从不直接使用
ld
,并且总是使用适当的编译器前端(gcc
here) 执行链接。正如您所发现的,
gcc
构造的链接命令行非常复杂,您在 Joan Esteban 的回答中接受的命令行是错误的。如果您想查看实际 链接命令,请检查
gcc -v a.o
的输出。另请注意,当您仅稍微更改
gcc
命令时,链接命令会发生显着变化(例如,某些操作系统需要不同的crt1.o
,具体取决于您是否正在链接多线程可执行文件或不),并且命令行始终是特定于操作系统的(这是从不直接使用ld
的另一个原因)。库应该跟在命令行上的目标文件之后。所以
ld -lc a.o
从不是正确的,并且应该总是是ld a.o -lc
的(变体) . Explanation .
关于c - `bash: ./a.out: No such file or directory` 运行由 `ld` 生成的可执行文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33970159/