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

Reply via email to