Undefined reference errors when including Rcpp.h

2019-07-24 16:54发布

I am using 64bit Ubuntu, and I am trying to write C++.

I discovered if I use #include <Rcpp.h>, I don't even need to call any functions in the R namespace, and I would already receive undefired reference errors:

obj/x.o: In function `Rcpp::Rstreambuf<true>::xsputn(char const*, long)':
/usr/local/lib/R/site-library/Rcpp/include/Rcpp/iostream/Rstreambuf.h:61: undefined reference to `Rprintf'
obj/x.o: In function `Rcpp::Rstreambuf<false>::xsputn(char const*, long)':
/usr/local/lib/R/site-library/Rcpp/include/Rcpp/iostream/Rstreambuf.h:65: undefined reference to `REprintf'
obj/x.o: In function `Rcpp::Rstreambuf<true>::overflow(int)':
/usr/local/lib/R/site-library/Rcpp/include/Rcpp/iostream/Rstreambuf.h:70: undefined reference to `Rprintf'
obj/x.o: In function `Rcpp::Rstreambuf<false>::overflow(int)':
/usr/local/lib/R/site-library/Rcpp/include/Rcpp/iostream/Rstreambuf.h:74: undefined reference to `REprintf'
obj/x.o: In function `Rcpp::Rstreambuf<true>::sync()':
/usr/local/lib/R/site-library/Rcpp/include/Rcpp/iostream/Rstreambuf.h:79: undefined reference to `R_FlushConsole'
obj/x.o: In function `Rcpp::Rstreambuf<false>::sync()':
/usr/local/lib/R/site-library/Rcpp/include/Rcpp/iostream/Rstreambuf.h:83: undefined reference to `R_FlushConsole'

I have installed r-base and r-base-dev. I installed Rcpp by running R as root and did a install.package("Rcpp")

I compile the C++ program using g++ with -I/usr/local/lib/R/site-library/Rcpp/include

What am I missing here? Thanks for any replies.

2条回答
叛逆
2楼-- · 2019-07-24 17:20

Just pulling Rcpp headers is not enough. You also need R headers and linking against R's library. You could use e.g. R CMD SHLIB to do this for you.

However, I'd suggest you either:

  • create a package that has LinkingTo: Rcpp etc ... (see Rcpp's documentation).
  • use sourceCpp on your .cpp file. See ?sourceCpp
查看更多
可以哭但决不认输i
3楼-- · 2019-07-24 17:22

As Romain Francois points out, you can't just have the headers (declarations), you also need the implementation.

What I suggest is to make a Makefile that produces a .so object. The R CMD SHLIB command is a good starting place to figure out which flags are needed, but it can't handle functions designed to be executed outside of Matlab.

Then, you need to find Rcpp.so and libR.so and link against both of them in your g++ call.

So, there is hope for "using R outside of R" -- in my case, I was able to compile some stuff from the VineCopula package into a .so file that Matlab was able to read.

See below for my Makefile (just as an example):

CFLAGS=-I/usr/share/R/include/ -I/usr/local/lib/R/site-library/Rcpp/include/ -I/usr/local/lib/R/site-library/VineCopula/include -dynamiclib -Wl,-headerpad_max_install_names -shared -L/usr/lib/R/lib -lR 
CFLAGS2=-I/usr/share/R/include/ -I/usr/local/lib/R/site-library/Rcpp/include/ -I/usr/local/lib/R/site-library/VineCopula/include 
LDFLAGS=-DNDEBUG -fpic  -g -O2 -fstack-protector-strong -Wformat -Werror=format-security -Wdate-time -D_FORTIFY_SOURCE=2 -g

all: RVinePDF.so

RVinePDF.so: RVinePDF.o Rcpp.so libR.so
  g++ $(CFLAGS) -o RVinePDF.so RVinePDF.o Rcpp.so libR.so $(LDFLAGS) 
  \rm *.o 

RVinePDF.o: RVinePDF.cpp 
  g++ $(CFLAGS2) -o RVinePDF.o -c RVinePDF.cpp $(LDFLAGS)

[other .o files defined similarly]
查看更多
登录 后发表回答