尝试使用外部库

时间:2016-07-22 21:09:42

标签: c++ c r makefile rcpp

我正在尝试将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中删除那部分,并在构建包之前从命令行“make”库时,我使用-I和-l语句得到了正确的g++调用,但是我得到了关于undefined的错误引用。

我注意到-l语句只包含在最终的g++调用中,其中包含最终的.dll,但未包含在早期的g++调用中,其中包含库的文件标题已编译。

所以我有两个问题:

  • 如何修复我的makevars以使其“成为”库,但是不会阻止Rcpp编译src中的文件?

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

1 个答案:

答案 0 :(得分:2)

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

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

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