I\'m trying to run devtools::install_github(\"gaborcsardi/notifier\")
but R does not appear to be properly recognizing RTools; which is located in C:\\Rto
There is a standalone mode in remotes
. This mode removes the dependency on pkgbuild
that was the proximate cause of the error (the ultimate problem is much deeper in the call chain).
This is documented in the remotes package readme.
You can force remotes
to use the standalone mode with
Sys.setenv(R_REMOTES_STANDALONE="true")
This solution found thank to gaborcsardi
It's not uncommon for utilities (in R or other languages/tools) to be able to deal with simple file paths and schema-based URLs (e.g., https://...
or file:///...
), I think the number of tools that equally deal with Windows' UNC paths (i.e., \\server\share\path
) is much less. While I believe that R is doing it just fine for finding the files (otherwise you'd have other problems by having your only two .libPaths()
be UNC shares), the underlying tools (including gcc
) might not.
I think the way-forward is to install the new package(s) into a directory that is not a network share. I also think this can be a temporary location, where the packages, once installed, can be moved/migrated over to the network share.
Below is a function that simplifies creation of a temporary directory, install to that directory, then move to the network share. (It doesn't actually check if the tgt
directory is a network share, the assumption is that you would not need to use this is your first library path is local.)
#' Install a package(s) using a temp-local directory
#'
#' On Windows, if '.libPaths()' starts with a UNC network share,
#' package compilation might not work correctly. This function creates
#' a temporary local directory, executes the desired code in 'expr',
#' and moves any new packages into the normal first library path.
#'
#' @param expr expression such as 'install.packages("car")' or
#' 'devtools::install_github(...)'; the expression must natively
#' install into the first of '.libPaths()', but if you try something
#' like 'install.packages(.., lib="some/other/path"), then the
#' temporary libpath will not be used (and may fail)
#' @param tgt character, the directory to move the isntalled
#' package(s)
#' @param cleanup logical, whether to remove the temporary libpath
#' @return nothing
with_local_libpath <- function(expr, tgt = .libPaths()[1], cleanup = TRUE) {
if (length(tgt) > 1) {
warning("'tgt' must be length 1")
tgt <- tgt[[1]]
}
if (length(tgt) < 1 || !dir.exists(tgt)) {
stop("'tgt' must be length 1 and an existing directory")
}
dir.create(tmplib <- tempfile(pattern = "local_libpath_"))
message("Local (temp) libpath: ", sQuote(tmplib))
oldlib <- .libPaths()
.libPaths(c(tmplib, oldlib))
on.exit(.libPaths(oldlib), add = TRUE)
force(expr)
newstuff <- list.files(tmplib, full.names = TRUE)
if (length(newstuff)) {
newdirs <- file.path(oldlib[1], basename(newstuff))
message("New packages found: ", paste(sQuote(basename(newstuff)), collapse = ", "))
message("Moving to: ", sQuote(tgt))
file.copy(newstuff, tgt, recursive = TRUE)
if (cleanup) {
message("Cleaning up")
unlink(tmplib, recursive = TRUE)
}
} else {
message("No new packages found (?)")
}
invisible()
}
I tested this with some simple examples, but not extensively, so caveat emptor. I don't have a network-mounted lib-path, so I'll force one (to a server I maintain):
.libPaths(c("\\\\myserver/r2evans/R/win.library/3.5", .libPaths()))
Failing installation:
remotes::install_github("gaborcsardi/notifier@d92b1b6")
# Downloading GitHub repo gaborcsardi/notifier@d92b1b6
# v checking for file 'C:\Users\r2\AppData\Local\Temp\RtmpWgKbkW\remotes43cc57193c83\gaborcsardi-notifier-d92b1b6/DESCRIPTION' (377ms)
# - preparing 'notifier':
# v checking DESCRIPTION meta-information
# - checking for LF line-endings in source and make files and shell scripts
# - checking for empty or unneeded directories
# - building 'notifier_1.0.0.tar.gz'
#
# Installing package into '\\myserver/r2evans/R/win.library/3.5'
# (as 'lib' is unspecified)
# * installing *source* package 'notifier' ...
# ** R
# ** inst
# Error in file.create(to[okay]) :
# (converted from warning) cannot create file '\myserver/r2evans/R/win.library/3.5/notifier/R.ico', reason 'No such file or directory'
# * removing '\\myserver/r2evans/R/win.library/3.5/notifier'
# In R CMD INSTALL
# Error: Failed to install 'notifier' from GitHub:
# (converted from warning) installation of package 'C:/Users/r2/AppData/Local/Temp/RtmpWgKbkW/file43cc60c05cc/notifier_1.0.0.tar.gz' had non-zero exit status
(I chose a specific version because of https://github.com/gaborcsardi/notifier/issues/22. While the error is different than your error, I suspect that the failure is for a similar/related reason.)
Successful installation:
with_local_libpath(remotes::install_github("gaborcsardi/notifier@d92b1b6"))
# Local (temp) libpath: 'C:\Users\r2\AppData\Local\Temp\RtmpWgKbkW\local_libpath_43ccbf98e2'
# Downloading GitHub repo gaborcsardi/notifier@d92b1b6
# v checking for file 'C:\Users\r2\AppData\Local\Temp\RtmpWgKbkW\remotes43cc7cb66d1f\gaborcsardi-notifier-d92b1b6/DESCRIPTION' (396ms)
# - preparing 'notifier':
# v checking DESCRIPTION meta-information
# - checking for LF line-endings in source and make files and shell scripts
# - checking for empty or unneeded directories
# - building 'notifier_1.0.0.tar.gz'
#
# Installing package into 'C:/Users/r2/AppData/Local/Temp/RtmpWgKbkW/local_libpath_43ccbf98e2'
# (as 'lib' is unspecified)
# * installing *source* package 'notifier' ...
# ** R
# ** inst
# ** byte-compile and prepare package for lazy loading
# ** help
# *** installing help indices
# converting help for package 'notifier'
# finding HTML links ... done
# notify html
# ** building package indices
# ** testing if installed package can be loaded
# *** arch - i386
# *** arch - x64
# * DONE (notifier)
# In R CMD INSTALL
# New packages found: 'notifier'
# Moving to: '\\myserver/r2evans/R/win.library/3.5'
# Cleaning up