在 C/C++ 项目中找到 "undefined" 引用
Locating "undefined" references in a C/C++ Project
我正在使用提供的 Makefile
在我的 Ubuntu 64 位系统上构建一个 C++ 项目,该项目还为开发人员提供了一个 API 库。
编译成功,完全没有错误,但是当我尝试在我的文件中包含 "api" 文件夹中提供的 API 库时,g++
抱怨 未定义引用.
不是依赖关系的问题(我已经成功构建项目),实际上缺少的引用是关于类和项目提供的功能,但它们在一些特定的(子)文件夹(我不知道是哪个!),我猜在某些 .so 文件 中,并且 g++
找不到它们,可能是因为它不知道它们在那些特定的子文件夹。
这不是第一次尝试使用 任何项目 中的 API 时发生这种情况,然后我想我遗漏了什么或者我做错了什么通常在尝试使用项目中提供的库时。
特别是,主要问题是我不知道如何告诉编译器在哪里声明了一些类或数据结构,而且我不知道不知道如何定位他们才能知道他们在哪里。
通常,我用来避免这个问题的解决方法是 运行 make install
(作为 root 或使用 sudo
)以便安装库和 API在标准文件夹中(如 /usr/include
或 /usr/lib
),如果我这样做,那么我可以使用 #include <library>
包含 API 库,但在最后一种情况下它不起作用要么,因为可能包含未找到的某些必需文件 classes/structures 未正确安装在系统的正确文件夹中。
我有时使用的另一种解决方法是尝试将所有项目文件放在同一个文件夹中,而不是使用项目文件夹结构,但显然这并不好! :-)
但我注意到其他几个人 设法使用 APIs,然后显然他们知道一些找到包含 "undefined" 的文件的方法参考并将它们包含在汇编中。
那么我的一般问题是: 给定一个 "classic" C++ 项目,该项目基于 "Makefile" 文件和常用的文件夹名称,如 src
, lib
、build
、bin
等,如果我想用项目提供的库写C++文件,编译器却报未定义引用,怎么办我可以找到包含此类引用的文件(.so 或 .o 或 .cpp)吗? 有什么工具可以找到它们吗? 我如何告诉编译器它们在哪里? 我应该为 g++
使用一些命令行选项还是应该以某种巧妙的方式使用 #include
宏?
PS 我还尝试使用 pkc-config
linux 工具来获得用于编译的正确选项并且它们可用,但编译器仍然抱怨未定义的引用。
关于我尝试的项目的更多细节:
对于感兴趣的人,link 项目如下:
https://github.com/dreal/dreal3
以及关于如何构建它的说明:
http://dreal.github.io/download/
查看 -rpath 链接器选项 - 特别是“$ORIGIN”参数。这使您可以找到与可执行文件位置相关的库,因此您不必将它们安装到标准位置,而只需将它们放在已知的、相对于可执行文件的位置。这应该可以帮助您解决一个难题。
注意:-Wl,
可用于通过 g++ 将参数传递给链接器。
至于将 compiler/linker 指向库以便它可以通过使用该库来解析未定义的引用,请使用 -l
(小写 L)选项指定库名称和 -L
指定搜索库的目录。
至于查看库 (.so) 文件以查看其中有哪些符号,您可以使用一些工具:objdump
、nm
、readelf
和 objcopy
.
我正在使用提供的 Makefile
在我的 Ubuntu 64 位系统上构建一个 C++ 项目,该项目还为开发人员提供了一个 API 库。
编译成功,完全没有错误,但是当我尝试在我的文件中包含 "api" 文件夹中提供的 API 库时,g++
抱怨 未定义引用.
不是依赖关系的问题(我已经成功构建项目),实际上缺少的引用是关于类和项目提供的功能,但它们在一些特定的(子)文件夹(我不知道是哪个!),我猜在某些 .so 文件 中,并且 g++
找不到它们,可能是因为它不知道它们在那些特定的子文件夹。
这不是第一次尝试使用 任何项目 中的 API 时发生这种情况,然后我想我遗漏了什么或者我做错了什么通常在尝试使用项目中提供的库时。
特别是,主要问题是我不知道如何告诉编译器在哪里声明了一些类或数据结构,而且我不知道不知道如何定位他们才能知道他们在哪里。
通常,我用来避免这个问题的解决方法是 运行 make install
(作为 root 或使用 sudo
)以便安装库和 API在标准文件夹中(如 /usr/include
或 /usr/lib
),如果我这样做,那么我可以使用 #include <library>
包含 API 库,但在最后一种情况下它不起作用要么,因为可能包含未找到的某些必需文件 classes/structures 未正确安装在系统的正确文件夹中。
我有时使用的另一种解决方法是尝试将所有项目文件放在同一个文件夹中,而不是使用项目文件夹结构,但显然这并不好! :-)
但我注意到其他几个人 设法使用 APIs,然后显然他们知道一些找到包含 "undefined" 的文件的方法参考并将它们包含在汇编中。
那么我的一般问题是: 给定一个 "classic" C++ 项目,该项目基于 "Makefile" 文件和常用的文件夹名称,如 src
, lib
、build
、bin
等,如果我想用项目提供的库写C++文件,编译器却报未定义引用,怎么办我可以找到包含此类引用的文件(.so 或 .o 或 .cpp)吗? 有什么工具可以找到它们吗? 我如何告诉编译器它们在哪里? 我应该为 g++
使用一些命令行选项还是应该以某种巧妙的方式使用 #include
宏?
PS 我还尝试使用 pkc-config
linux 工具来获得用于编译的正确选项并且它们可用,但编译器仍然抱怨未定义的引用。
关于我尝试的项目的更多细节:
对于感兴趣的人,link 项目如下: https://github.com/dreal/dreal3
以及关于如何构建它的说明: http://dreal.github.io/download/
查看 -rpath 链接器选项 - 特别是“$ORIGIN”参数。这使您可以找到与可执行文件位置相关的库,因此您不必将它们安装到标准位置,而只需将它们放在已知的、相对于可执行文件的位置。这应该可以帮助您解决一个难题。
注意:-Wl,
可用于通过 g++ 将参数传递给链接器。
至于将 compiler/linker 指向库以便它可以通过使用该库来解析未定义的引用,请使用 -l
(小写 L)选项指定库名称和 -L
指定搜索库的目录。
至于查看库 (.so) 文件以查看其中有哪些符号,您可以使用一些工具:objdump
、nm
、readelf
和 objcopy
.