Le 04/03/2017 à 20:41, Nathan Russell a écrit :
To summarize an issue I recently encountered,
- Beginning in R 3.4, R CMD check will (likely) expect users to register
symbols for native routines (see e.g. this discussion:
https://github.com/RcppCore/Rcpp/issues/636)
I came across the same issue with the package rmumps and applied a simplified
workaround:
- created an empty init.c (my package has only module export and no
C-callable functions, so tools::package_native_routine_registration_skeleton()
did not help)
8<-------- src/init.c
#include <R.h>
#include <Rinternals.h>
#include <stdlib.h> // for NULL
#include <R_ext/Rdynload.h>
void R_init_rmumps(DllInfo *dll)
{
R_registerRoutines(dll, NULL, NULL, NULL, NULL);
R_useDynamicSymbols(dll, TRUE);
}
8<-------- end of init.c
- in NAMESPACE I have put (note .registration=TRUE):
useDynLib(rmumps, .registration=TRUE)
exportPattern("^[[:alpha:]]+")
import(methods, Rcpp)
# plus some S3 methods I have defined
For now, it keeps silent the check routine of R-devel.
Serguei.
- Generally speaking, the function
tools::package_native_routine_registration_skeleton seems to generate the
appropriate boilerplate code, which can then be
placed in src/init.c to appease R CMD check
- However, packages using Rcpp modules will contain extra symbols of the form
'_rcpp_module_boot_modulename' (resulting from a call to
Rcpp::loadModule("modulename") AFAICT), which do __not__ get picked up by
package_native_routine_registration_skeleton
- Such packages will build correctly, but throw an error when you attempt to
load them:
"Unable to load module "modulename": Failed to initialize module pointer: Error
in FUN(X[[i]], ...):
no such symbol _rcpp_module_boot_modulename in package whatever"
- To fix this, one can manually add corresponding entries to the code generated
by package_native_routine_registration_skeleton, i.e. a declaration
extern SEXP _rcpp_module_boot_modulename(void);
and an entry in the CallEntries array
{"_rcpp_module_boot_modulename", (DL_FUNC) &_rcpp_module_boot_modulename, 0}
----------
If nothing else, I'm just putting this information out in the open for others
who run into this issue. However, if anyone has thoughts on addressing this,
either from the Rcpp side, or by making changes to
tools::package_native_routine_registration_skeleton, or something else, please
chime in.
Nate
----------
Steps to reproduce from a terminal, using the stock Rcpp modules:
cd /tmp
Rscript -e 'Rcpp::Rcpp.package.skeleton("mod", path = "/tmp", module = TRUE);
Rcpp::compileAttributes("mod")'
R CMD build mod && R CMD check --as-cran mod_1.0.tar.gz
# as expected:
# * checking compiled code ... NOTE
# File ‘mod/libs/mod.so’:
# Found no calls to: ‘R_registerRoutines’, ‘R_useDynamicSymbols’
#
# It is good practice to register native routines and to disable symbol
# search.
Rscript -e 'tools::package_native_routine_registration_skeleton("mod")' | tee
mod/src/init.c
# #include <R.h>
# #include <Rinternals.h>
# #include <stdlib.h> // for NULL
# #include <R_ext/Rdynload.h>
#
# /* FIXME:
# Check these declarations against the C/Fortran source code.
# */
#
# /* .Call calls */
# extern SEXP mod_rcpp_hello_world();
#
# static const R_CallMethodDef CallEntries[] = {
# {"mod_rcpp_hello_world", (DL_FUNC) &mod_rcpp_hello_world, 0},
# {NULL, NULL, 0}
# };
#
# void R_init_mod(DllInfo *dll)
# {
# R_registerRoutines(dll, NULL, CallEntries, NULL, NULL);
# R_useDynamicSymbols(dll, FALSE);
# }
R CMD build mod && R CMD check --as-cran mod_1.0.tar.gz
# ...
# * checking whether package ‘mod’ can be installed ... ERROR
# Installation failed.
# See ‘/tmp/mod.Rcheck/00install.out’ for details.
# ...
tail mod.Rcheck/00install.out
# *** installing help indices
# ** building package indices
# ** testing if installed package can be loaded
# Error: package or namespace load failed for ‘mod’ in .doLoadActions(where,
attach):
# error in load action .__A__.1 for package mod: loadModule(module = "NumEx",
what = TRUE, env = ns, loadNow = TRUE):
# Unable to load module "NumEx": Failed to initialize module pointer: Error
in FUN(X[[i]], ...):
# no such symbol _rcpp_module_boot_NumEx in package mod
# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
# Error: loading failed
# Execution halted
# ERROR: loading failed
# * removing ‘/tmp/mod.Rcheck/mod’
grep '^loadModule' mod/R/zzz.R
# loadModule("NumEx", TRUE)
# loadModule("yada", TRUE)
# loadModule("stdVector", TRUE)
# changes
diff -c init.c.old mod/src/init.c
# *** init.c.old2017-03-04 12:40:07.639280221 -0500
# --- mod/src/init.c2017-03-04 12:54:50.295290658 -0500
# ***************
# *** 9,17 ****
# --- 9,23 ----
#
# /* .Call calls */
# extern SEXP mod_rcpp_hello_world();
# + extern SEXP _rcpp_module_boot_NumEx(void);
# + extern SEXP _rcpp_module_boot_yada(void);
# + extern SEXP _rcpp_module_boot_stdVector(void);
#
# static const R_CallMethodDef CallEntries[] = {
# {"mod_rcpp_hello_world", (DL_FUNC) &mod_rcpp_hello_world, 0},
# + {"_rcpp_module_boot_NumEx", (DL_FUNC) &_rcpp_module_boot_NumEx, 0},
# + {"_rcpp_module_boot_yada", (DL_FUNC) &_rcpp_module_boot_yada, 0},
# + {"_rcpp_module_boot_stdVector", (DL_FUNC) &_rcpp_module_boot_stdVector,
0},
# {NULL, NULL, 0}
# };
R CMD build mod && R CMD check --as-cran mod_1.0.tar.gz
# success
# ...
# * checking PDF version of manual ... OK
# * DONE
#
# Status: 1 NOTE
# ^^^^^^ (unrelated)
_______________________________________________
Rcpp-devel mailing list
Rcpp-devel@lists.r-forge.r-project.org
https://lists.r-forge.r-project.org/cgi-bin/mailman/listinfo/rcpp-devel
_______________________________________________
Rcpp-devel mailing list
Rcpp-devel@lists.r-forge.r-project.org
https://lists.r-forge.r-project.org/cgi-bin/mailman/listinfo/rcpp-devel