主Makefile中的未定义引用

问题描述:

我在linux上做了一个示例项目,但是在运行主Makefile时出现错误

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

项目信息:

项目/数据库文件夹,具有文件database.h,database.cpp,bulid-database,Makefile

project/database folder having files database.h , database.cpp , bulid-database ,Makefile

数据库.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)
{
}

建筑物数据库

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

制作文件

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

项目/主文件夹,其中包含文件main.cpp,Makefile

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;
}

制作文件

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

问题::数据库make文件可以正常工作,但是主makefile出现了类似问题

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

错误: main.o:在函数main': main.cpp:(.text+0x92): undefined reference to mydatabase :: mydatabase(int,int)'中 collect2:ld返回1个退出状态

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

此行是错误的:

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

因为应该在行中的对象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

链接器将:

  1. 查找所有someobject.o的未定义引用并将其存储
  2. 然后打开library.a并通过library.a
  3. 解析未定义的引用
  4. 然后关闭library.a
  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

如果对象和库位于相反的位置,则链接器将打开library.a,在其表中看不到未定义的引用并将其关闭.然后尝试编译someobject.o,并且永远不会满足未定义的引用

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

编辑: 这是GCC的众所周知的警告,可以在此处以及选项--start-group--end-group可以帮助解决A依赖于B而B依赖于A的情况.

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.