尝试使用外部库时未定义的引用

Posted

技术标签:

【中文标题】尝试使用外部库时未定义的引用【英文标题】:Undefined reference when trying to use external library 【发布时间】:2016-07-22 21:09:42 【问题描述】:

我正在尝试将 C 库合并到一些 Rcpp 代码中。

我可以轻松地在 C++ 程序中使用 C 库。我“制作”了 C 库,它在 /lib 文件夹中创建了 .a 和 .dll 文件。然后我可以通过在程序中包含标题并从命令行运行类似的东西来使用该包:

cc myfile.cpp -o myfile -Ipath.to.header path.to.lib.a -lz

这实际上告诉编译器获取 .cpp 程序,包含来自 -I 的头文件,并链接到两个库。

如果我正确理解了makevars(不幸的是我似乎没有理解),那么让它与Rcpp一起工作应该不会太困难。

我将库添加到我的包中的一个文件夹中,并在 src 中添加一个 makevars 和 makevars.win,如下所示:

PKG_CFLAGS=
# specify header location
PKG_CPPFLAGS=-Ipath.to.lib/include
# specify libs to link to
PKG_LIBS=path.to.lib/lib/file.a -lz
# make library
path.to.lib/lib/file.a:
            cd path.to.lib;$(MAKE)

这正确地“制作”了库的 .a 和 .dll 文件,但是没有任何 Rcpp 魔法运行(即在构建中我从未看到编译 src 中的文件的g++ 系统调用),所以“没有创建 Dll”。

我相当肯定这是我的 makevars 目标中的一个问题,它使库。当我从 makevars 中删除该部分,并在构建包之前自己从命令行“制作”库时,我会使用我的 -I 和 -l 语句获得正确的 g++ 调用,但我收到有关未定义引用的错误。

我注意到 -l 语句仅包含在生成最终 .dll 的最终 g++ 调用中,但不包含在编译带有库头文件的早期 g++ 调用中。

所以我有两个问题:

如何修复我的 makevar 以便它“创建”库,但不会阻止 Rcpp 编译 src 中的文件?

如何处理未定义的引用?该库显然不是仅标头,所以我猜它需要在早期的 g++ 调用中使用 -l 语句,但这甚至是不可能的。

【问题讨论】:

【参考方案1】:

最好的方法是完全避免复杂的src/Makevars 文件。

解决此问题的一种简单方法:使用 configure 构建您的静态库,然后在实际构建后在 src/Makevars 中引用它。

我在 Rblpapi(我们在其中复制外部提供的库)和 nloptr 中使用该方案,我们在其中下载 nlopt 源并在“需要时”(即系统上没有 libnlopt 时)构建它。

【讨论】:

以上是关于尝试使用外部库时未定义的引用的主要内容,如果未能解决你的问题,请参考以下文章

尝试使用 dlopen 加载库时未定义的符号

为 C 库生成 Python SWIG 绑定时未定义的符号

使用 ifort/icc 时未定义对“main”的引用

链接时未定义的引用 - 缺少库?

在 Vue.js 2 组件中加载时未定义 Webpack 外部 JS 文件

在 c++ 对象上使用 extern 时未定义的引用,但不是整数类型