首页 文章

主Makefile中的未定义引用

提问于
浏览
2

我在linux中做了一个示例项目但是在运行main Makefile时遇到错误

Project Info:

project/database folder 有文件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 有文件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: 数据库make文件工作正常,但主要Makefile我有一些问题,如

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

2 回答

  • 6

    这条线错了:

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

    因为该库应该在对象 main.o 之后进行特定 . 这是由于链接器处理对象的方式 . 看看这个例子:

    gcc -o test someobject.o library.a
    

    链接器将:

    • 查找 someobject.o 的所有未定义引用并存储它们

    • 然后它打开 library.a 并通过 library.a 解析未定义的引用

    • 然后关闭 library.a

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

    EDIT :这是一个众所周知的GCC警告,可以看到更详细的堆栈溢出说明here,选项 --start-group--end-group 可以帮助解决A依赖于B的情况,而B依赖于A.

  • 1

    这是你的 Makefile . 你要:

    libdatabase.a
    

    要么

    -ldatabase
    

    main 编译行的末尾

相关问题