[Rcpp-devel] Symbol registration in packages with module classes

Dirk Eddelbuettel edd at debian.org
Wed Mar 8 17:16:03 CET 2017


On 6 March 2017 at 10:11, Serguei Sokol wrote:
| 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.

Sure -- but that just lets you satisfy the "letter of the law" as you
suppress the messages from R CMD check.

It may be better to satisfy the "spiti of the law" by registering symbols.

Dirk

| 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 at 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 at lists.r-forge.r-project.org
| https://lists.r-forge.r-project.org/cgi-bin/mailman/listinfo/rcpp-devel
-- 
http://dirk.eddelbuettel.com | @eddelbuettel | edd at debian.org


More information about the Rcpp-devel mailing list