【问题标题】:Locating "undefined" references in a C/C++ Project在 C/C++ 项目中定位“未定义”引用
【发布时间】:2017-10-31 02:05:56
【问题描述】:

我正在使用提供的Makefile 在我的 Ubuntu 64 位系统上构建一个 C++ 项目,该项目还为开发人员提供了一个 API 库。

编译成功,完全没有错误,但是当我尝试在我的文件中包含“api”文件夹中提供的 API 库时,g++ 抱怨 未定义的引用

这不是依赖的问题(我已经成功构建了项目),实际上缺少的引用是关于项目提供的类和函数的,但它们在一些特定的(子)文件夹中(我没有知道哪些!),我猜在一些 .so 文件中g++ 没有找到它们,可能是因为它不知道它们在那些特定的子文件夹中。

这不是第一次在尝试使用 任何项目 中的 API 时发生这种情况,然后我认为我在尝试使用一个项目。

主要问题是我不知道如何告诉编译器某些类或数据结构在哪里声明,而且我不知道如何定位 以便知道他们在哪里。

通常,我用来避免此问题的解决方法是运行 make install(以 root 身份或使用 sudo),以便将库和 API 安装在标准文件夹中(如 /usr/include/usr/lib),如果我这样做,然后我可以使用#include <library> 包含 API 库,但在最后一种情况下它也不起作用,因为可能包含未找到的类/结构的某些必需文件未正确安装在系统的正确文件夹中.

我有时使用的另一种解决方法是尝试将所有项目文件放在同一个文件夹中,而不是使用项目文件夹结构,但显然这不好! :-)

但我注意到其他几个人设法使用了 API,显然他们知道一些方法可以找到包含“未定义”引用的文件并将它们包含在编译中。

那么我的一般问题是: 给定一个“经典”C++ 项目,该项目基于“Makefile”文件和常用文件夹名称,如 srclibbuildbin等,如果我想使用项目提供的库编写 C++ 文件,但编译器抱怨未定义的引用,如何找到包含此类引用的文件(.so 或 .o 或 .cpp)? 有什么工具可以找到它们吗? 我如何告诉编译器它们在哪里?我应该为g++ 使用一些命令行选项还是应该以某种智能方式使用#include 宏?

PS 我还尝试使用pkc-config linux 工具来获得用于编译的正确选项,并且它们可用,但编译器仍然抱怨未定义的引用。

关于我尝试过的项目的更多细节:

对于感兴趣的人,该项目的链接如下: https://github.com/dreal/dreal3

以及如何构建它的说明: http://dreal.github.io/download/

【问题讨论】:

  • 我通常只是 CTRL+SHIFT+F 并复制+粘贴编译器抱怨的符号名称,它会找到我的符号。任何 IDE 都应该有一些功能来搜索符号,但在紧要关头 find/grep 就可以了。
  • 根据我的经验,这完全取决于项目。您需要在一定程度上调整项目构建过程,然后搜索丢失的部分在哪里,并通过反语来确定应该如何访问它。 find/grep 是肮脏和蛮力的,有时是最好的起点。除了 find/grep,还可以查看 ack。 beyondgrep.com
  • ctags 将生成一个 TAGS 文件,其中给出每个符号的定义位置。

标签: c++ linux makefile g++ shared-libraries


【解决方案1】:

查看 -rpath 链接器选项 - 特别是使用“$ORIGIN”参数。这使您可以找到与可执行文件位置相关的库,因此您不必将它们安装到标准位置,而只需将它们放在相对于可执行文件的已知位置。这应该可以帮助您解决一个难题。

注意:-Wl, 可用于通过 g++ 将参数传递给链接器。

至于将编译器/链接器指向一个库以便它可以通过使用该库来解析未定义的引用,请使用-l(即小写 L)选项来指定库名称,并使用 -L 来指定要搜索的目录图书馆。

至于查看库 (.so) 文件以查看其中包含哪些符号,您可以使用一些工具:objdumpnmreadelfobjcopy

【讨论】:

  • 嗨杰斯珀,非常感谢!你的意思是我应该手动使用 ld 工具而不是自动(通过 g++)?我应该什么时候使用它?构建项目或编译使用项目库的文件时?你能想象一个在假设项目中运行的命令示例吗? ——
  • 通过 g++ 使用这些选项很好。查看 g++ 文档以获取详细信息 - 您有一些关于现在要查找的内容的指针。
  • 非常感谢 Jesper,我将在接下来的几个小时内尝试
猜你喜欢
  • 2016-12-19
  • 2015-12-05
  • 1970-01-01
  • 2013-01-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-12
相关资源
最近更新 更多