Undefined reference to member of class in library

320
23 января 2017, 19:26

Итак, у меня есть 1 тестовое приложение и 1 библиотека, которая подключается к приложению. Проблема заключается в том, что, функции неопределенны, но я никак не могу понять почему. 1. Код тестового приложения: main.cpp

#include "log.h"

int main(int argc, char* argv[])
{
    Log::Get()->Print("Test %d", 50);
    delete Log::Get();
    return 0;
}

и Makefile

CC=g++
LINK=g++
LIBARIES=-lDeka
CFLAGS= -c -O0 -std=c++14 -Wall -I ../SDL_DekaLib/include
LINKFLAGS= -O0 -std=c++14 -Wall -I ../SDL_DekaLib/include -L . $(LIBARIES)
all: main.o libDeka.a
    $(LINK) $(LINKFLAGS) main.o -o test.exe
main.o: main.cpp
    $(CC) $(CFLAGS) main.cpp -o main.o
libDeka.a: log.o
    ar rc libDeka.a log.o
log.o: log.cpp
    $(CC) $(CFLAGS) log.cpp -o log.o
clean:
    del *.o
    del *.exe
    del *.a

ну и для галочки вывод в консоли

g++ -c -O0 -std=c++14 -Wall -I ../SDL_DekaLib/include main.cpp -o main.o
g++ -c -O0 -std=c++14 -Wall -I ../SDL_DekaLib/include log.cpp -o log.o
ar rc libDeka.a log.o
g++ -O0 -std=c++14 -Wall -I ../SDL_DekaLib/include -L . -lDeka main.o -o test.exe
main.o:main.cpp:(.text+0x10): undefined reference to `Log::Get()'
main.o:main.cpp:(.text+0x28): undefined reference to `Log::Print(char const*, ...)'
main.o:main.cpp:(.text+0x2d): undefined reference to `Log::Get()'
main.o:main.cpp:(.text+0x3a): undefined reference to `Log::~Log()'

Теперь библиотека. Она состоит только из логов:

log.h

#include <cstdio>
#include <cstdlib>
#include <ctime>
#include <clocale>
#include <cstdarg>
class Log
    {
    public:
        Log();
        ~Log();
        static Log* Get();
        void Print(const char* message, ...);
        void Debug(const char* message, ...);
        void Error(const char* message, ...);
    private:
        static Log* _instance;
        FILE* _file;
        void _print(const char* lvltext, const char* message);
        void _init();
        void _close();
    };

log.cpp - реализацию убрал, ибо не должна влиять на проблему, надеюсь.

#include "log.h"
Log* Log::_instance = nullptr;
void Log::_init()
    {
        ...
    }
void Log::_close()
    {
        ...
    }
Log::Log() : _file(nullptr)
    {
        _init();
    }
Log::~Log()
    {
        _close();
        _instance = nullptr;
    }
Log* Log::Get()
    {
        if(!Log::_instance)
            Log::_instance = new Log();
        return Log::_instance;
    }
void Log::Print(const char* message, ...)
    {
        ...
    }
void Log::Debug(const char* message, ...)
    {
#ifdef DEBUG
        ...
#endif // DEBUG
    }
void Log::Error(const char* message, ...)
    {
        ...
    }
    void Log::_print(const char* lvltext, const char* message)
    {
        ...
    }
Answer 1

Надо немного порядок поменять:
Было:

all: main.o libDeka.a
    $(LINK) $(LINKFLAGS) main.o -o test.exe

Стало:

all: main.o libDeka.a
    $(LINK) main.o $(LINKFLAGS) -o test.exe

А еще лучше:

all: main.o libDeka.a
    $(LINK) -o test.exe main.o $(LINKFLAGS)
Answer 2

Есть мысль, что библиотека Deka просто не пересобирается, а основной модуль ссылается на некоторую пустышку, в которой ещё нет реализации. Убедитесь, что libDeka.a обновляется и что именно обновлённый файл линкер использует при сборке main.

Для упрощения поиска проблемы я бы предложил исключить лишние функции, библиотеки и избавиться от пространства имён. Короче говоря попытайтесь создать Минимальный, самодостаточный и воспроизводимый пример.

Проверьте, что проблемы не возникает, если отказаться от использования библиотеки и ограничиться одним Makefile, где прописано правило сборки log.o в составе единого модуля. Примерно так:

all: main.o log.o
    $(LINK) $(LINKFLAGS) main.o log.o -o test.exe 
...

Дополнительно можете ознакомиться с вопросом: Ссылка на неразрешенный внешний символ (возможные причины).

READ ALSO
Какие отличия функций c++ от функций в c? [требует правки]

Какие отличия функций c++ от функций в c? [требует правки]

Какие отличия функций c++ от функций в c?

265
Программа на C++ . Метод последовательного перебора [требует правки]

Программа на C++ . Метод последовательного перебора [требует правки]

Помогите пожалуйста, прогорает экзаменсделать прогу на C++

578
cin и cin.get() ломают программу

cin и cin.get() ломают программу

Путем проб и ошибок я пришел тому что cin как то не закрывает поток или что еще и сразу заполняет "\n" следующее поле динамического массиваПодскажите...

417
Пропускать пустую переменную при вводе [требует правки]

Пропускать пустую переменную при вводе [требует правки]

Мы вводим переменные ,если мы нажмём Enter ,то пустая переменная пропустится и перейдёт ввод к другой переменнойКак сделать в с++ ?

332