9

SYSTEM SPEC:

  • OS - Mac OS X 10.6.8 (Snow Leopard)
  • g++ - Macports gcc 4.8.1_2+universal
  • R - 2.15.3
  • Rcpp - 0.10.3

I keep on receiving an error when I am trying to compile functions that use C++11 in R (through Rcpp) - for some reason, g++ does not recognise -std=c++11 option.

This example is taken from Rcpp help files (it does not contain anything specific to C++11, but can show what my problem is). If I try running:

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

I get:

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.

At the same time, I can compile this function directly from bash - if this code is in useCpp11.cpp file, then this runs without any complaints:

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

Certainly, I am doing something wrong, but I cannot work out what it is. gcc 4.8 is set as a default compiler in bash, Rcpp has been working without fault in the past. I suspect that I am not telling R which version of g++ to use - could that be the case?

Skif
  • 288
  • 2
  • 12
  • If your on a mac just use clang – aaronman Aug 26 '13 at 21:19
  • I also need my code to work on Windows and Linux... – Skif Aug 26 '13 at 21:21
  • 1
    Try passing "-v" instead of "-std=c++11" to confirm your suspicion that the wrong gcc version is being selected. – Andrew Tomazos Aug 26 '13 at 21:47
  • 1
    What is the output of running `Sys.getenv()["PATH"]` in an R session? Is there an older `g++` being accessed first from one of those directories? Try forcing use of that particular `g++` with `Sys.setenv(CXX=)`. – Kevin Ushey Aug 26 '13 at 21:58
  • @user1131467 - you are absolutely right, the darn thing still uses 4.2.1. What's the best way of handling it - shall I follow Kevin's advice? – Skif Aug 26 '13 at 22:11
  • @KevinUshey, would adding CXX env be sufficient? – Skif Aug 26 '13 at 22:12
  • 2
    I think the best solution is to create a file `~/.R/Makevars`, and have your make flags and such in there. So you can set `CXX=` and not have to worry about it from then on. – Kevin Ushey Aug 26 '13 at 22:19

3 Answers3

12

Kevin Ushley is absolutely right - the easiest way to make sure that the right compiler is being used is through Makevars file. In my case, I added:

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

This is what I have been missing - and it all worked afterwards. This works if you are compiling your package.

Skif
  • 288
  • 2
  • 12
  • 2
    I use the exact same mechanism -- but using it the way you describe it here prevents you from creating CRAN-compatible package as the C++11 option is now global (and we are not allowed to upload C++11 code). – Dirk Eddelbuettel Aug 27 '13 at 12:07
  • I don't mind that it is not CRAN-compatible - it's all written for internal use. It is a good job that we've managed to solve this one - details like these matter and often stand between users and good code :-) – Skif Aug 27 '13 at 13:44
  • Just noting that for some reason it was ignored when I put it in the `src/Makevars` inside the package, but as soon as I put it in `~/.R/Makevars` it worked. – Calimo Jan 07 '14 at 17:19
7

Quick ones:

  • you are behind on Rcpp which is at a released version 0.10.4

  • the version you are using (0.10.3) does have have a plugin for C++11

  • there is an entire article at the Rcpp Gallery which details this.

So allow me to quote from that C++11 piece on the Rcpp Gallery:

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

where the code in /tmp/cpp11.cpp is as follows:

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

If that does not work for you, then your system is not set up right. In other words, this is not a question for the Rcpp tag -- but rather for 'how do I set up my path to invoke the version of g++ I think I should be invoking'.

Dirk Eddelbuettel
  • 360,940
  • 56
  • 644
  • 725
  • Dirk, got it - I am out of date on R which is why I did not see 0.10.4. I have read your articles prior to posting and found them very informative - however, my problem was with my system set-up, you were exactly right. I did not know how to enforce R to use the compiler of my choice rather than the default one (which, in my case, does not support C++11). – Skif Aug 27 '13 at 01:00
  • Good to know. You need to sort out your `$PATH` and installation. Also, please feel free to 'accept' the answer (click on the tick-mark) and/or upvote it (click on on the 'up' triangle). – Dirk Eddelbuettel Aug 27 '13 at 01:12
  • On my setup (R 3.4.2, Rcpp 0.12.12, clang LLVM 9.0.0 on x86_64-apple-darwin16.7.0), adding `[[Rcpp::plugins("cpp11")]]` doesn't seem to be enough. I also have to add `PKG_CXXFLAGS = -std=c++11` to my `Makevars` or else the flag doesn't get added to the commands, and I get warnings like `warning: 'auto' type specifier is a C++11 extension`. – Ken Williams Oct 19 '17 at 16:36
  • You confused what command-line usage does ("plugins" for `cxxFunction()` or `sourceCpp()`) and what packages do ("src/Makevars"). There is no intersection here. Two different uses. – Dirk Eddelbuettel Oct 19 '17 at 16:46
2

If you don't want to fix up your path you can set the PKG_CXXFLAGS environment variable just prior to compiling.

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

For example:

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

and in 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;

where Foo_R_wrapper.cpp wraps a C++ function FooBar defined and implemented in Foo.h and Foo.cpp respectively.

Foo_R_wrapper.cpp could contain the following:

#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;
}
Beau Johnston
  • 116
  • 1
  • 4