r-lib / roxygen2

Generate R package documentation from inline R comments
https://roxygen2.r-lib.org
Other
590 stars 232 forks source link

NAMESPACE option causes error #833

Closed inmybrain closed 5 years ago

inmybrain commented 5 years ago

I first thank developers for building such a convenient package and debugging it. I recently faced with an error using roxygen2 together with RcppArmadillo.package.skeleton function. I already posted this issue on here, but it seems more appropriate to be answered by this great team =), so I would like to open this issue. It would be great if you could give me any comment on this.

My questions in the post are

  1. what is the error meaning?
  2. why does it work after removing the option .registration=TRUE of useDynLib in NAMESPACE file?

Thanks in advance!

gaborcsardi commented 5 years ago

First, package names cannot contain underscores.

Second, to run roxigenize you need to have a package that roxygen2 can load. It cannot load your package. Your namespace specifies that the package has compiled code, but it does not. R CMD INSTALL fails its loading test as well:

❯ library(roxygen2)
❯ library(RcppArmadillo)
❯ library(Rcpp)
❯ RcppArmadillo.package.skeleton(name = "prac181206", example_code = FALSE)
Calling package.skeleton to create basic package.
Creating directories ...
Creating DESCRIPTION ...
Creating NAMESPACE ...
Creating Read-and-delete-me ...
Saving functions and data ...
Making help files ...
Done.
Further steps are described in './prac181206/Read-and-delete-me'.

Adding RcppArmadillo settings
 >> added Imports: Rcpp
 >> added LinkingTo: Rcpp, RcppArmadillo
 >> added useDynLib and importFrom directives to NAMESPACE
 >> added Makevars file with Rcpp settings
 >> added Makevars.win file with RcppArmadillo settings

❯ roxygenize(package.dir =  "prac181206", roclets = "rd")
First time using roxygen2. Upgrading automatically...
Updating roxygen version in /private/tmp/prac181206/DESCRIPTION
Loading prac181206
Error in getDLLRegisteredRoutines.DLLInfo(dll, addNames = FALSE) :
  must specify DLL via a “DLLInfo” object. See getLoadedDLLs()
In addition: Warning message:
roxygen2 requires Encoding: UTF-8

❯ R CMD INSTALL prac181206
* installing to library ‘/Users/gaborcsardi/R’
* installing *source* package ‘prac181206’ ...
** libs
** help
Warning: /private/tmp/prac181206/man/prac181206-package.Rd:27: All text must be in a section
Warning: /private/tmp/prac181206/man/prac181206-package.Rd:28: All text must be in a section
*** installing help indices
** building package indices
** testing if installed package can be loaded
Error: package or namespace load failed for ‘prac181206’ in library.dynam(lib, package, package.lib):
 shared object ‘prac181206.so’ not found
Error: loading failed
Execution halted
ERROR: loading failed
* removing ‘/Users/gaborcsardi/R/prac181206’

Add a piece of C code that roxygen2 can compile and load and then it will work.

eddelbuettel commented 5 years ago

@gaborcsardi Sorry, but you are incorrect here. I showed in this SO answer that this used to just work with roxygen2 6.0.1 and older. As noted before, I get reliable failures with versions 6.1.0 and 6.1.1.

eddelbuettel commented 5 years ago

To stress, this has nothing to do with whether his tester package does or does not contain src/ (though I happily concede your point that his example is weird in not havng one). But that is totally irrelevant and besides the point here as roxygen2 still fails either way. Witness with the boolean flipped the other way:

edd@rob:/tmp$ r -lRcppArmadillo -e'RcppArmadillo.package.skeleton(name = "prac_181206")'

Calling kitten to create basic package.
Creating directories ...
Creating DESCRIPTION ...
Creating NAMESPACE ...
Creating Read-and-delete-me ...
Saving functions and data ...
Making help files ...
Done.
Further steps are described in './prac_181206/Read-and-delete-me'.

Adding pkgKitten overrides.
Deleted 'Read-and-delete-me'.
Done.

Consider reading the documentation for all the packaging details.
A good start is the 'Writing R Extensions' manual.

And run 'R CMD check'. Run it frequently. And think of those kittens.

Adding RcppArmadillo settings
 >> added Imports: Rcpp
 >> added LinkingTo: Rcpp, RcppArmadillo
 >> added useDynLib and importFrom directives to NAMESPACE
 >> added Makevars file with Rcpp settings
 >> added Makevars.win file with RcppArmadillo settings
 >> added example src file using armadillo classes
 >> added example Rd file for using armadillo classes
 >> invoked Rcpp::compileAttributes to create wrappers
edd@rob:/tmp$ cd prac_181206
edd@rob:/tmp/prac_181206$ Rscript -e 'roxygen2::roxygenize(".", roclets="rd")'
First time using roxygen2. Upgrading automatically...
Updating roxygen version in /tmp/prac_181206/DESCRIPTION
Loading prac_181206
Invalid DESCRIPTION:
Malformed package name

See section 'The DESCRIPTION file' in the 'Writing R Extensions' manual.

Error in getDLLRegisteredRoutines.DLLInfo(dll, addNames = FALSE) : 
  must specify DLL via a “DLLInfo” object. See getLoadedDLLs()
