C++17 in a package with Rcpp - r

#include <cmath>
#include <math.h>
#include <Rcpp.h>
// [[Rcpp::plugins("cpp17")]]
// [[Rcpp::export]]
double rcpp_hello_world(Rcpp::NumericVector x) {
double z;
z = std::cyl_bessel_i(0, x[0]);
return z ;
}
When I run the above code and call it using sourceCpp, it works as expected. However inside a R package setup I get
error: cyl_bessel_iis not a member of ‘std
11 | z = std::cyl_bessel_i[0]);
| ^~~~~~~~~~~~
make: *** [/usr/lib64/R/etc/Makeconf:177: rcpp_hello_world.o] Error 1
ERROR: compilation failed for package ‘Package’
upon running Rcpp::compileAttributes() and devtools::document(). I initialised the package with Rcpp.package.skeleton.
cyl_bessel_i was added to the standard library in C++17.
I am using gcc-12.1.0-2 and R-4.2.0-3. I am on Arch Linux.

The default C++ standard used in current versions of R is C++11 (or C++14 if available). Since you require C++17, you need to declare it in the src/Makevars file, using the line
CXX_STD=CXX17
In a comment you referred to the Rcpp documentation which says that Makevars is optional since Rcpp 0.11.0. I think that was written about linking to the Rcpp libs, but it is also true here, as pointed out by #MikkoMarttila: you can alternatively declare the C++ version in the SystemRequirements: field of the DESCRIPTION file, e.g.
SystemRequirements: C++17

Related

fatal error: 'RcppArmadillo.h' file not found

Rcpp::sourceCpp('~/Desktop/my.cpp')
Was working on some stand alone Rcpparmadillo files and came across this error:
fatal error: 'RcppArmadillo.h' file not found
#include <RcppArmadillo.h>
^~~~~~~~~~~~~~~~~
The example "my.cpp":
// [[Rcpp::depends(RcppArmadillo)]
#include <RcppArmadillo.h>
// [[Rcpp::export]]
arma::vec add_two(arma::vec x){
return x + 2;
}
/*** R
add_two( c(42, 22))
*/
I recently upgraded to RcppArmadillo version 0.9.900.1.0 and I am on macOS Catalina 10.15.5 and R version 3.6.1. This seems unusual as I can still build a package with RcppArmadillo, anyway I found some solution I will post below incase someone else has the same problem.
For others troubleshooting a similar problem, what worked for me was to add these lines to the DESCRIPTION file of my R package:
LinkingTo:
Rcpp,
RcppArmadillo
Posting here in case it's helpful for others. I came across this solution here: https://mattstats.wordpress.com/2016/11/04/r-hub-for-microsoft-r-open/
Copied contents of the folder:
-I"/Library/Frameworks/R.framework/Versions/3.6/Resources/library/RcppArmadillo/include"
To:
-I"/Library/Frameworks/R.framework/Versions/3.6/Resources/library/Rcpp/include"

Combine R, C++ and Fortran

