如何使用与其他 .o 文件一起编译的 .o 文件进行编译 (C99)
How to compile with a .o file that was compiled with other .o files (C99)
考虑 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
文件不正确,这是可以预测的已编译。
我在 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.c
、t2.c
、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
然后你 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。
考虑 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
文件不正确,这是可以预测的已编译。
我在 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.c
、t2.c
、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
然后你 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。