考虑c.c
包含a.h
和b.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
答案 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。因此,假设您有三个翻译单元-r
,t1.c
,t2.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 make和Program Library HowTo以及this。