14

C or C++ code inside subfolders in the src/ for example src/libfoo don't get compiled when I install a package.

When I searched on other questions I found this that mentions Makevars. I searched the Matrix package Makevars. I I thought that I should add:

PKG_LIBS: -Llibfoo

But that didn't work.

I also found that on Writing R Extensions. I added the following to my Makevars and It didn't work either.

SOURCES = $(libfoo/*.c)
OBJECTS = $(SOURCES:.c=.o)

How should I tweak the Makevars file?

Daniel Falbel
  • 1,721
  • 1
  • 21
  • 41
  • Read (and understand) the rest of [Matrix's Makevars](https://github.com/cran/Matrix/blob/master/src/Makevars), and contrast it with the vanilla ones you get from `Rcpp.package.skeleton()` (and used by most Rcpp-using packages). – Dirk Eddelbuettel Mar 28 '18 at 21:54
  • Sorry. I didn't find any `Makevars` file on vanilla `Rcpp.package.skeleton()`. – Daniel Falbel Mar 28 '18 at 21:58
  • Sorry, maybe so vanilla it doesn't need one. Take `RcppArmadillo.package.skeleton()` -- it's a one liner! Whereas the one from Matrix is dozens of lines -- and there is your answer. This is *much* harder. In short: _your_ responsibility `libfoo.a` gets built. – Dirk Eddelbuettel Mar 28 '18 at 21:59
  • Also, generally not just `-Llibfoo` as you need `-l...` too. So maybe `-Llibfoo -lfoo` if there is a `libfoo/libfoo.a`. – Dirk Eddelbuettel Mar 28 '18 at 22:01
  • Alright! Thanks, will try that! – Daniel Falbel Mar 28 '18 at 22:09
  • This is somewhat of an old post by now, and (incridibly) still one that gives life to a lot of confusion. This [github-repo](https://github.com/r-pkg-examples/rcpp-headers-subdirs) has an example of automatic inclusion for subdirectories, for anyone (like me) stumbling upon this in the future. – Oliver Jan 02 '21 at 19:43

1 Answers1

10

It ended up working by setting:

SOURCES = $(wildcard libfoo/*.c)
OBJECTS = foo.o RcppExports.o $(SOURCES:.c=.o)

The really mysterious part for me is the wildcard when defining the SOURCES.

Daniel Falbel
  • 1,721
  • 1
  • 21
  • 41
  • 2
    If it works it is good enough :) This is a seriously underdocumented corner, and it is generally recommended (on r-devel or r-package-devel) to do the least possible to not get into the way of R. And least-possible is what you did here: your sources go straight into the main shared library as if they'd been in `src/` all along. – Dirk Eddelbuettel Mar 29 '18 at 14:05
  • 2
    Check though if `wildcard` is permitted or if you are now in the "oh dear it is a GNU make extension" corner (which you can settle via `SystemRequirements:` if need be, – Dirk Eddelbuettel Mar 29 '18 at 14:06
  • Thanks for this! I found a version elsewhere that omitted `RcppExports.o` from `OBJECTS`. Everything compiled/loaded fine, but I got the dreaded "function not available for .Call" error at runtime. This version works perfectly. – dbaston Jun 06 '18 at 21:10
  • This worked for me after removing `foo.o RcppExports.o`. Presumably these are object files created by other C files in the root `src` directory? – Martin Smith Jul 02 '21 at 14:51