【问题标题】:Rcpp First Compilation troublercpp第一次编译麻烦
【发布时间】:2013-10-02 15:12:07
【问题描述】:

我最近从 amazon 下载了 2013 Rcpp 书,以了解如何更好地将 C++ 与我的 R 代码一起使用,我正在尝试使用第一个斐波那契递归函数和包装器的第一个编译示例,看看我是否能做到。我在 Ubuntu 上使用最新的 R。

首先是我的 C++:

    /* Cpp based recurive function */
int fibonacci(const int x){
  if(x == 0) return(0);
  if(x == 1) return(1);
  return(fibonacci(x - 1) + fibonacci(x - 2));
}


/* Wrapper */
extern "C" SEXP fibWrapper(SEXP xs) {
  int x = Rcpp::as<int>(xs);
  int fib = fibonacci(x);
  return(Rcpp::wrap(fib));
}

然后我启动 sh 并输入:

PKG_CXXFLAGS=`Rscript -e 'Rcpp:::CxxFlags()'`
PKG_LIBS=`Rscript -e 'Rcpp:::LdFlags()'`
R CMD SHLIB Fibonacci.cpp

但我明白了:

g++ -I/usr/share/R/include -DNDEBUG      -fpic  -O3 -pipe  -g  -c Fibonacci.cpp -o Fibonacci.o
Fibbonacci.cpp:10:12: error: 'SEXP' does not name a type
make: *** [Fibonacci.o] Error 1

我想也许我需要在我的 C++ 代码中包含指令,所以我再做一次,但这次在 C++ 文件的顶部使用 #include&lt;Rcpp.h&gt;,并在 sh 中再次执行相同的命令,但仍然没有乐趣:

g++ -I/usr/share/R/include -DNDEBUG      -fpic  -O3 -pipe  -g  -c Fibonacci.cpp -o Fibonacci.o
Fibonacci.cpp:1:18: fatal error: Rcpp.h: No such file or directory
compilation terminated.
make: *** [Fibbonacci.o] Error 1

我做错了什么? 如果我查询我在 sh 中设置的值:

$PKG_CXXFLAGS
sh: 9: -I/local/yrq12edu/R/x86_64-pc-linux-gnu-library/3.0/Rcpp/include: not found
$PKG_LIBS
sh: 10: -L/local/yrq12edu/R/x86_64-pc-linux-gnu-library/3.0/Rcpp/lib: not found

但我认为找不到消息只是因为 -L 标志,因为如果我 cd 到目录,文件就在那里。

谢谢, 本。

【问题讨论】:

  • 这个我不熟悉,大概是这样的:Rcpp:::SHLIB("fibbonacci.cpp")在包含cpp文件的目录中?
  • 刚刚用 Rcpp:::SHLIB 尝试过,正如你和这篇博文的建议:computerbastard.com/rcpp-c-compilation-trick 我得到以下信息:$ Rscript -e "Rcpp:::SHLIB('fibbonacci.cpp')" make: *** No rule to make target fibbonacci.o',fibbonacci.so'. Stop需要/跨度>
  • 对于它的价值,我完全不同意 Rcpp::SHLIB 的建议。也可以在这里删除。
  • 抱歉,我忘记了 Rcpp:::SHLIB 建议用于 Windows。评论被删除。

标签: c++ r compiler-construction fibonacci rcpp


【解决方案1】:

你似乎忽略了一个重要的细节。当你这样做时

PKG_CXXFLAGS=`Rscript -e 'Rcpp:::CxxFlags()'`
PKG_LIBS=`Rscript -e 'Rcpp:::LdFlags()'`
R CMD SHLIB Fibonacci.cpp

前两个的结果应该被赋值并导出到shell。您在这里所做的“分配和忘记”。

您在清单 2.1 中遗漏了这一点(或者可能是电子书放弃了它——我没有电子书)是 非常重要 尾随反斜杠,它使所有内容都成为一个单一的行:

PKG_CXXFLAGS=`Rscript -e 'Rcpp:::CxxFlags()'` \
PKG_LIBS=`Rscript -e 'Rcpp:::LdFlags()'`  \
R CMD SHLIB Fibonacci.cpp

现在赋值发生在与调用 R(shell 脚本本身)相同的执行过程中,它具有值并将它们传递给 g++ 的调用。

您可以从接下来的两行中看出我完全引用了具有所有必需的 -I 和 -L 部分的结果命令。因此(编译和链接步骤)都需要多行。

所以这本书是正确的,如果按照所示的方式完成所有这些工作。内联(在本章后面讨论)和属性(也在同一章后面讨论)基本上都会为您分配 PKG_CXXFLAGSPKG_LIBS

编辑:另外,您的测试是错误的。你的意思可能是这个

$ PKG_CXXFLAGS=`Rscript -e 'Rcpp:::CxxFlags()'`
$ echo $PKG_CXXFLAGS
-I/usr/local/lib/R/site-library/Rcpp/include
$ 

你不能只是“调用”一个 shell 变量,因此你得到了“未找到”的答案。

编辑 2:无论如何,您尝试的示例实际上只是为了激发第 2.4 节中的其余讨论,其中详细说明了多么费力、容易出错……这是——导致第 2.5 节和2.6 关于内联和属性。两者都好得多;使用那些。

【讨论】:

  • 感谢@DirkEddelbuettel 的解释,以及指向 Rcpp 属性的指针,Romain。我用反斜杠重新做了这个过程,它可以工作(你说得对,我忘了提到 echo 命令)。
  • 很高兴听到它有效。属性在第 1.2.5 和 2.6 节中介绍,应该可以帮助您入门。有关详细信息,请参阅 Rcpp 附带的小插图;本书的示例都可以正常工作,尽管主要使用内联。
【解决方案2】:

你是如何安装 R 的?看起来您缺少 R 标头。也许您需要安装r-base-dev package

关于代码,您不需要包装器。你可以把它放在一个.cpp 文件中:

#include <Rcpp.h>
using namespace Rcpp ;

// [[Rcpp::export]]
int fibonacci(const int x){
  if(x == 0) return(0);
  if(x == 1) return(1);
  return(fibonacci(x - 1) + fibonacci(x - 2));
}

只是sourceCpp这个文件:

> sourceCpp( "fib.cpp" )
> fibonacci(6)
[1] 8

【讨论】:

  • 好的,我会试一试,因为我在 Rcpp 电子书 5640 的 Loc 1318 上 - 清单 2.2。
  • 当然。不幸的是,属性([[Rcpp::export]] 装饰)出现在 Dirk 写这本书的过程中(并且接近尾声),所以它们在书中没有显示太多。然而,它们是我们现在鼓励人们使用的东西。例如,Rcpp 库中的所有示例都使用属性。
  • @RomainFrancois:您的第一行是错误的。编译器告诉他缺少 Rcpp.h,而不是 R.h。他有正确的 R 包;他没有正确传达-I 标志。
  • @DirkEddelbuettel 对。我被“Fibbonacci.cpp:10:12: error: 'SEXP' does not name a type”弄糊涂了
  • @RomainFrancois:这是 OP 的错误,因为他复制的代码具有所需的 #include,然后他添加了。
猜你喜欢
  • 2011-04-15
  • 2015-10-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-06-21
  • 2014-04-28
  • 1970-01-01
  • 2015-08-01
相关资源
最近更新 更多