I’m trying to solve an issue with makefile.
I have a main.cpp and then addOn.cpp and addOn.hpp.
I’m just trying to do the simple makefile to compile this.
I have:
main: Main.o Log.o
g++ -o main Main.o Log.o
Main.o: main.cpp Log.hpp
g++ -c main.cpp
Log.o: Log.cpp Log.hpp
g++ -c Log.cpp
But keep getting:
$ make
g++ -c main.cpp
g++ -c Log.cpp
g++ -o main Main.o Log.o
Undefined symbols for architecture x86_64:
"Log::~Log()", referenced from:
_main in Main.o
"Log::overallVerboseLvl", referenced from:
Log::setLevel(int) in Log.o
Log::Log() in Log.o
Log::Log() in Log.o
Log::operator<<(char const*)in Log.o
"Log::fileName", referenced from:
Log::setFile(std::basic_string<char, std::char_traits<char>, std::allocator<char> >)in Log.o
Log::Log(int)in Log.o
Log::Log(int)in Log.o
Log::Log() in Log.o
Log::Log() in Log.o
ld: symbol(s) not found for architecture x86_64
collect2: ld returned 1 exit status
make: *** [main] Error 1
Here are the files
main.cpp
#include <iostream>
#include <string.h>
#include "Log.hpp"
int main(int argc, char *argv[]) {
Log::setFile("output.log");
Log(Log::LEVEL_INF) << "out and up...";
Log::setLevel(Log::LEVEL_INF);
Log(Log::LEVEL_INF) << "another line";
Log(Log::LEVEL_ERR) << "now a number: " << 13;
Log(Log::LEVEL_DBG) << "I shall not pass";
return 0;
}
Log.hpp
#ifndef log_Log_hpp
#define log_Log_hpp
#include <string.h>
class Log{
private:
static std::string fileName;
static int overallVerboseLvl;
int messageVerboseLvl;
public:
static const int LEVEL_INF;
static const int LEVEL_ERR;
static const int LEVEL_DBG;
Log(int verboseLvl);
Log();
~Log();
std::ostream& operator<<(char const*);
static void setFile(std::string file);
static void setLevel(int level);
};
#endif
Log.cpp
#include <iostream>
#include <string.h>
#include "Log.hpp"
const int Log::LEVEL_INF = 0;
const int Log::LEVEL_ERR = 1;
const int Log::LEVEL_DBG = 2;
void Log::setLevel(int level){
Log::overallVerboseLvl = level;
}
void Log::setFile(std::string fileName ){
Log::fileName = fileName;
}
Log::Log(){
Log::fileName = "";
Log::overallVerboseLvl = Log::LEVEL_DBG;
}
Log::Log(int verboseLvl){
Log::fileName = "";
Log::messageVerboseLvl = verboseLvl;
}
std::ostream& Log::operator<<(char const* text){
if (Log::overallVerboseLvl >= Log::messageVerboseLvl) {
std::cout << text;
}
return std::cout;
}
What am I doing wrong?
You haven’t defined the destructor or the missing static variables. Add one of these:
The static variables part is kind of unintuitive. You’ve declared them, but haven’t defined them. You can think of it like this – all the compiler knows is that you want to be able to use those variables. But say you include
Log.h100 times. You wouldn’t want the compiler to create 100 copies of the same variables. So you have to give it a place to actually instantiate them. In yourLog.cppfile, do this: