C++ 制作链接步骤:建筑x86_64的未定义符号

C++ make link step : Undefined symbols for architecture x86_64

本文关键字:x86 符号 未定义 建筑 链接 C++      更新时间:2023-10-16

我正在尝试链接一个用 C/C++ 构建的编译研究实验项目。该项目依赖于HyperNEAT和机器人模拟软件WeBots。我已经成功地克隆并构建了HyperNEAT项目(在该项目中还有其他依赖项,例如Boost,TinyXML,JGTL(自定义库)和其他不相关的子项目)。

我制作了一个包含所有必要的标头搜索路径和库路径的 makefile,并编译了两个主要的.cpp文件:

/ModHyperNEAT/mod_ctrler7.cpp 
/ModSupervisor/mod_supervisor.cpp

工作,给我 2 个 .o 文件。

但是,在make链接步骤中,当我想创建两个文件的(单独的)可执行文件时,我收到"架构x86_64的未定义符号"错误(请参阅此处的pastebin:http://pastebin.com/kiwwCcUf)。似乎C++标准的数据类型和函数,例如 找不到std::string::end() const

我已经用谷歌搜索并搜索了SO以获取有关此问题的答案,如果我理解正确,似乎缺少库或二进制不兼容,但是库就在那里,并且两个项目都已使用-lstdc++标志进行编译。

这是make链接步骤(以及makefile中使用的宏):

CC = gcc
CFLAGS = -v -g -lstdc++ -Wall -Wno-error -ferror-limit=100 -fmessage-length=0
DEFINES = -DHCUBE_NOGUI -DTIXML_USE_STL
FLAGS = $(CFLAGS) $(DEFINES)
LIB_TINYXML = -L/Users/michahell/Documents/projects_c++/HyperNEAT/tinyxmldll/out
LIB_HYPERNEAT = -L/Users/michahell/Documents/projects_c++/HyperNEAT/NE/HyperNEAT/out
LIB_BOOST = -L/usr/local/Cellar/boost/1.57.0/lib
LIB_WEBOTS = -I/Applications/Webots/lib
LIBS = $(LIB_TINYXML) $(LIB_HYPERNEAT) $(LIB_BOOST) $(LIB_WEBOTS)
LIBFLAGS = -ltinyxmlpluslib -lboost_filesystem-mt -lboost_random-mt -lboost_system-mt -lNEATLib_d -lHypercube_NEAT_Base_d
WEBOTS_DYLIB = -dylib_file /Applications/Webots/lib/libController.dylib:/Applications/Webots/lib/libController.dylib
$(CC) $(FLAGS) $(LIBS) ./mod_ctrler7.o $(WEBOTS_DYLIB) $(LIBFLAGS)

我发现要链接到 .dylib,我必须使用特定的标志并指定完整路径,因此使用 $(WEBOTS_DYLIB) 宏。我正在使用-lstdc++标志,因为在HyperNEAT项目中,该标志也用于构建该库。如果我排除这个标志,我在编译过程中会得到很多错误(我现在理解的libc++和libstdc++不兼容)。所有库路径都签出,并且存在 .a 和/或 .dylib 文件。

我对 C/C++ 和 GCC 工具的了解非常有限,因为我以前从未使用过它。我认为这可能与以下事实有关:HyperNEAT 项目包含一个用于构建的 Boost 1.57.0 发行版,并且我的系统上安装了一个单独的(使用自制)Boost 版本,它是相同的版本:

$ brew info boost
boost: stable 1.57.0 (bottled), HEAD
http://www.boost.org
/usr/local/Cellar/boost/1.57.0 (10572 files, 439M) *

此错误无法通过链接步骤的原因可能是什么?如果 HyperNEAT 和我的项目都被克隆并将它们的根目录放在同一个位置,那么任何人都应该能够重现我的链接器错误。WeBots应该下载,但仅限于标题包含和库。当然,我的生成文件路径应该被修改。

如果有人能给我如何解决这个问题的提示,我将不胜感激!

事实证明,出于某种原因,我必须将 lstdc++ 标志包含在库链接标志中,而不是作为编译器标志,并将stdlib=libstdc++作为编译器标志。