I am trying to reimplement an R function using C++ and RCpp to speed up the computation. And in the C++ implementation, I need to use a Fortran function mvtdst found in link.
#include <Rcpp.h>
#include "mvtnorm.h"
using namespace Rcpp;
// [[Rcpp::export]]
NumericVector pmvnorm_rcpp(NumericVector upper, NumericMatrix corr)
{
double error;
double mvnP = pmvnorm_P(2, upper, corr, &error) ;
return mvnP ;
}
/*** R
pmvnorm_rcpp(c(1.5,1.5),c(0.0))
*/
Here, pmvnorm_P is defined in the mvtnorm.cpp file.
All the files found in link are kept in the working directory along with the RcppWrapper.cpp file.
When I compile my RcppWrapper.cpp file using sourceCpp() function in RCpp package, it gives the following error.
mvtnorm.o:mvtnorm.cpp:(.text+0x7c): undefined reference to `mvtdst_'
collect2.exe: error: ld returned 1 exit status
Error in Rcpp::sourceCpp("RcppWrapper.cpp") :
Error occurred building shared library.
Does anyone know how to resolve this error?
When you have code in two sources files
mvtnorm.cpp calling your backend function pmvnorm_P()
another file providing it
then you also must provide link instructions. Simply put, sourceCpp() is only intentended and working for one-file solutions (unless you give link instructions).
Simplest fix: just create a package assembling all your files in src/.
Fortran and C++ mangle the names of functions differently. It looks like mvtdst is the name of your Fotran function. (Right?) You need to "mangle" that by hand when called from C++. So instead of calling mvtdst, call mvtdst_ with the trailing underscore.
Unfortunately, compilers are not consistent in the mangling, so this will not be portable. (To make it portable, you'll need some sort of preprocessing that matched the mangling to the compiler.)

C++ R package error: uploading library

I submitted my package to the CRAN repository. The package was accepted without errors but in the second step of checking the CRAN maintainers reported the following error.
Unfortunately I don't understand how I can fix it.
In file included from /Builds/CRAN-QA-Simon/packages/mavericks-x86_64/Rlib/3.3/RcppArmadillo/include/armadillo:23:
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/fstream:864:20: error:
no member named 'Rf_error' in 'std::__1::codecvt_base'; did you mean simply 'Rf_error'?
if (__r == codecvt_base::error)
^~~~~~~~~~~~~~
/Library/Frameworks/R.framework/Resources/include/R_ext/Error.h:35:12: note:
'Rf_error' declared here
void NORET Rf_error(const char *, ...);
^
In my C++ file, I wrote:
#include <math.h>
#include "ANN/ANN.h"
#include "NN.h"
#include <R.h>
#include "RcppArmadillo.h"
#include <map>
#include <vector>
#include <iostream>
How do I have to correct this? Has Rpp.h to be included?
R itself is written in C, due to its early start way back in the early 1990s. C has no namespaces -- which can lead to conflicts as we lack the namespace separation. Identifiers from different libraries sharing the same name can be mistaken. This has happened here.
R uses, in its C API, functions length(), error(), .... etc which, given how common the name is, are likely to clash. So R has as mechanism of prepending Rf_ to its symbols: error becomes Rf_error. This use the preprecessor, which is reasonably dumb (as opposed to using the compiler itself). So when R sees error it wants it to be Rf_error.
What happens here is that you very likely has #include <RcppArmadillo.h> (and therefore the implicit #include <Rcpp.h> before the include for your actual library. Try it the other way around. That way R's messing with its error() will not interfere with the library one which is confusing you here.

How do you import external symbols when compiling the C sources of an R package?

I have downloaded the source code of an R package, "stats" in this case,
and would like to compile the C code of a function in there.
So far, compilation in the narrower sense seems to work, but the linker needs to import some symbols from
external libraries, e.g. "R_BaseEnv", defined by
#define LibImport __declspec(dllimport)
#define LibExtern extern LibImport
LibExtern SEXP R_BaseEnv; /* The base environment; formerly R_NilValue */
Among the downloaded files are some .dll-files, e.g. "R.dll",
but I have learned from here that the linker needs the corresponding .lib-files.
So how can I get the .lib-files? Searching for "R.lib" was without result.

Rcpp: "Cannot change working directory" when called with embedded R code

I have been successfully using Rcpp for a while, and have been able to experiment with most of its features. However, on a Windows 7 machine, with RStudio 0.98.1049 I am not able to sourceCpp a file that has embedded R code chunks in it.
Here is M(N)WE:
#include <Rcpp.h>
using namespace Rcpp;
// [[Rcpp::export]]
double plusOne(double x) {
return x + 1.0;
}
/*** R
plusOne(3)
*/
When I sourceCpp(..., embeddedR = TRUE), I get this error message:
Error in setwd(rWorkingDir) : cannot change working directory
which I am guessing arises from line 181 here. Not sure how to fix this. I am able to change directories from RStudio in general.
This issue was resolved with Rcpp 0.11.3 -- it should go away if you update.

Resources