I use these two files here and here.
I created a class in two separate files:
modul1.h
#ifndef MODUL1_H
#define MODUL1_H
#include <iostream>
#include <fstream>
#include "easylogger.h"
class Modul1
{
public:
Modul1(std::string name);
protected:
private:
easylogger::Logger *log;
};
#endif // MODUL1_H
and modul1.cpp
#include "modul1.h"
Modul1::Modul1(std::string name):log(new easylogger::Logger(name))
{
//ctor
//std::ofstream *f = new std::ofstream(name.c_str(), std::ios_base::app);
//log->Stream(*f);
//log->Level(easylogger::LEVEL_DEBUG);
//LOG_DEBUG(*log, "ctor ende!");
}
Now I want to use this class in another file (main.cpp):
#include "modul1.h"
int main()
{
std::cout << "Hello world!" << std::endl;
Modul1 mod1("test.log");
return 0;
}
When I compile it with the following Makefile, I get a "multiple definition of..." error:
g++ main.o modul1.o -o main
modul1.o: In functioneasylogger::Logger::Format(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)
:
modul1.cpp:(.text+0x0): multiple definition ofeasylogger::Logger::Format(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)
main.o:main.cpp:(.text+0x0): first defined here
modul1.o: In functioneasylogger::Logger::WriteLog(easylogger::LogLevel, easylogger::Logger*, char const*, unsigned int, char const*, char const*)
: modul1.cpp:(.text+0x2a): multiple definition ofeasylogger::Logger::WriteLog(easylogger::LogLevel, easylogger::Logger*, char const*, unsigned int, char const*, char const*)
main.o:main.cpp:(.text+0x2a): first defined here
collect2: ld returned 1 exit status
(At first I compiled it with code::blocks and got the same error)
How can I modify my Modul1 in order not to get this linking error? I don't think it is important, but I am using some Ubuntu 64bit with g++ 4.4.3
Makefile:
CC=g++
CFLAGS=-c -Wall
all: log_test
log_test: main.o easylogger.h modul1.o
$(CC) main.o modul1.o -o main
main.o: main.cpp modul1.h
$(CC) $(CFLAGS) main.cpp
modul1.o: modul1.cpp modul1.h
$(CC) $(CFLAGS) modul1.cpp
The way you are building this, easylogger.h (and consequently easylogger-inl.h) gets included twice, once for modul1.h and once for main.cpp
Your usage of it is wrong. But you can do this to make it work:
In modul1.h (remove #include "easylogger.h") and make it look like this
#ifndef MODUL1_H
#define MODUL1_H
#include <iostream>
#include <fstream>
//#include "easylogger.h"
namespace easylogger { class Logger; };
class Modul1
{
public:
Modul1(std::string name);
protected:
private:
easylogger::Logger *log;
};
#endif // MODUL1_H
and for modul1.cpp, include the real thing
#include "modul1.h"
#include "easylogger.h"
Modul1::Modul1(std::string name):log(new easylogger::Logger(name))
{
//ctor
//std::ofstream *f = new std::ofstream(name.c_str(), std::ios_base::app);
//log->Stream(*f);
//log->Level(easylogger::LEVEL_DEBUG);
//LOG_DEBUG(*log, "ctor ende!");
}
Good luck!
You include "easylogger-impl.h" in both of your translation units. There are function definitions in easylogger-impl.h. Therefore, you have multiple definitions of your functions.
The one definition rule says that you must have one, and only one, definition of any object or function.
You may solve this problem either by marking all of the easylogger-impl functions as inline
, or by ensuring that they appear in only one translation unit.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With