linux makefile中对函数的未定义引用

Posted

技术标签:

【中文标题】linux makefile中对函数的未定义引用【英文标题】:Undefined reference to function in linux makefile 【发布时间】:2014-01-27 16:32:56 【问题描述】:

我在 linux 上进行 make 编译时遇到问题.... 收到有关未定义引用的错误。 简而言之,我们使用 FLUID,一个 GUI 设计器。 FLUID 的代码在 MyProjectGUI 类中。我在 FLUID 之外写了一个回调函数,它是从 MyProjectGUI 的函数中调用的。

MyProjectGUI.h 包含回调函数头: #include "students/stu_callbacks.h" MyProjectGUI.cxx

#include "MyProjectGUI.h"
....
void MyProjectGUI::somecallback_i([args])
   ...
   brandNewCallback();
    ...

在“学生/stu_callbacks.h”中:

#include "../main_utils.h"
void brandNewCallback();

然后在“students/stu_callbacks.cpp”中:

#include "stu_callbacks.h"
void brandNewCallback() 
  ...stuffs...

Makefile我用过:

VXLDIR = [....]

CFLAGS = [...VXL header paths...] -Wno-deprecated -DJPEG_LIB_VERSION=80

CC = g++

#fltk library paths and libraries
FLTKLDFLAGS = -L/local/lib -L/usr/lib/x86_64-linux-gnu/ -Wl,-rpath,/local/lib -lfltk_gl -lGLU -lGL -lfltk -L/usr/X11R6/lib -lpthread -lm -lXext -lX11 -lsupc++

#vxl library paths and libraries
VXLLDFLAGS = -L$(VXLDIR)/bin/lib -lvil -lvnl_algo -lvnl_io -lvnl -lv3p_netlib -lvcl -lvul -lpng -ltiff -lopenjpeg2 -lgeotiff
LDFLAGS = -lstdc++ $(FLTKLDFLAGS) $(VXLLDFLAGS)

FLUID = fluid

%.o: %.cxx
    $(CC) -c $(CFLAGS) $(CPPFLAGS) -o $@ $<

%.cxx: %.fl
    $(FLUID) -c $<

BASIC_OBJ   = gl/glutils.o gl/Texture.o main.o file/load_image.o

IMDRAW_OBJ  = [...imdraw...]

UI_OBJ      = MyProjectUI.o

UI_CPP      = MyProjectUI.cxx MyProjectUI.h

GRAPHIC_OBJ = graphics/graphics.o

STUDENT_OBJ = graphics/graphics_algorithm.o

imdraw-code/myproject:  $(UI_CPP) $(BASIC_OBJ) $(UI_OBJ) $(STUDENT_OBJ) $(GRAPHIC_OBJ) $(IMDRAW_OBJ)

    $(CC) -o ../bin/viscomp $(BASIC_OBJ) $(UI_OBJ) $(GRAPHIC_OBJ) $(IMDRAW_OBJ) $(STUDENT_OBJ) $(LDFLAGS)
在大学的 Linux 下使用此 Makefile 进行编译时会收到有关未定义引用来自 MyProjectGUI.cxx 的函数“brandNewCallback()”的错误。请注意,它并没有抱怨找不到“students/stu_callbacks.h”,所以应该阅读标题。 使用 Visual Studio 编译的完全相同的代码没有问题。 它的结构类似于 Makefile 中列出的“file/load_image”,(“load_image”函数是从 MyProjectGUI 中调用的,包含的设置非常相似)......但不会导致任何问题。 尝试在 Makefile 中将“students/stu_callbacks.o”添加到“STUDENT_OBJ”,然后我收到关于在 stud_callbacks.h 的“main_utils.h”包含中找不到包含的致命错误,这根本没有意义。其他文件来源“main_utils.h”没有问题。 尝试将函数调用为::brandNewCallback();,仍然是同样的错误。 直接的解决方法是将所有这些回调代码放入 MyProjectGUI...

我不明白我怎么不能让它像它一样工作,它让我很不爽。昨晚我已经花了 5 个多小时尝试/谷歌搜索......所以任何帮助将不胜感激!

【问题讨论】:

我没有看到您在 makefile 中的任何位置列出 students/stu_callbacks.cpp 或其目标文件。 顺便说一句,您可能不应该在源文件中列出头文件(我在考虑UI_CPP中的MyProjectUI.h文件)。 @Joachim Pileborg,我试过了,见第 4 点。完全不熟悉makefile。我们只被告知将附加代码放在“student/”下,并使用提供的 Makefile 进行编译。甚至没有提到需要修改 Makefile。但是后来我对其进行了修改,但仍然出现了要点中提到的错误。至于 UI_CPP……这对我来说也很奇怪,但它是提供的 Makefile……至少在我添加回调内容之前它会编译。 这是编译错误还是链接错误?标头仅与编译步骤相关。链接期间未定义的引用错误意味着您没有在链接行中包含构建库。 (这似乎是您试图用第 4 条解决的问题,但显然遇到了其他错误?) @Etan Reisner,我认为是编译错误?!.. 类似于“MyProjectUI.cxx (0x188): undefined reference to function brandNewCallback(...) ...” 【参考方案1】:

您的规则%.o: %.cxx 指示Make 如何编译扩展名为.cxx 的源文件。但是,您的 自己的 C++ 源文件是students/stu_callbacks.cpp。您没有提供从 .cpp 文件中制作目标文件或从 students/stu_callbacks.cpp 文件中制作目标文件的规则。因此,您的 stu_callbacks 未链接,自然链接器会抱怨。

头文件的问题类似——C++编译器可能没有设置包含路径。

【讨论】:

以上是关于linux makefile中对函数的未定义引用的主要内容,如果未能解决你的问题,请参考以下文章

c++中对静态变量的未定义引用

gfortran中对`sleep`和`sizeof` instrinsics的未定义引用

c 中对“getline”的未定义引用

Qt 中对 NetWkstaUserGetInfo 的未定义引用,但在 VS 中有效

Qt 项目中对 glew 方法的未定义引用

ARM GCC 中对 posix_memalign 的未定义引用