2015-07-27 11 views
1

Я использую Qt и Cmake для проекта, и я новичок с этими двумя вещами, поэтому, пожалуйста, несите меня.CMake и QT multiple definition

У меня есть два класса с использованием Qt, один по имени MapMaker и другой по имени ImageLabel. MapMaker унаследовал от QMainWindowImageLabel и от QLabel

Imagelabel обладают класса как атрибут, который я назвал карту, что владеть методом addObstacle. MapMaker обладает imageLabel, а ImageLabel имеет карту.

Каждый метод Map находится в файле Map.hpp, в то время как метод MapMaker и ImageLabel находится в файле .cpp.

Когда я компиляция, у меня есть эта ошибка:

CMakeFiles/mapmakerv3.dir/includes/Qtfiles/MapMakerv3.cpp.o: In function `Map::drawObstacle(int, int, bool)': 
/home/malcolm/AASS/sketch_maker/includes/MapInterpretation/Map.hpp:431: multiple definition of `Map::addObstacle(int, int, bool)' 
CMakeFiles/mapmakerv3.dir/main.cpp.o:/home/malcolm/AASS/sketch_maker/includes/MapInterpretation/Map.hpp:431: first defined here 
CMakeFiles/mapmakerv3.dir/includes/Qtfiles/imageLabel.cpp.o: In function `Map::drawObstacle(int, int, bool)': 
/home/malcolm/AASS/sketch_maker/includes/MapInterpretation/Map.hpp:431: multiple definition of `Map::addObstacle(int, int, bool)' 
CMakeFiles/mapmakerv3.dir/main.cpp.o:/home/malcolm/AASS/sketch_maker/includes/MapInterpretation/Map.hpp:431: first defined here 
CMakeFiles/mapmakerv3.dir/mapmakerv3_automoc.cpp.o: In function `Map::drawObstacle(int, int, bool)': 
/home/malcolm/AASS/sketch_maker/includes/MapInterpretation/Map.hpp:431: multiple definition of `Map::addObstacle(int, int, bool)' 
CMakeFiles/mapmakerv3.dir/main.cpp.o:/home/malcolm/AASS/sketch_maker/includes/MapInterpretation/Map.hpp:431: first defined here 
collect2: error: ld returned 1 exit status 
CMakeFiles/mapmakerv3.dir/build.make:187: recipe for target 'mapmakerv3' failed 
make[2]: *** [mapmakerv3] Error 1 
CMakeFiles/Makefile2:60: recipe for target 'CMakeFiles/mapmakerv3.dir/all' failed 
make[1]: *** [CMakeFiles/mapmakerv3.dir/all] Error 2 
Makefile:76: recipe for target 'all' failed 
make: *** [all] Error 2 

Я дважды проверить все мои ifndef (охранников заголовка) define в начале каждого файла заголовок, и они не являются одинаковыми.

Что смешно в том, что если я inline метод addObstacle, тогда ошибка исчезнет.

Вот мой Cmake:

cmake_minimum_required(VERSION 2.6) 
project(mapmakerv3) 

set (MapMaker_VERSION_MAJOR 1) 
set (MapMaker_VERSION_MINOR 0) 

find_package(Qt4 REQUIRED) 
find_package(OpenCV REQUIRED) 

find_package(Boost REQUIRED) 

if (NOT Boost_FOUND) 
    message(STATUS "This project requires the Boost library, and will not be compiled.") 
    return() 
endif() 

include_directories("${PROJECT_BINARY_DIR}" ${QT_INCLUDES} ${CMAKE_CURRENT_BINARY_DIR} includes includes/Qtfiles includes/MapInterpretation/ includes/TopologicalMap/ includes/MapComparator/ Test/Ddata/) 

set(CMAKE_AUTOMOC TRUE) 
set(CMAKE_INCLUDE_CURRENT_DIR ON) 
add_executable(mapmakerv3 main.cpp includes/Qtfiles/MapMaker.cpp includes/Qtfiles/imageLabel.cpp) 
target_link_libraries(mapmakerv3 ${QT_QTCORE_LIBRARY} ${QT_QTGUI_LIBRARY} ${OpenCV_LIBS}) 

install(TARGETS mapmakerv3 RUNTIME DESTINATION bin) 
add_subdirectory(includes) 

Я попытался скомпилировать тестовый файл без каких-либо Qt-зависимых файлов (не ImageLabel ни картографа) и только некоторые пользовательского класса я сделал и компилирование идет хорошо. Я предполагаю, что ошибка связана с частью Qt (какая-то конфигурация проекта, которую я не сделал, или я не знаю), но я понятия не имею, как это сделать.

Единственная ошибка, я знаю, что ошибка multiple definition является ошибкой в ​​защите заголовков. Что еще может быть причиной этого здесь?

Я знаю, что сейчас это довольно грязный вопрос, просто скажите мне, какую информацию я должен предоставить, чтобы помочь.

ответ

3

Include guards защищает только для множественного включения одного и того же заголовочного файла в том же translation unit (исходный файл со всеми заголовками). Он не защищает от множества определений в разных единицах перевода.

Либо сделайте определения функций inline (если имеет смысл это сделать) или переместите их в свой исходный файл.

+0

Вложение все было бы проще, не так ли? – Malcolm

+2

@Malc Помните, что 'inline' - это всего лишь * подсказка * для компилятора, одна из которых может игнорировать компилятор (в этом случае функция не включена, но все же локальна в каждой единицы перевода и не экспортируется). Кроме того, создание функции имеет смысл только для функций, которые * могут * быть встроены, например, как небольшие функции в циклах, простые функции getter или setter и т. Д. Большие или более сложные функции действительно должны быть помещены в отдельный исходный файл. –

+0

Большое спасибо за все четкие объяснения. Это действительно полезно! – Malcolm