Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Compilation error using Rcpp with typedef

I'm writing some C++ components for my R package using RcppEigen and I'm having trouble using typedefs in this context. The following code won't compile:

// [[Rcpp::depends(RcppEigen)]]
#include <RcppEigen.h>

using namespace Rcpp;

typedef Eigen::ArrayXd MapAr1;

// [[Rcpp::export]]
MapAr1 myFun(const MapAr1& x){

  MapAr1 y = x;
  y[0] = 0;

  return y;

}

Here is the error:

==> Rcpp::compileAttributes()

* Updated src/RcppExports.cpp
* Updated R/RcppExports.R

==> devtools::document(roclets=c('rd', 'collate', 'namespace'))

Updating my_package documentation
Loading my_package
Re-compiling my_package
'/usr/lib64/R/bin/R' --no-site-file --no-environ --no-save --no-restore  \
  --quiet CMD INSTALL '/my_path/my_package'  \
  --library='/tmp/RtmpgPjAdf/devtools_install_125071da0b53' --no-R --no-data  \
  --no-help --no-demo --no-inst --no-docs --no-exec --no-multiarch  \
  --no-test-load 

* installing *source* package ‘my_package’ ...
g++ -m64 -I/usr/include/R -DNDEBUG  -I/usr/local/include -I"/my_path/R/x86_64-redhat-linux-gnu-library/3.3/Rcpp/include" -I" /my_path/R/x86_64-redhat-linux-gnu-library/3.3/RcppEigen/include"   -fpic  -O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches   -m64 -mtune=generic  -c RcppExports.cpp -o RcppExports.o
** libs
RcppExports.cpp:10:1: error: ‘MapAr1’ does not name a type
 MapAr1 myFun(const MapAr1& x);
 ^
RcppExports.cpp: In function ‘SEXPREC* my_package_myFun(SEXP)’:
RcppExports.cpp:15:42: error: ISO C++ forbids declaration of ‘type name’ with no type [-fpermissive]
     Rcpp::traits::input_parameter< const MapAr1& >::type x(xSEXP);
                                          ^
RcppExports.cpp:15:50: error: template argument 1 is invalid
     Rcpp::traits::input_parameter< const MapAr1& >::type x(xSEXP);
                                                  ^
RcppExports.cpp:15:58: error: expected initializer before ‘x’
     Rcpp::traits::input_parameter< const MapAr1& >::type x(xSEXP);
                                                          ^
RcppExports.cpp:16:40: error: ‘x’ was not declared in this scope
     rcpp_result_gen = Rcpp::wrap(myFun(x));
                                        ^
RcppExports.cpp:16:41: error: ‘myFun’ was not declared in this scope
     rcpp_result_gen = Rcpp::wrap(myFun(x));
                                         ^
make: *** [RcppExports.o] Error 1
ERROR: compilation failed for package ‘my_package’
* removing ‘/tmp/RtmpgPjAdf/devtools_install_125071da0b53/my_package’
Error: Command failed (1)
Execution halted

Exited with status 1.

The same code compiles outside the package. So I'm guessing that something is not copied properly to the RcppExports files. I also noticed a similar problem when trying to use the RcppEigen namespace: using namespace RcppEigen; is not copied.

Any idea how to solve this without modifying RcppExports by hand? Thanks!

like image 463
ixpl Avatar asked Mar 19 '17 09:03

ixpl


1 Answers

You are making your life too complicated by insisting on the typedef. Once you include it in the file, and your function signature, it becomes part of the interface and hence also needs to be in your RcppExports.cpp. So you need to provide it 'one level higher'.

But there is a provision for that: call the file pkgname_types.h and it will be included. I created a simple package eigentest and added a file eigentest_types.h in the src/ directory:

#include <RcppEigen.h>

typedef Eigen::ArrayXd MapAr1;

and then added it to your code snippet with

#include "eigentest_types.h"

instead of the typedef.

That's all you need -- just replace eigentest with your package name.

like image 55
Dirk Eddelbuettel Avatar answered Nov 16 '22 14:11

Dirk Eddelbuettel