2

I did a sample project in linux but i am getting error while running main Makefile

Project Info:

project/database folder having files database.h , database.cpp , bulid-database ,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-database

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 $@ $<
    ar ruv libdatabase.a $@
    ranlib libdatabase.a

project/Main folder having files 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

ISSUE: database make file is working fine but main Makefile i am having some issue like

Error: main.o: In function main': main.cpp:(.text+0x92): undefined reference tomydatabase::mydatabase(int, int)' collect2: ld returned 1 exit status

Jeggu
  • 569
  • 2
  • 10
  • 26

2 Answers2

6

This line is wrong:

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

because the library should be specificed AFTER the object main.o on the line. This is due to the way the linker handles the objects. Look at this example:

gcc -o test someobject.o library.a

The linker will:

  1. look up all undefined references of someobject.o and store them
  2. then it opens library.a and resolves the undefined references via library.a
  3. then it closes library.a

If the object and the library are in the other way around, then the linker opens library.a, sees no undefined references in its table and closes it. Then it tries and compiles someobject.o and the undefined references are never satisfied

EDIT: This is a well-known caveat of GCC, a more detailed stack-overflow explanation can be seen here, and options --start-group and --end-group can help resolve cases where A depends on B, and B depends on A.

Community
  • 1
  • 1
qdii
  • 12,505
  • 10
  • 59
  • 116
1

It's your Makefile. You want:

libdatabase.a

or

-ldatabase

at the end of your main compile line

Paul Evans
  • 27,315
  • 3
  • 37
  • 54