3

I have some running c++ code using the Lapacke version that comes with OpenBlas. I would like to include this code into an R package and transfer data between that function and R using the Rcpp package. But somehow the two seem not to like each other. As soon as I have #include <lapacke.h> and #include <Rcpp.h> in one source file it isn't compiling anymore. Both separately work fine. There is a whole bunch off error messages which as far as I can tell say that Rcpp is broken (e.g /home/Alex/R/x86_64-pc-linux-gnu-library/3.4/Rcpp/include/Rcpp/traits/traits.h:32:15: error: expected ‘)’ before ‘__extension__’).

I have no idea why this happens. Is there a way to use both at the same time? Or should I do something completely different?

Here is a minimal example that gives me the error:

  1. I created a package using

    Rcpp::Rcpp.package.skeleton("LT", example_code = FALSE)
    
  2. I added a .cpp file to /src containing

    #include <lapacke.h>
    #include <Rcpp.h>
    
    int test_LAPACK(){
      return(1);
    }
    
  3. I added a Makvars file to /src containing

    PKG_CXXFLAGS = -I/opt/OpenBLAS/include
    PKG_LIBS =  -L/opt/OpenBLAS/lib -lopenblas -lpthread -lgfortran
    CXX_STD = CXX11
    
  4. Compile and install

    Rcpp::compileAttributes("LT")
    devtools::install("LT")
    
Alex
  • 4,925
  • 2
  • 32
  • 48
  • 1
    @DirkEddelbuettel At least for my simple example changing the order of the includes seem to work. Thanks for this tip. – Alex Nov 10 '18 at 17:01
  • That is _very often_ the case. Large projects tend to define things, other projects may get "hit" by that. Experience teaches you to put certain things first or last. Worst case you have conflicting needs... – Dirk Eddelbuettel Nov 10 '18 at 17:08
  • But yes, added that comment as an edit to the answer--the key really is the link order here. – Dirk Eddelbuettel Nov 10 '18 at 17:34

1 Answers1

5

It actually works on my system following a standard sudo apt install liblapacke-dev provided I also change the include order.

Witness:

Source

rob:/tmp/lapacke/LT$ cat src/lt.cpp 
#include <Rcpp.h>
#include <lapacke.h>

int test_LAPACK(){
          return(1);
}
rob:/tmp/lapacke/LT$ ls src/      ## no Makevars needed
lt.cpp
rob:/tmp/lapacke/LT$ 

Build

rob:/tmp/lapacke/LT$ build.r 
* checking for file ‘./DESCRIPTION’ ... OK
* preparing ‘LT’:
* checking DESCRIPTION meta-information ... OK
* cleaning src
* installing the package to process help pages
* saving partial Rd database
* cleaning src
* checking for LF line-endings in source and make files and shell scripts
* checking for empty or unneeded directories
Removed empty directory ‘LT/R’
* building ‘LT_1.0.tar.gz’

rob:/tmp/lapacke/LT$

Install

rob:/tmp/lapacke/LT$ install.r LT_1.0.tar.gz 
* installing *source* package ‘LT’ ...
** libs
ccache g++ -I"/usr/share/R/include" -DNDEBUG  -I"/usr/local/lib/R/site-library/Rcpp/include"    -fpic  -g -O3 -Wall -pipe   -march=native -c lt.cpp -o lt.o
ccache g++ -Wl,-S -shared -L/usr/lib/R/lib -Wl,-Bsymbolic-functions -Wl,-z,relro -o LT.so lt.o -L/usr/lib/R/lib -lR
installing to /usr/local/lib/R/site-library/LT/libs
** help
*** installing help indices
** building package indices
** testing if installed package can be loaded
* DONE (LT)
rob:/tmp/lapacke/LT$ 

Run

(After I added a line // [[Rcpp::export]], ran compileAtttributes() and rebuilt and installed.)

rob:/tmp/lapacke/LT$ r -lLT -p -e'test_LAPACK()'
[1] 1
rob:/tmp/lapacke/LT$ 

Summary

Check your compiler. There is no fundamental reason this should not work, and it works here (Ubuntu 18.04).

Dirk Eddelbuettel
  • 360,940
  • 56
  • 644
  • 725