在C++x11中使用RInside和Rcpp

3
我想在C ++x11代码中使用RInside来调用R例程。默认情况下,R似乎安装了库的c++98版本,因此链接不成功。我想知道我应该采取哪些不同的步骤来安装C++x11版本的RInside(但我猜我需要重新编译所有的R / R包,是吗?),是否存在更简单的解决方案。提前感谢(我在MacOs上工作)。
更新: 我重新安装了Rcpp和RInside,执行以下操作(我的Makevars为空,因此是c ++ 98版本)。
 sudo R CMD INSTALL ~/Downloads/Rcpp_0.10.4.tar.gz 
 sudo R CMD INSTALL ~/Downloads/RInside_0.2.10.tar.gz

然后我使用(不带cx11)编译hello world示例:

clang++ -I/Library/Frameworks/R.framework/Versions/2.15/Headers/ -I/Library/Frameworks/R.framework/Versions/2.15/Resources/library/RInside/include/ -I/Library/Frameworks/R.framework/Versions/2.15/Resources/library/Rcpp/include/  -c ../src/Gui/test.cc -o testOut.cc.o

clang++ testOut.cc.o -o testOut -L/Library/Frameworks/R.framework/Versions/2.15/Resources/library/RInside/lib/x86_64 -L/Library/Frameworks/R.framework/Versions/2.15/Resources/library/Rcpp/lib/x86_64 -framework R -lRInside -lRcpp

这让我感到:
  Hello, world!

然而,通过添加x11选项:
clang++ -I/Library/Frameworks/R.framework/Versions/2.15/Headers/ -I/Library/Frameworks/R.framework/Versions/2.15/Resources/library/RInside/include/ -I/Library/Frameworks/R.framework/Versions/2.15/Resources/library/Rcpp/include/  -c ../src/Gui/test.cc -o testOut.cc.o -stdlib=libc++ -std=c++11

clang++ testOut.cc.o -o testOut -L/Library/Frameworks/R.framework/Versions/2.15/Resources/library/RInside/lib/x86_64 -L/Library/Frameworks/R.framework/Versions/2.15/Resources/library/Rcpp/lib/x86_64 -framework R -lRInside -lRcpp -stdlib=libc++ -std=c++11

我在连接时遇到以下问题:

  Undefined symbols for architecture x86_64:
   "RInside::parseEvalQ(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&)", referenced from:
  _main in testOut.cc.o
   "RInside::operator[](std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&)", referenced from:
  _main in testOut.cc.o
   "Rcpp::Environment::assign(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, SEXPREC*) const", referenced from:
        bool Rcpp::Environment::assign<char [15]>(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, char const (&) [15]) const in testOut.cc.o

重新编译Rcpp和RInside时使用c++x11选项
clang++ -I/Library/Frameworks/R.framework/Versions/2.15/Headers/ -I/Library/Frameworks/R.framework/Versions/2.15/Resources/library/RInside/include/ -I/Library/Frameworks/R.framework/Versions/2.15/Resources/library/Rcpp/include/  -c ../src/Gui/test.cc -o testOut.cc.o -stdlib=libc++ -std=c++11

clang++ testOut.cc.o -o testOut -L/Library/Frameworks/R.framework/Versions/2.15/Resources/library/RInside/lib/x86_64 -L/Library/Frameworks/R.framework/Versions/2.15/Resources/library/Rcpp/lib/x86_64 -framework R -lRInside -lRcpp -stdlib=libc++ -std=c++11

喜欢是可以的,但是./test会导致段错误。

补充一下:我的clang版本是:Apple clang version 4.1 (tags/Apple/clang-421.11.66)


如果你的程序在最简单的示例上出现问题,我会说你并没有“成功”构建库。此外,没有必要重新打印已经存在于RInside存储库和分发中多年的源代码。 - Dirk Eddelbuettel
2个回答

2

R是使用C编译器编译的。构建软件包时不一定需要使用相同的编译器。因此,使用clang编译附加程序包是完全有效的。我在~/.R/Makevars文件中有这个配置,以使用clang和C++11编译软件包:

CC=clang
CXX=clang++
CXXFLAGS= -stdlib=libc++ -std=c++11

另外,您可能希望查看Rcpp11,这是一个以C++11为中心重新设计的Rcpp。也许很容易将RInside分支为使用Rcpp11而不是Rcpp。


0

我不知道不同的链接器要求。你所拥有的应该可以正常工作。否则,请展示你实际的链接步骤和错误,最好以可重复的方式呈现,这样我也可以查看。

