使用文件夹结构时的 C++ 未定义符号

Posted

技术标签:

【中文标题】使用文件夹结构时的 C++ 未定义符号【英文标题】:C++ Undefined symbols when using folder structure 【发布时间】:2014-07-01 07:38:46 【问题描述】:

我目前正在尝试了解 OpenGL,并找到了 this 教程。我已经到了一个地步,我想用我学到的东西做点什么,所以我厌倦了用(有点)自制的 Makefile 来设置一个小项目文件夹。项目结构如下:

project_root:
 -- Makefile
 -- src/
       main.cpp
       imageloader.cpp
 -- obj/
       main.o (no compiletime error)
       imageloader.o (no compiletime error)
 -- include/
       imageloader.h
 -- textures/
       some texture files

Makefile:

CC = g++

SRC_DIR = ./src
OBJ_DIR = ./obj
INC_DIR = ./include

INCLUDE_PATHS = -I/usr/local/include -I/opt/X11/include -I$(INC_DIR)
LIBRARY_PATHS = -L/usr/local/lib -I/opt/X11/lib
LINKER_FLAGS = -framework OpenGL -lGLUT
COMPILER_FLAGS = -w

SRC_FILES = main.cpp imageloader.cpp
HEADER_FILES = imageloader.h

HEADERS = $(HEADER_FILES:%.h=$(INC_DIR)/%.h)
SRC = $(SRC_FILES:%.cpp=$(SRC_DIR)/%.cpp)

OBJS = $(SRC_FILES:%.cpp=$(OBJ_DIR)/%.o)

EXEC = main

$(OBJ_DIR)/%.o: $(SRC)
        $(CC) $(INCLUDE_PATHS) $(LIBRARY_PATHS) $(COMPILER_FLAGS) -c -o $@ $<

all: $(OBJS) $(HEADERS)
        $(CC) $(OBJS) $(INCLUDE_PATHS) $(LIBRARY_PATHS) $(COMPILER_FLAGS)         $(LINKER_FLAGS) -o $(EXEC)

run:
    ./main

print:
        @echo "C++ objcet files: "$(OBJS)
        @echo "C++ source files: "$(SRC)
        @echo "C++ header files: "$(HEADERS)

clean:
       rm -fv $(EXEC)
       rm -fv $(OBJS)

当我尝试编译时,我得到以下输出:

g++ -I/usr/local/include -I/opt/X11/include -I./include -L/usr/local/lib -I/opt/X11/lib -w -c -o obj/main.o src/main.cpp
g++ -I/usr/local/include -I/opt/X11/include -I./include -L/usr/local/lib -I/opt/X11/lib -w -c -o obj/imageloader.o src/main.cpp
g++ ./obj/main.o ./obj/imageloader.o -I/usr/local/include -I/opt/X11/include -I./include -L/usr/local/lib -I/opt/X11/lib -w -framework OpenGL -lGLUT -o main
Undefined symbols for architecture x86_64:
  "loadBMP(char const*)", referenced from:
      initRendering()     in main.o
      initRendering()     in imageloader.o
  "Image::~Image()", referenced from:
      initRendering()     in main.o
      initRendering()     in imageloader.o
ld: symbol(s) not found for architecture x86_64
collect2: ld returned 1 exit status
make: *** [all] Error 1

困扰我的是,代码只是从教程站点获取,没有修改,当我在同一个文件夹中编译它时(所有 .cpp 和 .h 文件在同一个地方),它编译得很好。我有一种感觉,我犯了一个明显的错误,但我似乎无法弄清楚导致错误的原因?

有人能指出这不能编译的原因吗?

提前致谢:)

【问题讨论】:

它正在寻找一些它找不到的库,我只能猜测它是 glut 库。我没有在 linux 中使用过 glut 但在 Windows 中我必须将.dll 复制到system32 目录并将.lib 寻址到我的源代码,我认为你应该对 .so 和 .a 文件在 linux 中做同样的事情. 哦,对不起,我应该提到的。似乎缺少来自 imageloader.cpp/h 的函数 平台?如果您询问构建问题,您确实需要在问题中包含您正在使用的平台。对我来说看起来像 Mac OS,但之前的评论表明它是 Linux。 这是 OS X,你是对的,对不起。然而,正如 xio4 所指出的,问题的发生是因为 imageloader.cpp 从未真正编译过。 【参考方案1】:

您正在编译 main.cpp 两次:

g++ -I/usr/local/include -I/opt/X11/include -I./include -L/usr/local/lib -I/opt/X11/lib -w -c -o obj/main.o src/main.cpp <--- main.cpp
g++ -I/usr/local/include -I/opt/X11/include -I./include -L/usr/local/lib -I/opt/X11/lib -w -c -o obj/imageloader.o src/main.cpp <--- main.cpp, instead imageloader.cpp

【讨论】:

我已经看了好几个小时了! XD 谢谢!

以上是关于使用文件夹结构时的 C++ 未定义符号的主要内容,如果未能解决你的问题,请参考以下文章

使用 bjam 编译的来自 C++ 的未定义符号

AttributeError:python:未定义符号:使用 ctypes 从 Python 访问 C++ 函数时

C++ 构造函数中体系结构 x86_64 的 GCC 未定义符号

C++ 库的 JNI 包装器和未定义的符号错误

ImportError:使用 SWIG 时 _...so 文件中的未定义符号

为 f2py 使用 C++ 源时未定义的符号