在C / C ++项目中定位“未定义”引用

时间:2017-05-30 14:24:03

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

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

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

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

当尝试使用来自任何项目的API时,这不是第一次发生这种情况,然后我认为我在尝试使用提供的库中时遗漏了某些内容或者我做错了什么一个项目。

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

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

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

但是我注意到其他几个人设法使用API​​ ,然后显然他们知道某种方法来查找包含“未定义”引用的文件并将它们包含在编译中。

然后我的一般问题是:给出一个基于“Makefile”文件的“经典”C ++项目,并使用常见的文件夹名称,如srclib,{{1如果我想使用项目提供的库编写C ++文件,但编译器抱怨未定义的引用,我如何找到文件(.so或.o)。},build等等。或.cpp)包含此类引用?是否有任何工具可以找到它们? 如何告诉编译器它们在哪里?我应该为bin使用某个命令行选项还是应该以某种智能方式使用g++宏?

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

关于我尝试过的项目还有一些问题:

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

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

1 个答案:

答案 0 :(得分:2)

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

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

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

至于查看库(.so)文件以查看其中包含的符号,您可以使用一些工具:objdumpnmreadelf和{ {1}}。