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

Serguei Sokol serguei.sokol at gmail.com
Thu Mar 9 10:50:09 CET 2017


Le 08/03/2017 à 17:16, Dirk Eddelbuettel a écrit :
>
> 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.
Right. But in this case I just don't know how as I don't
have plain C-callable functions while module registering mechanisms in Rcpp is
a mystery for me. Should I register my constructors, methods, fields, ... ?
With what names, with what syntax?

I'll wait that the dust settles down with this new registering requirement
and happyly apply new instructions for Rcpp modules in this matter.

Best,
Serguei.

>
> 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
>



More information about the Rcpp-devel mailing list