2013-08-26 56 views
10

HỆ THỐNG SPEC:g ++ lỗi khi cố gắng biên dịch C++ 11 với Rcpp

  • OS - Mac OS X 10.6.8 (Snow Leopard)
  • g ++ - Macports gcc 4.8 .1_2 + phổ
  • R - 2.15.3
  • Rcpp - 0.10.3

Tôi tiếp tục nhận được lỗi khi tôi đang cố gắng biên dịch các hàm sử dụng C++ 11 trong R (thông qua Rcpp) - vì lý do nào đó, g ++ không nhận dạng được tùy chọn -std=c++11.

Ví dụ này được lấy từ các tệp trợ giúp Rcpp (nó không chứa bất kỳ điều gì cụ thể cho C++ 11, nhưng có thể cho biết vấn đề của tôi là gì). Nếu tôi cố gắng chạy:

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

tôi nhận được:

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. 

Cùng lúc đó, tôi có thể biên dịch chức năng này trực tiếp từ bash - nếu mã này là trong useCpp11.cpp tập tin, sau đó này chạy mà không có bất kỳ khiếu nại :

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

Chắc chắn, tôi đang làm điều gì đó sai, nhưng tôi không thể tìm ra nó là gì. gcc 4.8 được đặt làm trình biên dịch mặc định trong bash, Rcpp đã hoạt động mà không có lỗi trong quá khứ. Tôi nghi ngờ rằng tôi không nói với R mà phiên bản của g ++ để sử dụng - có thể đó là trường hợp?

+0

Nếu bạn trên một mac chỉ cần sử dụng kêu vang – aaronman

+0

Tôi cũng cần mã của tôi để làm việc trên Windows và Linux ... – Skif

+1

Cố gắng đi qua "-v" thay vì "-std = C++ 11" để xác nhận sự nghi ngờ của bạn rằng phiên bản gcc sai đang được chọn. –

Trả lời

11

Kevin Ushley hoàn toàn đúng - cách dễ nhất để đảm bảo rằng trình biên dịch phù hợp đang được sử dụng là thông qua tệp Makevars.Trong trường hợp của tôi, tôi đã thêm:

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

Đây là những gì tôi đã bỏ lỡ - và tất cả đều hoạt động sau đó. Điều này hoạt động nếu bạn đang biên soạn gói của mình.

+2

Tôi sử dụng chính xác cơ chế đó - nhưng sử dụng nó theo cách bạn mô tả ở đây ngăn bạn tạo gói CRAN tương thích vì tùy chọn C++ 11 hiện là toàn cục (và chúng tôi không được phép tải lên mã C++ 11) . –

+0

Tôi không nhớ rằng nó không tương thích với CRAN - tất cả đều được viết để sử dụng nội bộ.Đó là một công việc tốt mà chúng tôi đã xoay xở để giải quyết vấn đề này và thường đứng giữa người dùng và mã tốt :-) – Skif

+0

Chỉ cần lưu ý rằng vì lý do nào đó, nó bị bỏ qua khi tôi đặt nó trong 'src/Makevars 'bên trong gói, nhưng ngay sau khi tôi đặt nó vào' ~/.R/Makevars' nó hoạt động. – Calimo

7

nhanh những:

  • bạn đang ở phía sau trên Rcpp mà là một phiên bản phát hành 0.10.4

  • phiên bản bạn đang sử dụng (0.10.3) không có có một plugin cho C++ 11

  • an entire article at the Rcpp Gallery chi tiết điều này.

Vì vậy, cho phép tôi trích dẫn từ C++11 piece on the Rcpp Gallery rằng:

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

nơi mã trong /tmp/cpp11.cpp là như sau:

#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; 
} 

Nếu điều đó không làm việc cho bạn, sau đó hệ thống của bạn không được thiết lập đúng. Nói cách khác, đây không phải là câu hỏi cho thẻ Rcpp - nhưng thay vì 'làm cách nào để thiết lập đường dẫn của tôi để gọi phiên bản g ++, tôi nghĩ tôi nên gọi'.

+0

Dirk, hiểu rồi - Tôi đã lỗi thời về R, đó là lý do tại sao tôi không thấy 0.10.4. Tôi đã đọc các bài viết của bạn trước khi đăng và thấy chúng rất nhiều thông tin - tuy nhiên, vấn đề của tôi là với việc thiết lập hệ thống của tôi, bạn đã đúng. Tôi không biết cách thực thi R để sử dụng trình biên dịch của lựa chọn của tôi thay vì trình biên dịch mặc định (trong trường hợp của tôi, không hỗ trợ C++ 11). – Skif

+0

Điều cần biết. Bạn cần phải sắp xếp của bạn '$ PATH' và cài đặt. Ngoài ra, xin vui lòng 'chấp nhận' câu trả lời (bấm vào dấu chọn) và/hoặc upvote nó (bấm vào hình tam giác 'lên'). –

+0

Trên thiết lập của tôi (R 3.4.2, Rcpp 0.12.12, clang LLVM 9.0.0 trên x86_64-apple-darwin16.7.0), thêm '[[Rcpp :: plugins (" cpp11 ")]]' không có vẻ là đủ. Tôi cũng phải thêm 'PKG_CXXFLAGS = -std = C++ 11' vào' Makevars' của tôi hoặc cờ khác không được thêm vào các lệnh, và tôi nhận được các cảnh báo như 'warning: 'auto' type specifier là C++ 11 tiện ích mở rộng'. –

0

Nếu bạn không muốn sửa chữa đường dẫn của mình, bạn có thể đặt biến môi trường PKG_CXXFLAGS ngay trước khi biên dịch.

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

Ví dụ:

Trong 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") 
        )  

và trong 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; 

nơi Foo_R_wrapper.cpp kết thúc tốt đẹp một C++ vui vẻ ction FooBar được xác định và triển khai trong các số Foo.hFoo.cpp tương ứng.

Foo_R_wrapper.cpp có thể chứa những điều sau đây:

#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; 
} 
Các vấn đề liên quan