尝试使用外部库时未定义的引用
Undefined reference when trying to use external library
我正在尝试将 C 库合并到一些 Rcpp 代码中。
我可以轻松地在 C++ 程序中使用 C 库。我 'make' C 库,它在 /lib 文件夹中创建 .a 和 .dll 文件。然后我可以通过在程序中包含 header 和命令行中的 运行 来使用这个包:
cc myfile.cpp -o myfile -Ipath.to.header path.to.lib.a -lz
这实际上告诉编译器采用 .cpp 程序,包括来自 -I 的 headers,以及 link 到两个库。
如果我正确理解 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)
这正确 'makes' 库的 .a 和 .dll 文件,但是 none 的 Rcpp 魔术运行(即在构建中我从未看到 g++
系统调用编译 src 中的文件),所以 "no Dll was created".
我相当确定这是我创建库的 makevars 目标中的一个问题。当我在构建包之前从 makevars 和 'make' 自己从命令行删除该部分时,我使用我的 -I 和 -l 语句获得了正确的 g++
调用,但是我得到了错误关于未定义的引用。
我注意到 -l 语句仅包含在生成最终 .dll 的最终 g++
调用中,但未包含在较早的 g++
调用中库 header 已编译。
所以我有两个问题:
如何修复我的 makevars 使其 'makes' 库,但不阻止 Rcpp 编译 src 中的文件?
如何处理未定义的引用?该库显然不是 header-only,所以我猜它需要在较早的 g++
调用中使用 -l 语句,但这甚至可能是不可能的。
最好的方法是完全避免复杂的 src/Makevars
文件。
解决此问题的一种简单方法:使用 configure
构建您的静态库,然后一旦您实际构建,只需在 src/Makevars
.
中引用它
我在 Rblpapi(我们在其中复制外部提供的库)和 nloptr(我们下载 nlopt 源并构建它)中使用该方案 'when needed'(即当系统上没有 libnlopt 时)。
我正在尝试将 C 库合并到一些 Rcpp 代码中。
我可以轻松地在 C++ 程序中使用 C 库。我 'make' C 库,它在 /lib 文件夹中创建 .a 和 .dll 文件。然后我可以通过在程序中包含 header 和命令行中的 运行 来使用这个包:
cc myfile.cpp -o myfile -Ipath.to.header path.to.lib.a -lz
这实际上告诉编译器采用 .cpp 程序,包括来自 -I 的 headers,以及 link 到两个库。
如果我正确理解 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)
这正确 'makes' 库的 .a 和 .dll 文件,但是 none 的 Rcpp 魔术运行(即在构建中我从未看到 g++
系统调用编译 src 中的文件),所以 "no Dll was created".
我相当确定这是我创建库的 makevars 目标中的一个问题。当我在构建包之前从 makevars 和 'make' 自己从命令行删除该部分时,我使用我的 -I 和 -l 语句获得了正确的 g++
调用,但是我得到了错误关于未定义的引用。
我注意到 -l 语句仅包含在生成最终 .dll 的最终 g++
调用中,但未包含在较早的 g++
调用中库 header 已编译。
所以我有两个问题:
如何修复我的 makevars 使其 'makes' 库,但不阻止 Rcpp 编译 src 中的文件?
如何处理未定义的引用?该库显然不是 header-only,所以我猜它需要在较早的
g++
调用中使用 -l 语句,但这甚至可能是不可能的。
最好的方法是完全避免复杂的 src/Makevars
文件。
解决此问题的一种简单方法:使用 configure
构建您的静态库,然后一旦您实际构建,只需在 src/Makevars
.
我在 Rblpapi(我们在其中复制外部提供的库)和 nloptr(我们下载 nlopt 源并构建它)中使用该方案 'when needed'(即当系统上没有 libnlopt 时)。