This issue is currently a place that I'll dump my notes about the investigation of this problem, and also thoughts about possible workarounds.
What R does
R 3.6.0, install binary from remote repo, or from a local ZIP file
-
Staged installation does not matter here.
-
If the package is loaded in the current R session, installations is refused with a warning:
> install.packages("curl")
Installing package into ‘C:/Users/Gabor/Documents/R/win-library/3.6’
(as ‘lib’ is unspecified)
Warning: package ‘curl’ is in use and will not be installed
- Now if we unload the package, but not the DLL, then we get a warning and a broken package is left around, i.e. only the dll is there, the rest is removed:
> unloadNamespace("curl")
> install.packages("curl")
Installing package into ‘C:/Users/Gabor/Documents/R/win-library/3.6’
(as ‘lib’ is unspecified)
trying URL 'https://cloud.r-project.org/bin/windows/contrib/3.6/curl_3.3.zip'
length 2996751 bytes (2.9 MB)
downloaded 2.9 MB
package ‘curl’ successfully unpacked and MD5 sums checked
Warning: cannot remove prior installation of package ‘curl’
The downloaded binary packages are in
C:\Users\Gabor\AppData\Local\Temp\Rtmp2JeKkE\downloaded_packages
> library(curl)
Error in library(curl) : there is no package called ‘curl’
- The same happens in the package is loaded in another R session. Note that even if we install the exact same binary, we'll end up with a broken installation.
R 3.6.0, install source from remote repo, or from local tar.gz file, or from a local directory
- If the package is loaded in the current session, R still tries to install it. With the default staged install, moving the package to its final place produces a warning, but the installation still continues, and then the load-test fails, and the originally installed package is restored. So for some time the library contains a broken package. Finally, the
install.packages() call gives a warning that the installation had a non-zero exit status:
** testing if installed package can be loaded from temporary location
*** arch - i386
*** arch - x64
WARNING: moving package to final location failed, copying instead
Warning in file.copy(instdir, dirname(final_instdir), recursive = TRUE, :
problem copying C:\Users\Gabor\Documents\R\win-library\3.6\00LOCK-curl\00new\curl\libs\x64\curl.dll to C:\Users\Gabor\Documents\R\win-library\3.6\curl\libs\x64\curl.dll: Permission denied
** testing if installed package can be loaded from final location
*** arch - i386
*** arch - x64
Error: package or namespace load failed for 'curl' in FUN(X[[i]], ...):
no such symbol R_new_file_writer in package C:/Users/Gabor/Documents/R/win-library/3.6/curl/libs/x64/curl.dll
Error: loading failed
Execution halted
ERROR: loading failed for 'x64'
* removing 'C:/Users/Gabor/Documents/R/win-library/3.6/curl'
* restoring previous 'C:/Users/Gabor/Documents/R/win-library/3.6/curl'
Warning in file.copy(lp, dirname(pkgdir), recursive = TRUE, copy.date = TRUE) :
problem copying C:\Users\Gabor\Documents\R\win-library\3.6\00LOCK-curl\curl\libs\x64\curl.dll to C:\Users\Gabor\Documents\R\win-library\3.6\curl\libs\x64\curl.dll: Permission denied
The downloaded source packages are in
‘C:\Users\Gabor\AppData\Local\Temp\Rtmp4EIpFM\downloaded_packages’
Warning message:
In install.packages("curl", type = "source") :
installation of package ‘curl’ had non-zero exit status
-
The same happens if the package is loaded in another session.
-
If the already installed package is of the same version as the one being installed, then the load-test succeeds and you only get the warnings about the failed move and the failed copy:
** testing if installed package can be loaded from temporary location
*** arch - i386
*** arch - x64
WARNING: moving package to final location failed, copying instead
Warning in file.copy(instdir, dirname(final_instdir), recursive = TRUE, :
problem copying C:\Users\Gabor\Documents\R\win-library\3.6\00LOCK-curl\00new\curl\libs\x64\curl.dll to C:\Users\Gabor\Documents\R\win-library\3.6\curl\libs\x64\curl.dll: Permission denied
** testing if installed package can be loaded from final location
*** arch - i386
*** arch - x64
** testing if installed package keeps a record of temporary installation path
* DONE (curl)
- If the already installed package is not of the same version as the one being installed, but they are close enough for the load-test to succeed, then you get a package that looks OK, but essentially has undefined behavior: it may crash, it may freeze, it may fail, or produce the wrong results. :(
R 3.6.0, non-staged install, source from repo
The end result is the same as for staged install, although the warnings are slightly different. If the load-test fails, then we only get the warning about the failed copy of the DLL file.
** testing if installed package can be loaded
*** arch - i386
*** arch - x64
Error: package or namespace load failed for 'curl' in FUN(X[[i]], ...):
no such symbol R_new_file_writer in package C:/Users/Gabor/Documents/R/win-library/3.6/curl/libs/x64/curl.dll
Error: loading failed
Execution halted
ERROR: loading failed for 'x64'
* removing 'C:/Users/Gabor/Documents/R/win-library/3.6/curl'
* restoring previous 'C:/Users/Gabor/Documents/R/win-library/3.6/curl'
Warning in file.copy(lp, dirname(pkgdir), recursive = TRUE, copy.date = TRUE) :
problem copying C:\Users\Gabor\Documents\R\win-library\3.6\00LOCK-curl\curl\libs\x64\curl.dll to C:\Users\Gabor\Documents\R\win-library\3.6\curl\libs\x64\curl.dll: Permission denied
The downloaded source packages are in
‘C:\Users\Gabor\AppData\Local\Temp\RtmpIlhhOz\downloaded_packages’
Warning message:
In install.packages("curl", type = "source") :
installation of package ‘curl’ had non-zero exit status
What pkginstall does currently
pkginstall only installs binary packages. To install a source package, needs to be R CMD build-t first, and then pkginstall extracts the binary, and install the extracted binary:
This is the current code:
https://github.com/r-lib/pkginstall/blob/0ca61acc1028e1f8d399bbb175824219bcee12e5/R/install_binary.R#L51-L92
In a nutshell:
- First move the existing package dir to a temporary place. This works even if a process has the DLL open. If the move fails, it aborts.
- Then tries to delete the moved dir, which may fail if another process as the file open. If it fails, it gives a warning.
- Then it tries to move the extracted new package into the library. If this fails, then it aborts.
This issue is currently a place that I'll dump my notes about the investigation of this problem, and also thoughts about possible workarounds.
What R does
R 3.6.0, install binary from remote repo, or from a local ZIP file
Staged installation does not matter here.
If the package is loaded in the current R session, installations is refused with a warning:
R 3.6.0, install source from remote repo, or from local tar.gz file, or from a local directory
install.packages()call gives a warning that the installation had a non-zero exit status:The same happens if the package is loaded in another session.
If the already installed package is of the same version as the one being installed, then the load-test succeeds and you only get the warnings about the failed move and the failed copy:
R 3.6.0, non-staged install, source from repo
The end result is the same as for staged install, although the warnings are slightly different. If the load-test fails, then we only get the warning about the failed copy of the DLL file.
What pkginstall does currently
pkginstall only installs binary packages. To install a source package, needs to be
R CMD build-t first, and then pkginstall extracts the binary, and install the extracted binary:This is the current code:
https://github.com/r-lib/pkginstall/blob/0ca61acc1028e1f8d399bbb175824219bcee12e5/R/install_binary.R#L51-L92
In a nutshell: