Reputation: 599
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?
Upvotes: 0
Views: 1314
Reputation: 1523
You haven't defined the destructor or the missing static variables. Add one of these:
Log::~Log() {
}
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.h
100 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 your Log.cpp
file, do this:
// Note, no 'static' keyword needed (or allowed).
std::string Log::fileName;
int Log::overallVerboseLvl;
Upvotes: 5
Reputation: 49049
You haven't defined those things the linker is complaining about. You have declared ~Log() but there's no such method in Log.cpp. Similiarly, the static variables filename
and overallVerboseLvl
must be defined in Log.cpp.
Upvotes: 1
Reputation: 688
have a clean target, run make clean command and then try make. I think you may have some .o files from a previous compilation on different operating system
clean:
<TAB> rm *.o
Upvotes: 3