2014-01-25 3 views
2

Я сделал образец проект в Linux, но я получаю сообщение об ошибке при запуске главного MakefileНеопределенная ссылка в главном Makefile

Информации о проекте:

папка проекта/баз данных, имеющих файлы database.h, баз данных .cpp, Bulid-базы данных, Makefile

database.h

/*data base file*/ 
#include<iostream> 
using namespace std; 
class mydatabase 
{ 
public: 
    mydatabase(int a , int b); 
    int sum(){return m_a +m_b;} 
    int diff(){return m_a -m_b;} 
    int mul(){return m_a *m_b;} 
    float div(){return m_a /m_b;} 
    int reminder(){return m_a %m_b;} 

private: 
    int m_a , m_b; 
}; 

database.cpp

#include "database.h" 
mydatabase::mydatabase(int a ,int b):m_a(a) , m_b(b) 
{ 
} 

Bulid-база

make 
if [ -f libdatabase.a ]; 
then 
    echo "Database-Library Build Success" 
    cp libdatabase.a ../LIBs/ 
else 
    echo "databse-Library Build Failure" 
fi 

Makefile

HEADERFILES = $(wildcard *.h) 
CPPFILES = $(wildcard *.cpp) 
OBJFILES = $(patsubst %.cpp,%.o ,$(wildcard *.cpp)) 
$(OBJFILES): %.o : %.cpp $(HEADERFILES) 
    g++ -c -o [email protected] $< 
    ar ruv libdatabase.a [email protected] 
    ranlib libdatabase.a 

проект/Главная папка имеющие файлы main.cpp, Makefile

main.cpp

#include "database.h" 
#include <iostream> 
int main() 
{ 
    mydatabase *obj = new mydatabase(10 ,5); 
    std::cout<<"sum is"<<obj->sum()<<endl; 
    std::cout<<"diff is"<<obj->diff()<<endl; 
    std::cout<<"mul is"<<obj->mul()<<endl; 
    std::cout<<"div is"<<obj->div()<<endl; 
    std::cout<<"reminder is"<<obj->reminder()<<endl; 
    getchar(); 
    return 0; 
} 

Makefile

CC  = g++ 
INCPATH = -I. \ 
     -I.. \ 
     -I../database 
LIBPATH = -L../LIBs 
LDFLAGS = ${LIBPATH}/libdatabase.a 
CFLAGS = ${INCPATH} 
testdate:main.o 
    $(CC) $(CFLAGS) -o testdate main.o $(LDFLAGS) 
main.o:main.cpp 
    $(CC) $(CFLAGS) -c -o main.o main.cpp 

ВОПРОС: базы данных сделать файл работает нормально, но главный Makefile я с некоторые вопросы, такие как

Ошибка: main.o: В функции main': main.cpp:(.text+0x92): undefined reference to MyDatabase :: MyDatabase (интермедиат, целое)» collect2: л.д. возвращается статус 1 выхода

+0

Если вы собираетесь использовать 'new', вы должны« удалить »этот объект, когда вы закончите с ним. –

ответ

6

Эта линия является неправильным:

$(CC) $(CFLAGS) -o testdate $(LDFLAGS) main.o 

, потому что библиотека должна быть specificed ПОСЛЕ объект main.o на линии. Это связано с тем, как линкер обрабатывает объекты.Посмотрите на этот пример:

gcc -o test someobject.o library.a 

Компоновщик:

  1. посмотреть все неопределенные ссылки из someobject.o и хранить их
  2. тогда он открывает library.a и решает неопределенные ссылки через library.a
  3. затем закрывается library.a

Если объект и библиотека находятся в обратном порядке, то компоновщик открывается library.a, не видит неопределенных ссылок в своей таблице и не закрывает его. Затем он пытается и компилирует someobject.o и неопределенные ссылки никогда не удовлетворены

EDIT: Это хорошо известно предостережение GCC, более подробный стек переполнения объяснение можно увидеть here и варианты --start-group и --end-group может помогите решить случаи, когда A зависит от B, а B зависит от A.

1

Это ваш Makefile. Вы хотите:

libdatabase.a 

или

-ldatabase 

в конце вашей main компиляции линии

+1

Спасибо, его работа – Jeggu

+0

@srinivas, если да, примите, как лучший ответ, приветствия :) –

Смежные вопросы