2

I'm using a Qt and Cmake for a project and I'm a newbie with those two things, so please bear with me.

I have two class using Qt, one named MapMaker and another named ImageLabel. MapMaker inherited from QMainWindow and ImageLabel from QLabel

Imagelabel possess a Class as attribute that I named Map that possess a method addObstacle. MapMaker posses an imageLabel and ImageLabel possess a Map.

Every method of Map is in the Map.hpp file while MapMaker and ImageLabel method are in a .cpp file.

When I'm compiling, I have this error :

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 

I've double check all of my ifndef define (header guards) at the beginning of every header files and they are not the same.

What's funny is that if I inline the method addObstacle then the error disappear.

Here is my 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) 

I tried to compile a test file with no Qt-dependant files (no ImageLabel nor MapMaker) and only some custom class I made and the compiling goes fine. My guess is that the error is linked to the Qt part (some project configuration I have not done or I donät know about) but I have no idea how.

The only error I know that throws a multiple definition error is a mistake in the header guards. What else could be the reason for this here ?

I know it's a pretty messy question for now, just tell me what information I should provide to help.

1 Answer 1

3

Include guards only protects for multiple inclusion of the same header file in the same translation unit (a source file with all headers). It does not protect against multiple definitions in different translation units.

Either make the function definitions inline (if it makes sense to do so) or move them into their own source file.

Sign up to request clarification or add additional context in comments.

3 Comments

Inlining everything would be easier wouldn't it ?
@Malc Remember that inline is just a hint to the compiler, one the compiler can ignore (in which case the function is not inlined but still local in each translation unit and not exported). Also, making a function only makes sense for functions that can be inlined, like for example small functions in loops, simple getter or setter functions, etc. Larger or more complicated functions should really be put in a separate source file.
Thanks a lot for all the clear explanations. It is really helpful !

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.