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@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 -- http://dirk.eddelbuettel.com | @eddelbuettel | e...@debian.org _______________________________________________ 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