【问题标题】:g++ errors when trying to compile c++11 with Rcpp尝试使用 Rcpp 编译 c++11 时出现 g++ 错误
【发布时间】:2014-02-12 15:10:19
【问题描述】:

系统规格:

  • 操作系统 - Mac OS X 10.6.8(雪豹)
  • g++ - Macports gcc 4.8.1_2+universal
  • R - 2.15.3
  • Rcpp - 0.10.3

当我尝试编译在 R 中(通过 Rcpp)使用 C++11 的函数时,我不断收到错误消息 - 由于某种原因,g++ 无法识别 -std=c++11 选项。

此示例取自 Rcpp 帮助文件(它不包含任何特定于 C++11 的内容,但可以显示我的问题所在)。如果我尝试运行:

require( Rcpp )
Sys.setenv( "PKG_CXXFLAGS"="-std=c++11" )
cppFunction(plugins=c("cpp11"), '
int useCpp11() {
    int x = 10;
    return x;
}')

我明白了:

cc1plus: error: unrecognized command line option "-std=c++11"
make: *** [file61239328ae6.o] Error 1
g++ -arch x86_64 -I/Library/Frameworks/R.framework/Resources/include -I/Library/Frameworks/R.framework/Resources/include/x86_64 -DNDEBUG  -I/usr/local/include  -I"/Library/Frameworks/R.framework/Versions/2.15/Resources/library/Rcpp/include"   -std=c++11  -fPIC  -g -O2  -c file61239328ae6.cpp -o file61239328ae6.o 
Error in sourceCpp(code = code, env = env, rebuild = rebuild, showOutput = showOutput,  : 
  Error 1 occurred building shared library.

同时,我可以直接从 bash 编译这个函数 - 如果这个代码在 useCpp11.cpp 文件中,那么它运行没有任何抱怨:

g++ useCpp11.cpp -std=c++11

当然,我做错了什么,但我无法弄清楚它是什么。 gcc 4.8 被设置为 bash 中的默认编译器,Rcpp 过去一直在正常工作。我怀疑我没有告诉 R 使用哪个版本的 g++ - 可能是这样吗?

【问题讨论】:

  • 如果你在 Mac 上使用 clang
  • 我还需要我的代码在 Windows 和 Linux 上工作...
  • 尝试传递“-v”而不是“-std=c++11”来确认您怀疑选择了错误的 gcc 版本。
  • 在 R 会话中运行 Sys.getenv()["PATH"] 的输出是什么?是否有一个较旧的g++ 首先从这些目录之一访问?尝试使用 Sys.setenv(CXX=<full_path_to_g++>) 强制使用特定的 g++
  • 我认为最好的解决方案是创建一个文件~/.R/Makevars,并在其中放置您的制作标志等。所以你可以设置CXX=<path_to_g++>,从此不用操心。

标签: c++ r gcc c++11 rcpp


【解决方案1】:

Kevin Ushley 绝对正确 - 确保使用正确编译器的最简单方法是通过 Makevars 文件。就我而言,我补充说:

CXX = g++-4.8.1
PKG_CXXFLAGS = -std=c++11

这就是我所缺少的——后来一切都奏效了。如果您正在编译您的包,这将有效。

【讨论】:

  • 我使用完全相同的机制——但使用您在此处描述的方式会阻止您创建与 CRAN 兼容的包,因为 C++11 选项现在是全局的(我们不允许上传 C++11 代码)。
  • 我不介意它与 CRAN 不兼容——它都是为内部使用而编写的。我们已经设法解决了这个问题,这是一项很好的工作 - 像这些细节很重要,并且经常站在用户和好的代码之间:-)
  • 只是注意到,由于某种原因,当我将它放入包内的 src/Makevars 时,它被忽略了,但我一放入 ~/.R/Makevars,它就起作用了。
【解决方案2】:

快速的:

所以请允许我引用C++11 piece on the Rcpp Gallery

R> library(Rcpp)
R> sourceCpp("/tmp/cpp11.cpp")
R> useAuto()
[1] 42
R> 

其中/tmp/cpp11.cpp中的代码如下:

#include <Rcpp.h>

// Enable C++11 via this plugin (Rcpp 0.10.3 or later)
// [[Rcpp::plugins("cpp11")]]

// [[Rcpp::export]]
int useAuto() {
    auto val = 42;      // val will be of type int
    return val;
}

如果这对您不起作用,那么您的系统设置不正确。换句话说,这不是Rcpp 标签的问题——而是“如何设置我的路径来调用我认为我应该调用的 g++ 版本”。

【讨论】:

  • Dirk,明白了——我在 R 上已经过时了,这就是为什么我没有看到 0.10.4。我在发布之前阅读了您的文章,发现它们非常有用 - 但是,我的问题在于我的系统设置,您完全正确。我不知道如何强制 R 使用我选择的编译器而不是默认编译器(在我的情况下,它不支持 C++11)。
  • 很高兴知道。您需要整理您的$PATH 和安装。此外,请随时“接受”答案(单击对勾)和/或投票(单击“向上”三角形)。
  • 在我的设置中(R 3.4.2,Rcpp 0.12.12,x86_64-apple-darwin16.7.0 上的 clang LLVM 9.0.0),添加 [[Rcpp::plugins("cpp11")]] 似乎还不够。我还必须将PKG_CXXFLAGS = -std=c++11 添加到我的Makevars 中,否则该标志不会添加到命令中,并且我会收到warning: 'auto' type specifier is a C++11 extension 之类的警告。
  • 您混淆了命令行使用的作用(cxxFunction()sourceCpp() 的“插件”)和软件包的作用(“src/Makevars”)。这里没有交叉点。两种不同的用途。
【解决方案3】:

如果您不想修复路径,可以在编译之前设置 PKG_CXXFLAGS 环境变量。

     export PKG_CXXFLAGS='`Rscript -e "Rcpp:::CxxFlags()"` -std=c++11'

例如:

R

#generate the bare Rcpp package as usual
library(Rcpp)
Rcpp.package.skeleton("Foo",
                      example_code=FALSE,
                      attributes=TRUE,
                      cpp_files=c("./Foo_R_wrapper.cpp", "./Foo.h", "/Foo.cpp")
                     )    

Bash

#tell the compiler to use C++11
export PKG_CXXFLAGS='`Rscript -e "Rcpp:::CxxFlags()"` -std=c++11'

#compile as usual
cd ./Foo/;
R -e 'Rcpp::compileAttributes(".",verbose=TRUE)';
cd ..;

R CMD build Foo;
#ensure that there are no bugs
R CMD check Foo;

其中 Foo_R_wrapper.cpp 包装了一个分别在 Foo.hFoo.cpp 中定义和实现的 C++ 函数 FooBar。

Foo_R_wrapper.cpp 可以包含以下内容:

#include <Rcpp.h>                                   

#include "Foo.h"                                    

// [[Rcpp::export]]                                 
SEXP FooBar(SEXP baa)
{                                                   
    Rcpp::NumericVector baa_vec(baa)
    //Do something from Foo.h (to baa_vec?)
    ...
    //etc
    return baa_vec;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-10-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-08
    相关资源
    最近更新 更多