Calls: <Anonymous> ... assignNativeRoutines -> getDLLRegisteredRoutines.DLLInfo
In addition: Warning message:
roxygen2 requires Encoding: UTF-8 
Execution halted
edd@rob:/tmp/prac_181206$ 

Whereas using my little wrapper (which has access to a tucked-away version 6.0.1) it all works:

edd@rob:/tmp/prac_181206$ roxy.r        # an example script from littler
** Using cached version 6.0.1 of roxygen2.
First time using roxygen2. Upgrading automatically...
Loading required package: Rcpp
Warning message:
Version of roxygen2 last used with this package is 6.1.1.  You only have version 6.0.1 
edd@rob:/tmp/prac_181206$ 

And that is our point: the old roxygen2 worked, the current one does not. I happen to have workflows that do not entail devtools or pkgload. And you guys took a working tool away from me. In August. And it still doesn't work. We generally try not to do such things.

gaborcsardi commented 5 years ago

@gaborcsardi Sorry, but you are incorrect here. I showed in this SO answer that this used to just work with roxygen2 6.0.1 and older. As noted before, I get reliable failures with versions 6.1.0 and 6.1.1.

roxygen2 needs to be able to load the package in order to generate the documentation. Bring the package in a state that can be loaded, and then it will work. E.g. run R CMD INSTALL on the directory to create the shared lib.

The 6.0.1 roxygen loading code was buggy, and as a side effect it worked on some broken package trees as well. The new roxygen loading code does not work on these.

To stress, this has nothing to do with whether his tester package does or does not contain src/ (though I happily concede your point that his example is weird in not havng one). But that is totally irrelevant and besides the point here as roxygen2 still fails either way.

Right. If you add src, roxygen still cannot load the package. It also needs the shared lib.

eddelbuettel commented 5 years ago

roxygen still cannot load the package. It also needs the shared lib.

That is an enforced regression. Not roxygen2 version prior to 6.1.0 needed that. In other words it worked for seven years and I still do not see why that existing functionality cannot continue to be provided.

As I said before, all I want from the package is Rd creation. Why would that need shared libraries? Is it not add that this is now a requirement when no roxygen version made between 2011 and 2017 needed it?

gaborcsardi commented 5 years ago

Not roxygen2 version prior to 6.1.0 needed that.

That was a side effect of the buggy loading code.

As I said before, all I want from the package is Rd creation. Why would that need shared libraries?

It needs to load the package to inspect the objects in the package. E.g. to generate the "Usage" section of the documentation. E.g. to generate the manual for the code below you need to evaluate the package code, otherwise you can't tell what g is.

#' ...
f <- function(foo, bar) {

}

#' ...
g <- f

Without evaluating the package code, you can't even tell what objects your package has. To evaluate the package code properly, roxygen2 needs to load the shared libraries, that's just part of loading a package.

eddelbuettel commented 5 years ago

Not always. Look at this where I am currently editing the R file for anytime to update it help page:

edd@rob:~/git/anytime(master)$ roxy.r 
** Using cached version 6.0.1 of roxygen2.
Loading required package: Rcpp
Loading required package: RApiDatetime
Writing anytime.Rd
edd@rob:~/git/anytime(master)$ Rscript -e 'roxygen2::roxygenize(".", roclets="rd")'
Updating roxygen version in /home/edd/git/anytime/DESCRIPTION
Loading anytime
edd@rob:~/git/anytime(master)$ roxy.r 
** Using cached version 6.0.1 of roxygen2.
Loading required package: Rcpp
Loading required package: RApiDatetime
Warning message:
Version of roxygen2 last used with this package is 6.1.1.  You only have version 6.0.1 
edd@rob:~/git/anytime(master)$ 

This package does have src/ yet here it didn't think it needed to compile. I really don't understand why you force the loading of the DLL down. I would love to have a lighterweight mode -- which is why I had started using this package years ago,

gaborcsardi commented 5 years ago

Not always.

Yes, but there is basically no way to automatically tell when.

eddelbuettel commented 5 years ago

Ok, so could we settle on you good folks adding a new option to prevent the dyn.load dance if it appears to be semi-random anyway?

dschuhmacher commented 5 years ago

I stumbled on this discussion, because I got the same Error in getDLLRegisteredRoutines.DLLInfo. My usual workflow uses roxygenize exclusively to create the .Rd files. I was happy to find out that any workaround that first produces a DLL in the src/ of the directory on which I run roxygenize seems to fix the error.

(For me) this is a bit of a nuisance, however. So I wholeheartedly agree with Dirk's suggestion that it would be very nice to have an option for not loading the DLL when running roxygenize or (if you prefer to phrase it that way) an option that reproduces the "buggy" behaviour of the older versions.

david-cortes commented 5 years ago

I would also like to get that old behavior back. In addition, I still don't see why roxygen2 will fail to load a package (and consequently not produce documentation) when devtools's build and install will do it just fine. Now the workflow for me is manually editing the NAMESPACE file to remove compiled code, commenting out the .onLoad function, renaming the src folder before running roxygenize, then reverting the changes back.

hadley commented 5 years ago

Duplicate of #822