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中对函数的未定义引用的主要内容,如果未能解决你的问题,请参考以下文章
gfortran中对`sleep`和`sizeof` instrinsics的未定义引用