c - `bash: ./a.out: No such file or directory` 运行由 `ld` 生成的可执行文件

标签 c linux gcc linker dynamic-linking

这是 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.outa.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

这个命令行有几个问题:

  1. 一般来说,用户级代码应该从不直接使用ld,并且总是使用适当的编译器前端(gcc here) 执行链接。

    正如您所发现的,gcc 构造的链接命令行非常复杂,您在 Joan Esteban 的回答中接受的命令行是错误的。

    如果您想查看实际 链接命令,请检查gcc -v a.o 的输出。

    另请注意,当您仅稍微更改 gcc 命令时,链接命令会发生显着变化(例如,某些操作系统需要不同的 crt1.o ,具体取决于您是否正在链接多线程可执行文件或不),并且命令行始终是特定于操作系统的(这是从不直接使用 ld 的另一个原因)。

  2. 库应该跟在命令行上的目标文件之后。所以 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/

相关文章:

php - Cron Job 命令不起作用

c++ - Linux 中的代码执行时间

c++ - WebKitGTK 中的 Ext JS webkit_web_view

将 char 指针转换为 int 指针 - 缓冲区错误 10

c - 什么会导致指针分配出现段错误?

c++ - GCC 的 wchar_t 有多大?

无法理解 C 源代码,它不能在 GCC 中编译,但在 Visual C++ 中编译

C while无限循环打印错误

c++ - 如何在 Ubuntu 20.04 上安装 libstdc++6 调试符号?

c++ - 使用大括号将临时值初始化为静态数据成员的初始化程序会导致错误