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

时间:2015-03-11 20:33:33

标签: c gcc compilation linker 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文件未正确编译,这是可预测的。

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

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

1 个答案:

答案 0 :(得分:0)

首先,-std=c99只有一个破折号。

我猜你是在Linux上。

然后,你总是应该-Wall -Wextra -g(特别是因为你是新手)到gcc-Wall要求几乎所有警告,{{1对于更多警告,-Wextra要求调试信息。

最后,您希望生成一个可执行文件-g(不要将可执行文件命名为myprog,这应该是一个目标文件)

c.o

您需要删除任何gcc -std=c99 -Wall -Wextra -g -o myprog c.c a.o b.o ,因为您希望链接发生。

如果你的意思是 - 但今天非常不寻常,那么最好制作共享库! - 将几个目标文件聚合成一个-c(稍后与其他对象链接)你可以尝试{{3} }

all.o

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

使用gcc -std=c99 -Wall -Wextra -g -r c.c a.o b.o -o all.o 链接器选项聚合对象的原因很少。除非你真的知道自己在做什么,否则你很可能错了(尝试-r)。

也许你想制作一个-r linker option。现在,制作共享库要好得多。共享库(技术上是software library共享对象)应包含ELF。因此,假设您有三个翻译单元-rt1.ct2.c,您首先将它们编译为PIC:

t3.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

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运行它。要使用position independent code,请尝试./myprog

如果您有多个翻译单元,请更好地学习如何使用valgrind。阅读GNU makeProgram Library HowTo以及this