4

I do not have a ~/.R/Makevars file and

> tools::makevars_user()
character(0)
> tools::makevars_site()
character(0)

Yet, R must be reading the configuration from somewhere as .cpp files containing Rcpp exports in the package src subdirectory compile fine.

I am interested to know how to write a Makefile.win in the src directory so that Rcpp files continue to compile, alongside TMB .cpp files. Currently a makefile like:

all: fn1.dll fn2.dll

fn1.dll: fn1.cpp
    Rscript --vanilla -e "TMB::compile('fn1.cpp')"

fn2.dll: fn2.cpp
    Rscript --vanilla -e "TMB::compile('fn2.cpp')"

clean:
    rm -rf *o

works fine to compile TMB files, and is in fact suggested by: https://github.com/kaskr/adcomp/issues/43

I tried to modify the makefile suggested by Dirk here but had no luck to replicate R's default behaviour even with a fresh new test package.

My session info:

> sessionInfo()
R version 3.3.2 (2016-10-31)
Platform: x86_64-w64-mingw32/x64 (64-bit)
Running under: Windows 7 x64 (build 7601) Service Pack 1
Alex
  • 15,186
  • 15
  • 73
  • 127

1 Answers1

0

I still have no idea how to use Makevars to do what I want, which is to essentially:

  1. Do a normal default make in Rstudio (Windows 7) via Build and Reload package for all Rcpp export files. Under the hood, this calls Rcpp::compileAttributes() then proceeds to run the other package building commands.
  2. Do another make using Rstudio Build and Reload, except now it reads the Makefile that only compiles the TMB code.

However, I do have a work-around. Essentially, the R extensions manual states that:

Something close to the default behavior could be replicated with the following `src/install.libs.R' file:

...

Since, the code to compile the TMB .cpp files are simply R commands, it is easy enough to integrate them into such a file:

# replicate default R
files <- Sys.glob(paste("*", SHLIB_EXT, sep=''))
libarch <- if (nzchar(R_ARCH)) paste('libs', R_ARCH, sep='') else 'libs'
dest <- file.path(R_PACKAGE_DIR, libarch)
dir.create(dest, recursive = TRUE, showWarnings = FALSE)
file.copy(files, dest, overwrite = TRUE)

# now do TMB files
cpp_files <- list.files('./TMB/', full.names = T, pattern = '*.cpp')

for (f in cpp_files) {
    TMB::compile(f)
}

files <- Sys.glob(paste("./TMB/*", SHLIB_EXT, sep=''))
libarch <- if (nzchar(R_ARCH)) paste('libs', R_ARCH, sep='') else 'libs'
dest <- file.path(R_PACKAGE_DIR, libarch)
dir.create(dest, recursive = TRUE, showWarnings = FALSE)
file.copy(files, dest, overwrite = TRUE)

This file reads and compiles all TMP type .cpp files, stored in the sub-directory <pkgdir>/src/TMB, and then copies all subsequent .dlls in <pkgdir>/src/ and <pkgdir>/src/TMB to the installation directory of the package.

Note, it is possible, but possibly very difficult to use Makevars to get a compilation done when the TMB files are stored in a subdirectory. Dirk recommended the example in the matrix package, but I had no luck modifying the code there to do what I want.

Alex
  • 15,186
  • 15
  • 73
  • 127