makefile: символ (ы) не найден для архитектуры - PullRequest
0 голосов
/ 02 апреля 2012

Я пытаюсь решить проблему с makefile.

У меня есть main.cpp, а затем addOn.cpp и addOn.hpp.Я просто пытаюсь сделать простой make-файл для компиляции.

У меня есть:

    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

Но продолжаю получать:

    $ 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

Вот файлы
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;
}

Что я делаю не так?

Ответы [ 3 ]

5 голосов
/ 02 апреля 2012

Вы не определили деструктор или отсутствующие статические переменные. Добавьте один из них:

Log::~Log() {
}

Часть статических переменных неинтуитивна. Вы объявили их, но не определили их. Вы можете думать об этом так - все, что знает компилятор, - это то, что вы хотите использовать эти переменные. Но скажем, вы включаете Log.h 100 раз. Вы бы не хотели, чтобы компилятор создавал 100 копий одинаковых переменных. Таким образом, вы должны дать ему место, чтобы на самом деле их создать. В вашем файле Log.cpp сделайте следующее:

// Note, no 'static' keyword needed (or allowed).
std::string Log::fileName;
int Log::overallVerboseLvl;
3 голосов
/ 02 апреля 2012

иметь чистую цель, запустите команду make clean и попробуйте make.Я думаю, что у вас могут быть некоторые файлы .o из предыдущей компиляции в другой операционной системе

clean:
     <TAB> rm *.o
1 голос
/ 02 апреля 2012

Вы не определили те вещи, на которые жалуется компоновщик. Вы объявили ~ Log (), но в Log.cpp такого метода нет. Аналогично, статические переменные filename и overallVerboseLvl должны быть определены в Log.cpp.

...