我试图将一个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语句只包含在final.dll所在的finalg++调用中,而不包含在前面编译库头文件的g++调用中。
所以我有两个问题:
如何修复makevars,使其“生成”库,但不阻止Rcpp编译src中的文件?
如何处理未定义的引用?这个库显然不仅仅是头文件,所以我猜它需要在前面的g++调用中使用-l语句,但这甚至是不可能的。

最佳答案

最好的方法是完全避免复杂的src/Makevars文件。
一个简单的ish方法是:使用configure来构建静态库,然后一旦您真正构建了静态库,就在src/Makevars中引用它。
我在Rblpapi(我们在其中复制外部提供的库)和nloptr(我们在其中下载nlopt源并在“需要时”(即系统上没有libnlopt时)中使用该方案。

关于c++ - 尝试使用外部库时未定义引用,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/38535274/

10-09 13:34