请看以下内容。我们首先使用默认标志进行构建:

edd@max:~/svn/rinside/pkg/inst/examples/standard$ grep ^CXXFLAGS ~/.R/Makevars
CXXFLAGS=             -g -O3 -Wall -pipe -Wno-unused -pedantic    # plain C++ 
edd@max:~/svn/rinside/pkg/inst/examples/standard$ make rinside_sample0
ccache g++-4.7 -I/usr/share/R/include \
  -I/usr/local/lib/R/site-library/Rcpp/include \
  -I/usr/local/lib/R/site-library/RInside/include -g -O3 -Wall \
  -pipe -Wno-unused -pedantic -Wall   \
  rinside_sample0.cpp  -L/usr/lib/R/lib -lR  -lblas \
  -llapack -L/usr/local/lib/R/site-library/Rcpp/lib -lRcpp \
  -Wl,-rpath,/usr/local/lib/R/site-library/Rcpp/lib \
  -L/usr/local/lib/R/site-library/RInside/lib \
  -lRInside -Wl,-rpath,/usr/local/lib/R/site-library/RInside/lib \
  -o rinside_sample0
edd@max:~/svn/rinside/pkg/inst/examples/standard$ ./rinside_sample0 
Hello, world!       
edd@max:~/svn/rinside/pkg/inst/examples/standard$ 

现在,我只需将-std=c++11添加到我的CXXFLAGS中:

edd@max:~/svn/rinside/pkg/inst/examples/standard$ grep ^CXXFLAGS ~/.R/Makevars 
CXXFLAGS=             -g -O3 -Wall -pipe -Wno-unused -pedantic -std=c++11
edd@max:~/svn/rinside/pkg/inst/examples/standard$  

重新制作二进制文件:

edd@max:~/svn/rinside/pkg/inst/examples/standard$ rm rinside_sample0  
edd@max:~/svn/rinside/pkg/inst/examples/standard$ make rinside_sample0
ccache g++-4.7 -I/usr/share/R/include \
 -I/usr/local/lib/R/site-library/Rcpp/include \
 -I/usr/local/lib/R/site-library/RInside/include \
 -g -O3 -Wall -pipe -Wno-unused \
 -pedantic -std=c++11 -Wall  \
  rinside_sample0.cpp  -L/usr/lib/R/lib -lR \
 -lblas -llapack -L/usr/local/lib/R/site-library/Rcpp/lib -lRcpp \
 -Wl,-rpath,/usr/local/lib/R/site-library/Rcpp/lib \
 -L/usr/local/lib/R/site-library/RInside/lib \
 -lRInside -Wl,-rpath,/usr/local/lib/R/site-library/RInside/lib \
 -o rinside_sample0 
edd@max:~/svn/rinside/pkg/inst/examples/standard$ ./rinside_sample0    
Hello, world!        
edd@max:~/svn/rinside/pkg/inst/examples/standard$  

要部署C++11,您不需要新的编译器或项目。

只需将一个选项添加到您的编译器标志中-就是这么简单。

为了更加明确,我们还可以在rinside_sample0.cpp中添加这三行代码,使其成为一个C++11程序:

auto magic = 42;                    // C++11 
R["magic"] = magic;                    
R.parseEvalQ("print(magic)");     

并且(使用所需的-std=c++11标志),它也可以构建和运行。在Rcpp或RInside端部署它们时,严格不需要任何更改,只需使用支持C++11的编译器即可。


抱歉,我有点迷失。您是建议我不需要重新编译RInside和Rcpp吗? - beuhbbb
这就是我的示例刚刚演示的。 - Dirk Eddelbuettel
Rcpp 0.10.4是一个较旧的版本。请尝试最新版本。尝试不进行任何修改来证明您的系统没有问题。然后再加入修改。rcpp-devel列表可能会对您有所帮助,因为有相当多的OS X用户。 - Dirk Eddelbuettel
可能会与新的 clang++ 产生交互 - 我们为 CRAN 发布 Rcpp / Rinside,并通过 CRAN 在所有(合理的)系统和操作系统上进行测试(除了 Solaris,没有人使用,也没有人可以帮助我们修补)。这包括 OS X。您正在超出这些规格使用它;正如我所展示的,在我的系统上仍然可以工作,而我没有像您这样的访问权限。 - Dirk Eddelbuettel
选择更新版本并不能解决“Undefined symbols for architecture x86_64”问题。我不明白为什么我需要重新编译Rcpp和RInside以获得兼容版本,而你却不需要这样做。 - beuhbbb
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接