Reputation: 31206
I have a main method,
main.cpp:
#include "MyStruct.h"
MyStruct.h:
#ifndef MYPROJ_MYSTRUCT_H
#define MYPROJ_MYSTRUCT_H
#include <vector>
#include <unordered_map>
bool function1(std::vector<std::string> label){
// actual implementation
}
bool function2(...){ ... }
struct MyStruct{ ... }
#endif
This compiles. However, when I add the cpp
file to contain the function definitions,
main.cpp:
#include "MyStruct.h"
MyStruct.h:
#ifndef MYPROJ_MYSTRUCT_H
#define MYPROJ_MYSTRUCT_H
#include <vector>
bool function1(...){ ... }
bool function2(...){ ... }
struct MyStruct{ ... }
#endif
MyStruct.cpp:
#include "MyStruct.h"
// and that's it
Just by including the header file, I get linker errors as if I am importing the header multiple times;
Here is the CMakeLists:
cmake_minimum_required(VERSION 3.8)
set(CMAKE_CXX_STANDARD 17)
set(SOURCE_FILES main.cpp MyStruct.cpp)
add_executable(my_proj ${SOURCE_FILES})
The errors consist of all duplicate symbol errors. I am not sure how to get this to work, as this is something I do all the time using make and g++ without running into issues; I also don't seem to have this problem when I use CMake with g++ on Cygwin/Windows (this is on MacOSX).
Next, when I transition all functions to the .cpp file, and only declarations are present in the header, I eliminate most of the duplicate symbols except for :
duplicate symbol __Z8get_uvidv in:
CMakeFiles/main.cpp.o
CMakeFiles/MyStruct.cpp.o
duplicate symbol _uvid in:
CMakeFiles/main.cpp.o
CMakeFiles/MyStruct.cpp.o
ld: 2 duplicate symbols for architecture x86_64
Updated Source
// header: MyStruct.h
#ifndef MYPROJ_MYSTRUCT_H
#define MYPROJ_MYSTRUCT_H
#include <unordered_map>
#include <vector>
#include "AnotherStruct.h"
bool add_item(std::pair<std::string,float> & item);
void insert_item(std::vector<AnotherStruct> & A, std::pair<std::string,float> element);
...
struct MyStruct {
std::unordered_map<std::string,int> labels;
std::vector<AnotherStruct> data;
MyStruct(std::vector<char *> inputs);
void GetData();
void SortData(bool (*compare)(AnotherStruct &,AnotherStruct &);
//...
}
#endif
And the .cpp
:
#include "MyStruct.h"
// implement everything declared in .h
bool add_item(...){
...
}
bool insert_item(...){
...
}
MyStruct::MyStruct(...){
...
}
void MyStruct::GetData(...){
...
}
void MyStruct::SortData(...){
...
}
And the main:
#include "MyStruct.h"
The errors:
duplicate symbol __Z8get_uvidv in:
main.cpp.o
MyStruct.cpp.o
duplicate symbol _uvid in:
main.cpp.o
MyStruct.cpp.o
I have no idea what __Z8get_uvidv
could possibly be, nor _uvid
, so I assumed there was something going on with the std imports
, or underneath the hood with respect to the compiler.
Bearing in mind that everything compiles when I copy it over to the main method, or leave all definitions in the header file, I am stumped.
Upvotes: 0
Views: 330
Reputation: 36483
You have included MyStruct.h
in both main.cpp
and MyStruct.cpp
.
Include basically does a copy-paste, leaving you with 2 translation units (main.cpp
and MyStruct.cpp
) that both contain a definition for function1
and function2
(because you included the header file in both).
Solution:
Only declare the functions in the header file and define them in one translation unit only.
Upvotes: 2