[Rcpp-devel] Can an Rcpp package include Fortran code?

John Buonagurio jbuonagurio at exponent.com
Thu Oct 6 20:15:47 CEST 2016


On 6 October 2016 at 12:19, Avraham Adler wrote:
| Has anyone successfully created a package that uses Rcpp for C++ code
| and which also has Fortran code? I'm experimenting with comparing
| Fortran and C++ and if I could use Rcpp to handle the C++ portion, it
| would reduce the steepness of the learning curve.
| 
| However, I haven't had success. The following C++ and Fortran snippets
| compile properly separately—the C++ as part of Rcpp and the Fortran
| using R CMD SHLIB and dynload—and the R snippets call them properly,
| but when I put both the .cpp and .f95 files in /src, I get the huge
| error posted below the files.
| 
| Am I missing something simple or will having C++ and Fortran code in
| the same package prevent the use of Rcpp and require the old methods
| of calling compiled code?

Avi,

Take a look at my package 'htdp' for a complete example:

https://github.com/jbuonagurio/RHTDP

Specifically:

src/Makevars
src/RcppHTDP.cpp
src/htdp/htdp.h
src/htdp/README

A few notes:

1. I have a single Fortran file with F95 INCLUDE statements to simplify 
the build, at the cost of incremental linking. You don't have to do 
this, see the 'matrix' package on CRAN for a more complex build example. 

2. Set 'PKG_LIBS = $(FLIBS)' in Makevars to link the appropriate 
libraries (-lgfortran -lquadmath -lm). 

3. Do not use Fortran I/O if you want your package on CRAN (e.g. WRITE, 
STOP). Use the R-only versions of error and warning (REXIT, RWARN). 
These are defined in src/main/xxxpr.f in the R sources. 

4. This package will probably only work with gfortran, which exports all 
symbols with a trailing underscore by default. Make sure your function 
prototypes have the underscore in the header file, with extern "c". 

5. A better and more interoperable way to call Fortran from C/C++ is to 
use ISO_C_BINDING, which lets you pass by value, set number of bytes for 
storage, etc. I originally set up this package to use ISO_C_BINDING, 
however I realized later that earlier versions of gfortran (before GCC 
4.9.3) require explicit interfaces which I didn't want to bother with. 
You probably should. See this older commit for the ISO_C_BINDING version:

<https://github.com/jbuonagurio/RHTDP/commit/5912279aa139b15baa435db2d6e6f78807a707a3> 

6. Don't use .Fortran(). Call the Fortran code from C++, and let Rcpp 
attributes create the .Call() statements for you. 


Dirk/Kevin, please feel free to add/revise!

Best,
John Buonagurio



More information about the Rcpp-devel mailing list