2013-06-09 2 views
0

Когда я пытаюсь скомпилировать мой проект C++ с помощью моей Makefile я продолжаю получать ошибки, как те:Weird ошибка «множественное определение` xxx`»при компиляции 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 

Может кто-нибудь, пожалуйста, объясните мне, что вызывает эту ошибку и показать мне, как это исправить?

+0

Но что именно я должен публиковать? Эта проблема зависит от всего проекта, содержащего больше классов. Я не думаю, что нужен какой-то исходный код, потому что, как я уже сказал, я уверен, что код можно скомпилировать и запустить, поэтому проблема, вероятно, в 'Makefile' – Dworza

+0

. Это ошибки компоновщика, а не ошибки компилятора. –

+0

@chris Если эти ошибки не будут вызваны компоновщиком, а кодом, вы не думаете, что он не будет компилировать и запускать его вообще? Как я писал в своем сообщении, я МОГУ Скомпилировать и запустить приложение, когда компилирую его с помощью 'g ++ main.cpp -Wall -pedantic -Wno-long-long -O0 -ggdb -lncurses -pthread -o AppName'. Тем не менее мне нужно использовать 'Makefile', поэтому я не могу использовать этот комманд для компиляции навсегда – Dworza

ответ

2

Посмотрите, что сообщают вам сообщения об ошибках. Начнем с первых строк:

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

Это сообщение говорит о том, что объектный файл Server.o содержит несколько определение функции функции Bot::getRandomMessage(), и что многократное определение происходит от линии 18 в исходном файле Bot.cpp. Теперь посмотрим на следующую строку:

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

Это говорит о том, что определение в Server.o кратна определение, потому что есть также определение в Bot.o. Он также сообщает вам, что определение в Bot.o произошло из строки 18 в исходном файле Bot.cpp, который является тем же местом в источнике, что и другое определение.

Это означает, что Bot.cpp был составлен по крайней мере дважды, один раз, чтобы сделать Server.o и один раз, чтобы сделать Bot.o.

Это, вероятно, не то, что вы хотите.Это предполагает, что некоторые из ваших исходных или заголовочных файлов включают Bot.cpp, когда вы хотели включить Bot.h, или что вы в противном случае включили Bot.cpp. Другая возможность заключается в том, что у вас есть команда компиляции, которая компилирует Bot.cpp, чтобы сделать Server.o.

+0

Я включаю везде файлы '* .cpp', так что это может быть проблемой. Если я включил там классы '* .h', он заставил меня получать ошибки, например' /home/ubuntu/NetBeansProjects/SemestralniPraceChat/Server.cpp:186: неопределенная ссылка на 'Bot :: getRandomMessage() ' /home/ubuntu/NetBeansProjects/SemestralniPraceChat/Server.cpp: 186: неопределенная ссылка на 'Bot :: getName() '' Из-за этого, я подумал, что я должен включать '* .cpp' ~~> becuase Bot.h определяет только интерфейс и в 'Bot.cpp' я включаю' Bot.h' и реализую все функции ... вот как я думал .. Разве это не правильно? – Dworza

+1

@Dworza: Вы неправильно структурировали исходные файлы и сборку проекта. Как правило, исходные файлы должны включать только заголовочные файлы для объявления вещей; они не должны включать другие исходные файлы для определения вещей. Вы используете привязку для предоставления определений: каждый исходный файл скомпилирован в объектный модуль, а затем необходимые объектные модули связаны между собой, чтобы предоставить одну исполняемую программу. –

1

Обычно, когда я сталкиваюсь с чем-то вроде этого ... его появление двойного правила или среда проекта перепутаны, но Брат, это не проблема с файлами.

вам нужно будет изучить код ..... Я смоделировал и протестировал make-файл, который вы задали здесь, с пустыми файлами и эхом. Файл 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 ...

+0

Можете ли вы объяснить, что вы подразумеваете под «двойным правилом»? – Dworza

+0

хорошо, когда у вас есть цель, указанная дважды в файле дескриптора .... подумайте об этом компиляции: $ (RUN), упомянутом в верхней части файла makefile, а внизу утилита make читает компиляцию: $ (OBJECTS) .. .. так что дознаватель знает, какое действие нужно делать, когда нужно построить компиляцию цели, но тогда он не даст вам имя функции в тексте ошибки – nsd

1

При компиляции с g++ main.cpp -Wall -pedantic -Wno-long-long -O0 -ggdb -lncurses -pthread -o AppName вы на самом деле не включаете ваш Server, Client, Bot, DummyBot и т.д. (Это вы имеете в своем make-файле). Вот почему вы не видите эту ошибку.

также Если main.cpp компилируется без каких-либо других файлов, зачем вам нужен этот клиент, Bot, сервер и т. Д. В вашем файле makefile?

Должно быть какое-то переопределение. попробуйте очистить и перекомпилировать. а затем проверить функции, которые его отчеты. например Server.cpp:74, Bot.cpp:18, Bot::getRandomMessage()

также удивительно, что ваш main.cpp не вызывает никаких функций сервера, Bot .... Если он называет его предполагаемым бросить ошибки компоновщика.

Смежные вопросы