【问题标题】:C: compiling and linking component programs separately using 'ld'?C:使用'ld'分别编译和链接组件程序?
【发布时间】:2021-10-12 02:11:45
【问题描述】:

我试图理解extern 和链接。作为一个简单的演示,我编写了两个 C 文件:一个使用函数的主文件和另一个定义函数的文件:

/* main.c */
#include <stdio.h>
extern void print_nos(int, int);
int main(void) {
    print_nos(10, 20);
    return 0;
}
/* print_nos.c */
#include <stdio.h>
void print_nos(int lower, int higher) {
    int i;
    for (i = lower; i <= higher; i++)
        printf("%d ", i);
    printf("\n");
}

我有两个与此有关的问题:

1)

我知道我可以简单地将两个文件作为参数一次传递给 gcc:

gcc -o main main.c print_nos.c

这很好用,但我想使用ld 明确地进行链接,所以我这样做了:

$ gcc -c main.c        # produces main.o
$ gcc -c print_nos.c   # produces print_nos.o
$ ld -o main main.o print_nos.o -lc
ld: warning: cannot find entry symbol _start; defaulting to 0000000000401050

如您所见,当我尝试运行输出文件时,我收到了上述警告:

$ ./main
-bash: ./main: No such file or directory

我在组装方面没有太多经验,所以我不知道从哪里开始解决这个问题 - 感谢任何帮助。

2)

其次,当我删除 extern 说明符并尝试运行 gcc -o main.c print_nos.c 时,程序编译得很好。函数是否需要声明为extern?当我查看所有标准包含文件(如 stdlib、stdio 等)时,我发现所有函数都有一个 extern 声明。因此,我是否应该在我的情况下使用extern(在类似于上述代码的实际代码中)?

【问题讨论】:

  • 你几乎从不直接使用ld。 C 程序通常使用标准库 (-lc) 之外的一堆特定于实现的运行时库和启动文件。您需要在命令行中指定这些内容以及您自己的目标文件。只需使用gcc 代替:gcc -o main main.o print_nos.ogcc 会自动添加这些运行时库和启动文件。如果您构建没有运行时的简单汇编语言程序,或者为不使用正常运行时的嵌入式计算机构建 C 程序,则可以使用 ld
  • 我会使用gcc main.c print_nos.c -o main ...另外你可以看看这里:stackoverflow.com/questions/14163208/…

标签: c linker extern


【解决方案1】:

我不建议直接使用ld,除非您知道自己在做什么并且有充分的理由。如果您想单独编译模块(这是一个好主意,因此您可以只重新编译源文件已更改的模块)您可以使用gcc 进行编译和链接,如下所示:

gcc -c main.c        # produces main.o
gcc -c print_nos.c   # produces print_nos.o
gcc -o main main.o print_nos.o

至于extern 说明符,函数不需要它。函数声明默认为隐式extern

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-08-14
    • 1970-01-01
    • 2021-09-10
    • 1970-01-01
    • 2023-03-19
    • 2021-03-19
    • 1970-01-01
    相关资源
    最近更新 更多