【问题标题】:RInside and Rcpp in c++x11c++x11 中的 RInside 和 Rcpp
【发布时间】:2013-10-24 14:15:40
【问题描述】:

我想在 c++x11 代码中使用 RInside 来调用 R 例程。默认情况下,R 似乎安装了库的 c++98 版本,因此链接不成功。我想知道我应该执行哪些不同的步骤来安装 RInside 的 c++x11 版本(但我想我需要重新编译所有 R/R 包,是吗?)以及是否存在一些更简单的解决方案。在此先感谢(我在 MacO 上工作)

更新: 我重新安装了 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

然后我使用 (no 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

使用 c++x11 选项重新编译 Rcpp 和 RInside 时

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 存储库和分发中多年的源代码。

标签: r c++11 linker rcpp rinside


【解决方案1】:

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 可能不会太难。

【讨论】:

    【解决方案2】:

    我不知道不同的链接器要求。你所拥有的应该只是工作。否则,请显示您的实际链接步骤和错误,最好以可重现的方式显示,我也可以查看我的结果。

    见证以下内容。我们首先使用默认标志构建:

    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?
    • 这就是我刚才演示的例子。
    • Rcpp 0.10.4 是旧版本。试试最新的。尝试所有不做任何修改以证明您的系统没有被软管。然后撒上修改。 rcpp-devel 列表可能会对您有所帮助,因为 OS X 用户很多。
    • 很可能会与新的clang++ 进行交互——我们为 CRAN 发布了 Rcpp / Rinside,它通过了 CRAN 测试的所有(合理的)系统和操作系统(除了注意到的例外没有人使用的 Solaris,没有人可以帮助我们提供补丁)。这包括 OS X。您正在使用它超出这些规格;正如我所展示的那样,它仍然可以在我的系统上运行,但我无法访问像你这样的系统。
    • 选择较新的版本并不会删除“架构 x86_64 的未定义符号”。我不明白为什么我需要重新编译 Rcpp 和 RInside 以获得兼容版本,而您不需要它。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-05
    • 1970-01-01
    • 2016-07-02
    • 2013-03-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多