I have a header file called coolStuff.h
that contains a function awesomeSauce(arg1)
that I would like to use in my cpp source file.
Directo
The problem is that sourceCpp
is expressly designed to build only a single standalone source file. If you want sourceCpp
to have dependencies then they need to either be:
In the system include directories (i.e. /usr/local/lib
or /usr/lib
); or
In an R package which you list in an Rcpp::depends
attribute
As Dirk said, if you want to build more than one source file then you should consider using an R package rather than sourceCpp
.
Note that if you are working on a package and perform a sourceCpp on a file within the src directory of the package it will build it as if it's in the package (i.e. you can include files from the src directory or inst/include directory).
I was able to link a boost library using the following global command in R before calling sourceCpp
Sys.setenv("PKG_CXXFLAGS"="-I \path-to-boost\")
Basically mirroring this post but with a different compiler option: http://gallery.rcpp.org/articles/first-steps-with-C++11/
Angle brackets <> are for system includes, such as the standard libs.
For files local to your own project, use quotes: "".
Also, if you are placing headers in a different directory, the header path should be specified local to the source file including it.
So for your example this ought to work:
#include "../cppHeaders/coolStuff.h"
You can configure the search paths such that the file could be found without doing that, but it's generally only worth doing that for stuff you want to include across multiple projects, or otherwise would expect someone to 'install'.
We can add it by writing path to the header in the PKG_CXXFLAGS
variable of the .R/Makevars
file as shown below. The following is an example of adding header file of xtensor
installed with Anaconda in macOS.
⋊> ~ cat ~/.R/Makevars
CC=/usr/local/bin/gcc-7
CXX=/usr/local/bin/g++-7
CPLUS_INCLUDE_PATH=/opt/local/include:$CPLUS_INCLUDE_PATH
PKG_CXXFLAGS=-I/Users/kuroyanagi/.pyenv/versions/miniconda3-4.3.30/include
LD_LIBRARY_PATH=/opt/local/lib:$LD_LIBRARY_PATH
CXXFLAGS= -g0 -O3 -Wall
MAKE=make -j4
Couple of things:
"Third party header libraries" as in your subject makes no sense.
Third-party headers can work via templated code where headers are all you need, ie there is only an include step and the compiler resolves things.
Once you need libraries and actual linking of object code, you may not be able the powerful and useful sourceCpp
unless you gave it meta-information via plugins (or env. vars).
So in that case, write a package.
Easy and simple things are just that with Rcpp and the new attributes, or the older inline and cxxfunction
. More for complex use --- and external libraries is more complex you need to consult the documentation. We added several vignettes to Rcpp for that.
I was able to link any library (MPFR in this case) by setting two environment variables before calling sourceCpp:
Sys.setenv("PKG_CXXFLAGS"="-I/usr/include")
Sys.setenv("PKG_LIBS"="-L/usr/lib/x86_64-linux-gnu/ -lm -lmpc -lgmp -lmpfr")
The first variable contains the path of the library headers. The second one includes the path of the library binary and its file name. In this case other dependent libraries are also required. For more details check g++ compilation and link flags. This information can usually be obtained using pkg-config:
pkg-config --cflags --libs mylib
For a better understanding, I recommend using sourceCpp with verbose output in order to print the g++ compilation and linking commands:
sourceCpp("mysource.cpp", verbose=TRUE, rebuild=TRUE)