我可以单独编译我的两个文件serveur.c和client.c但是当我尝试使用makefile时,它会显示一个错误。我想要的很简单:两个编译文件:serveur.o和client.o。
以下是我分别编译两个文件时的代码:
gcc -lpthread serveur.c -o serveur.o
和
gcc -lpthread client.c -o client.o
这是我的makefile:
chatroom: serveur.o client.o
gcc serveur.o client.o -o chatroom
serveur.o: serveur.c
gcc -lpthread serveur.c -o serveur.o
client.o: client.c
gcc -lpthread client.c -o client.o
这是我写的错误:" make -f makefile"在终端
gcc serveur.o client.o -o chatroom
duplicate symbol _main in:
serveur.o
client.o
ld: 1 duplicate symbol for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make: *** [chatroom] Error 1
感谢您的帮助! :)
答案 0 :(得分:2)
如果您成功地将两个独立的部分分别构建到一个程序中,则意味着两个源文件都包含main()
或main(int, char*[])
。但是,每个程序只能有一个main()
函数(您可以将每个函数定义一次的限制实际应用于所有函数)。
如果这两个文件中的每一个都包含一个完整的程序,那么你不可能只将它们链接在一起:除了重复main()
之外,每个程序都会有一些设置和一些控制。也就是说,简单地删除其中一个main()
函数不太可能导致工作程序。
如果您刚刚向其中一个来源添加了main()
函数,否则它不会“编译”,您需要摆脱这个main()
并确保您实际< em>通过传递-c
选项将代码编译成目标文件。当链接代码时,您将关闭-c
选项。
答案 1 :(得分:1)
编译器,汇编器和链接器在创建可执行文件时的工作方式可能存在一些误解。
通常的惯例是将.o扩展名赋予汇编程序阶段后生成的目标文件而不是可执行文件!
由于gcc将充当编译,汇编和链接管理器,在一次运行中执行所有步骤而不会被告知在较早阶段停止gcc -lpthread serveur.c -o serveur.o
和
gcc -lpthread client.c -o client.o
将创建可执行文件而不是对象文件。
要在汇编阶段后停止gcc,必须将-c
开关传递给它。 gcc -c serveur.c
和gcc -c client.c
。在这种情况下,不需要提供-o serverveur.o
和-o client.o
,因为默认情况下gcc会使用它们。
要链接生成的目标文件,最后要做的事情是gcc -lpthread serveur.o client.o -o chatroom
一个Makefile来完成所有看起来像这样的事情:
chatroom: serveur.o client.o
gcc -lpthread $^ -o $@
不幸的是,这仍然无法解决你有两个main()函数定义的问题,一个在serveur.c中,另一个在client.c中。
由于gcc -lpthread serveur.c -o serveur.o
和gcc -lpthread client.c -o client.o
已被链接器拒绝,并且未解析对main的引用,我很确定您的两个源都包含定义。
如果不是构建一个可执行文件而是想让你创建两个可执行文件serveur
和client
,那么你的Makefile看起来应该是这样的。
.PHONY: all
all: serveur client