如何使用与其他 .o 文件一起编译的 .o 文件进行编译 (C99)

How to compile with a .o file that was compiled with other .o files (C99)

考虑 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 文件不正确,这是可以预测的已编译。

我在 Whosebug 上看到了一些类似的问题,但我无法让它以任何方式工作。

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

首先是-std=c99单横线

我猜你在 Linux.

然后,你总是应该将 -Wall -Wextra -g(特别是因为你是新手)传递给 gcc : -Wall 要求 nearly all警告,-Wextra 更多警告,-g 要求调试信息。

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

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

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

如果你的意思是 - 但今天这很不寻常,最好制作共享库! - 将几个目标文件聚集成一个 all.o (稍后 link 与其他对象一起编辑)你可以试试 -r linker option

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

不过我上次试是在上个世纪,所以细节可能有误

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

也许你想做一个software library. These days it is much better to make a shared library. A shared library (technically an ELF shared object) should contain 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

然后你 link 将所有这些 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

您可能会考虑使用静态 linking 和 ar 来制作静态库 libmyt.a,但我不建议这样做。


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

如果你有多个翻译单元,最好学习如何使用GNU make. Read the Program Library HowTo and this and these hints