【问题标题】:How to compile with a .o file that was compiled with other .o files (C99)如何使用与其他 .o 文件 (C99) 一起编译的 .o 文件进行编译
【发布时间】:2015-03-11 20:33:32
【问题描述】:

考虑c.c 包含a.hb.h 的代码,以及main.c 包含c.h 的代码 我试着像这样编译它

gcc --std=c99 -o a.o -c a.c
gcc --std=c99 -o b.o -c b.c
gcc --std=c99 -o c.o -c c.c a.o b.o

但是当我运行最后一个时,gcc 对我大喊大叫

gcc --std=c99 -o c.o -c c.c a.o b.o
gcc: warning: a.o: linker input file unused because linking not done
gcc: warning: b.o: linker input file unused because linking not done

然后当我尝试使用 gcc -o main main.c c.o 编译 main.c 文件时,它说有很多未定义的引用,一旦 c 文件未正确编译,这是可以预测的。

我在 stackoverflow 上看到了一些类似的问题,但我无法让它工作。

我在 Arch Linux 上运行 gcc v4.9.2-3

【问题讨论】:

  • 你试过gcc --std=c99 -o c.o b.o a.o c.c吗?
  • 在哪个操作系统上,使用哪个版本的 GCC?你为什么要问?你不只是想链接一些可执行文件吗?请编辑您的问题以改进它!
  • @ForceBru 如果我这样做,它会告诉我undefined reference to main,因为 c.o 不是最终程序,它稍后将与 main.c 一起使用以创建最终的可执行文件

标签: c gcc compilation linker c99


【解决方案1】:

首先,它是-std=c99,带有一个破折号。

我猜你是在 Linux 上。

然后,您应该始终将-Wall -Wextra -g(尤其是因为您是新手)传递给gcc-Wall 要求几乎所有警告,-Wextra 要求更多警告,@ 987654335@询问调试信息。

最后,你想生成一个可执行文件myprog(不要将可执行文件命名为c.o,这应该是一个目标文件)

gcc -std=c99 -Wall -Wextra -g -o myprog c.c a.o b.o

您需要删除任何-c,因为您希望链接发生。

如果你的意思是 - 但现在这很不寻常,最好制作共享库!- 将多个对象文件聚合到一个 all.o(稍后与其他对象链接)你可以试试-r linker option

gcc -std=c99 -Wall -Wextra -g -r c.c a.o b.o -o all.o

但我上次尝试是在上个世纪,所以细节可能有误。

使用-r 链接器选项聚合对象的理由很少。除非你真的知道自己在做什么,否则你很可能是错的(尝试-r)。

也许你想创建一个software library。如今,制作共享库要好得多。共享库(技术上是ELF 共享对象)应该包含position independent code。因此,假设您有三个翻译单元t1.ct2.ct3.c,您首先将它们编译为 PIC:

 gcc -std=c99 -Wall -Wextra -g -fPIC t1.c -c -o t1.pic.o
 gcc -std=c99 -Wall -Wextra -g -fPIC t2.c -c -o t2.pic.o
 gcc -std=c99 -Wall -Wextra -g -fPIC t3.c -c -o t3.pic.o

然后将所有这些 PIC 对象文件链接到共享库 libmyt.so

 gcc -std=c99 -Wall -Wextra -g -shared \
    t1.pic.o t2.pic.o t3.pic.o \
    -o libmyt.so

稍后您将使用此共享库,例如作为

 gcc -std=c99 -Wall -Wextra -g main.o -o myprog -Wl,-rpath . libmyt.so

或作为

 gcc -std=c99 -Wall -Wextra -g main.o -o myprog -Wl,-rpath . -L. -lmyt

您可以考虑使用ar 进行静态链接以创建静态库libmyt.a,但我不建议这样做。


当然,您将使用gdb ./myprog 调试您的程序,并且您可以尝试使用./myprog 运行它。要使用valgrind,请尝试valgrind ./myprog

如果您有多个翻译单元,最好学习如何使用GNU make。阅读Program Library HowTothisthese hints

【讨论】:

  • 我真正的意思是聚合对象以供以后使用,就像你说的那样,但现在 ld(链接器)告诉我 ld: cannot find -lgcc_s 我找不到任何对 -r on 的引用gcc 手册页,它的真正含义是什么?
  • -r 是一个链接器选项。但是如果你想聚合对象,创建一个静态库(使用ar)或者更好的是共享对象。
猜你喜欢
  • 1970-01-01
  • 2016-05-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-08
  • 2016-06-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多