roxygen2
roxygen2 copied to clipboard
v7.1.0: code-loading pkgload order changed and src compilations fails because NAMESPACE file is missing
Since v7.1.0 out pkg build pipeline fails on step roxygen2::roxygenise()
(devtools::document()
).
because it cannot compile our src files due to missing NAMESPACE file.
Until v7.0.2 roxygen2::roxygenise() created the NAMESPACE file first before compiling the src files with v7.1.0 it seems the oder changed and it tries to compile before creating the NAMESPACE file.
The current workaround is to set Roxygen: list(load = "installed")
but this is not ideal because it assumes that the pkg is installed beforehand. Which is not the default case in our build pipeline.
Can you please create a reprex following the advice at https://github.com/r-lib/roxygen2/blob/master/.github/SUPPORT.md#making-a-reprex ?
OK, try again (my first attempt was bogus). Reprex:
dir.create('foo/R', recursive = TRUE)
dir.create('foo/src', recursive = TRUE)
writeLines(r'(#' Test
#' @useDynLib foo, test_c, .registration = TRUE
#' @export
test = function () .Call(test_c)
)',
'foo/R/foo.r'
)
writeLines(r'(#include "Rinternals.h"
SEXP test_c() {
return R_NilValue;
}
static const R_CallMethodDef methods[] = {
{"test_c", (DL_FUNC) & test_c, 0},
{NULL, NULL, 0}
};
void R_init_lock_env(DllInfo* info) {
R_registerRoutines(info, NULL, methods, NULL, NULL);
R_useDynamicSymbols(info, FALSE);
R_forceSymbols(info, TRUE);
}
)',
'foo/src/foo.c'
)
description = t(as.matrix(c(
Package = 'foo',
Title = 'Foo',
Version = '0.0.9',
Author = 'klmr',
Depends = 'R (>= 3.5.0)',
Suggests = 'roxygen2',
Encoding = 'UTF-8'
)))
write.dcf(description, 'foo/DESCRIPTION')
Using {roxygen2} version 7.2.1 I do not have this issue anymore. @mcsage can you confirm?
I confirm this is still present in 7.2.1 and 7.2.2.
What happens is that the first thing that roxygen2 does is to delete the NAMESPACE file, then, after that, it needs to load the package. To do so, it uses pkgload::load_all, but this one verifies if the package has a src directory, and if so, then checks if something needs to be done to compile it. If it finds (with pkgbuild::needs_compile) that the package already has an so file for the C part, it's happy and it loads the package, so that the NAMESPACE file can be created. However if the needs_compile() returns TRUE, now it needs to build the DLL, which requires the NAMESPACE file, but this file has already been deleted, and then it stops.
This may actually be a duplicate of #1144, which has a fix in flight.
This appears to be fixed by #1538, so that makes me confident that it is indeed a duplicate.