编译C ++项目时奇怪的错误“`xxx`的多重定义”

时间:2013-06-09 15:48:09

标签: c++ compilation header makefile

当我尝试通过Makefile编译我的C ++项目时,我不断遇到错误:

Server.o: In function `Bot::getRandomMessage()':
/home/ubuntu/NetBeansProjects/SemestralniPraceChat/./Bot.cpp:18: multiple definition of `Bot::getRandomMessage()'
Bot.o:/home/ubuntu/NetBeansProjects/SemestralniPraceChat/./Bot.cpp:18: first defined here
Server.o: In function `Bot':
/home/ubuntu/NetBeansProjects/SemestralniPraceChat/./Bot.cpp:27: multiple definition of `Bot::Bot()'
Bot.o:/home/ubuntu/NetBeansProjects/SemestralniPraceChat/./Bot.cpp:27: first defined here
Server.o: In function `~Bot':
/home/ubuntu/NetBeansProjects/SemestralniPraceChat/./Bot.cpp:30: multiple definition of `Bot::~Bot()'
Bot.o:/home/ubuntu/NetBeansProjects/SemestralniPraceChat/./Bot.cpp:30: first defined here
Server.o: In function `~Bot':
/home/ubuntu/NetBeansProjects/SemestralniPraceChat/./Bot.cpp:30: multiple definition of `Bot::~Bot()'
Bot.o:/home/ubuntu/NetBeansProjects/SemestralniPraceChat/./Bot.cpp:30: first defined here
Server.o: In function `~Bot':
/home/ubuntu/NetBeansProjects/SemestralniPraceChat/./Bot.cpp:30: multiple definition of `Bot::~Bot()'
Bot.o:/home/ubuntu/NetBeansProjects/SemestralniPraceChat/./Bot.cpp:30: first defined here
Server.o: In function `Bot::getName()':
/home/ubuntu/NetBeansProjects/SemestralniPraceChat/./Bot.cpp:33: multiple definition of `Bot::getName()'
Bot.o:/home/ubuntu/NetBeansProjects/SemestralniPraceChat/./Bot.cpp:33: first defined here
Server.o: In function `ChatRoom::getCurrentTime()':
/home/ubuntu/NetBeansProjects/SemestralniPraceChat/./Server.cpp:74: multiple definition of `ChatRoom::getCurrentTime()'
main.o:/home/ubuntu/NetBeansProjects/SemestralniPraceChat/./Server.cpp:74: first defined here
Server.o: In function `Bot::getRandomMessage()':
/home/ubuntu/NetBeansProjects/SemestralniPraceChat/./Bot.cpp:18: multiple definition of `vectorOfThreads'
main.o:/home/ubuntu/NetBeansProjects/SemestralniPraceChat/./Server.cpp:74: first defined here
Server.o: In function `Bot::getRandomMessage()':

我对此很困惑..当我直接用命令编译它时 g++ main.cpp -Wall -pedantic -Wno-long-long -O0 -ggdb -lncurses -pthread -o AppName,然后它不会产生任何错误。所以我希望错误出现在Makefile

的某个地方
#macros
Remove=rm -rf
Doxygen=Doxyfile
RUN=./dvoram64
FLAGS=-Wall -pedantic -Wno-long-long -O0 -ggdb -pthread -lncurses -g
OBJECTS=main.o Bot.o Server.o Client.o GrumpyBot.o JokerBot.o WeatherBot.o DummyBot.o

#generates final binary and documentation
all:    $(Doxygen)
    make compile

#build into final binary
compile: $(RUN)

#run program
run:    
    make link
    $(RUN)
    $(RUN)


clean:
    $(Remove) dvoram64
    $(Remove) $(OBJECTS)

#generate documentation in '<login>/doc' folder
doc: $(Doxygen) /*
    ( cd ./ | doxygen $(Doxygen))

link: $(OBJECTS)
    g++ $(OBJECTS) -lncurses -pthread -o dvoram64

#rules how to compile into the executalble file
$(RUN): $(OBJECTS)

Bot.o: ./Bot.cpp ./Bot.h
    g++ $(FLAGS) -c ./Bot.cpp

DummyBot.o: ./DummyBot.cpp ./DummyBot.h ./Bot.h
    g++ $(FLAGS) -c ./DummyBot.cpp

GrumpyBot.o: ./GrumpyBot.cpp ./GrumpyBot.h ./Bot.h
    g++ $(FLAGS) -c ./GrumpyBot.cpp

JokerBot.o: ./JokerBot.cpp ./JokerBot.h ./Bot.h
    g++ $(FLAGS) -c ./JokerBot.cpp

WeatherBot.o: ./WeatherBot.cpp ./WeatherBot.h ./Bot.h
    g++ $(FLAGS) -c ./WeatherBot.cpp

Client.o: ./Client.cpp
    g++ $(FLAGS) -c ./Client.cpp


main.o: ./main.cpp 
    g++ $(FLAGS) -c ./main.cpp

Server.o: ./Server.cpp ./Bot.h ./JokerBot.h ./WeatherBot.h ./GrumpyBot.h ./DummyBot.h
    g++ $(FLAGS) -c ./Server.cpp

有人可以解释一下,导致这个错误的原因并告诉我,如何修复它?

3 个答案:

答案 0 :(得分:2)

查看错误消息告诉您的内容。从第一行开始:

Server.o: In function `Bot::getRandomMessage()':
/home/ubuntu/NetBeansProjects/SemestralniPraceChat/./Bot.cpp:18: multiple definition of `Bot::getRandomMessage()'

此消息表示目标文件Server.o包含函数Bot::getRandomMessage()函数的多重定义,并且多重定义来自源文件Bot.cpp中的第18行。现在看下一行:

Bot.o:/home/ubuntu/NetBeansProjects/SemestralniPraceChat/./Bot.cpp:18: first defined here

这告诉您Server.o中的定义是多重定义,因为Bot.o中也有定义。它还告诉您Bot.o中的定义来自源文件Bot.cpp中的第18行,它与源中的位置与其他定义相同。

这意味着Bot.cpp至少编译了两次,一次制作Server.o一次制作Bot.o

这可能不是你想要的。它表示当您打算包含Bot.cpp或您错误地包含Bot.h时,您的某些源文件或标题文件包含Bot.cpp。另一种可能性是你有一个编译命令可以编译Bot.cpp以生成Server.o

答案 1 :(得分:1)

一般来说,当我面对这样的事情......它出现双重规则或者项目环境搞砸了但是兄弟,这不是一个makefile问题。

你将不得不查看代码......我模拟并测试了你在这里提出的makefile,包含空文件和echo。 makefile似乎正常运行。

  Kaizen ~/so_test $ make -nf mk.t2
  make compile

  Kaizen ~/so_test $ make -nf mk.t2 compile
   echo g++ -Wall -pedantic -Wno-long-long -O0 -ggdb -pthread -lncurses -g -c ./main.cpp
   echo g++ -Wall -pedantic -Wno-long-long -O0 -ggdb -pthread -lncurses -g -c ./Bot.cpp
   echo g++ -Wall -pedantic -Wno-long-long -O0 -ggdb -pthread -lncurses -g -c ./Server.cpp
   echo g++ -Wall -pedantic -Wno-long-long -O0 -ggdb -pthread -lncurses -g -c ./Client.cpp
   echo g++ -Wall -pedantic -Wno-long-long -O0 -ggdb -pthread -lncurses -g -c ./GrumpyBot.cpp
   echo g++ -Wall -pedantic -Wno-long-long -O0 -ggdb -pthread -lncurses -g -c ./JokerBot.cpp
   echo g++ -Wall -pedantic -Wno-long-long -O0 -ggdb -pthread -lncurses -g -c ./WeatherBot.cpp
   echo g++ -Wall -pedantic -Wno-long-long -O0 -ggdb -pthread -lncurses -g -c ./DummyBot.cpp

我无法根据那里的内容推断出很多建议,srry ......

答案 2 :(得分:1)

使用g++ main.cpp -Wall -pedantic -Wno-long-long -O0 -ggdb -lncurses -pthread -o AppName进行编译时,实际上并未包含ServerClientBotDummyBot等。(您在makefile文件)。这就是为什么你没有看到这个错误。

如果main.cpp编译时没有任何其他文件,那么为什么在makefile中需要这些Client,Bot,Server等..

某处必须重新定义。尝试清理和重新编译。然后检查其报告的功能。例如Server.cpp:74Bot.cpp:18Bot::getRandomMessage()

另外令人惊讶的是你的main.cpp不会调用任何Server,Bot ......函数。如果它调用它应该抛出链接器错误。