kotoko
kotoko

Reputation: 599

makefile: symbol(s) not found for architecture

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

Answers (3)

parkovski
parkovski

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

ergosys
ergosys

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

tartar
tartar

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

Related Questions