r-lib / pak

A fresh approach to package installation
https://pak.r-lib.org
639 stars 56 forks source link

some packages do not default to binary on Windows #654

Open agilly opened 6 days ago

agilly commented 6 days ago

Possibly related to #613.

I see an installation error when trying to install imager on R for Windows 4.2.0 (note: in my setting it is difficult to upgrade R otherwise I would).

The result of install.packages:

> install.packages("imager")
--- Please select a CRAN mirror for use in this session ---

  There is a binary version available but the source version is later:
       binary source needs_compilation
imager 0.45.8  1.0.2              TRUE

  Binaries will be installed
trying URL 'https://cloud.r-project.org/bin/windows/contrib/4.2/imager_0.45.8.zip'
Content type 'application/zip' length 9121823 bytes (8.7 MB)
downloaded 8.7 MB

package 'imager' successfully unpacked and MD5 sums checked

The downloaded binary packages are in
        C:\Users\R. Tidi Victor\AppData\Local\Temp\RtmpUTqvQU\downloaded_packages

I can use the package successfully after this. However, my setup stack uses pak to install missing packages. I successfully install pak 0.7.2:

        install.packages("pak", repos = sprintf(
        "https://r-lib.github.io/p/pak/stable/%s/%s/%s",
        .Platform$pkgType,
        R.Version()$os,
        R.Version()$arch
        ))

However, when I ask it for imager:

> pak::pkg_install("imager")
✔ Loading metadata database ... done

→ Will install 20 packages.
→ Will download 20 CRAN packages (36.80 MB).
+ bmp          0.3    [dl] (120.69 kB)
+ cli          3.6.2  [dl] (1.34 MB)
+ digest       0.6.35 [dl] (215.55 kB)
+ downloader   0.4    [dl] (25.06 kB)
+ glue         1.7.0  [dl] (160.67 kB)
+ igraph       2.0.3  [dl] (7.27 MB)
+ imager       1.0.2  [bld][cmp][dl] (4.48 MB)
+ jpeg         0.1-10 [dl] (133.21 kB)
+ lifecycle    1.0.4  [dl] (139.75 kB)
+ magrittr     2.0.3  [dl] (227.09 kB)
+ pkgconfig    2.0.3  [dl] (22.20 kB)
+ png          0.1-8  [dl] (190.85 kB)
+ purrr        1.0.2  [dl] (499.90 kB)
+ Rcpp         1.0.12 [dl] (2.82 MB)
+ readbitmap   0.1.5  [dl] (20.10 kB)
+ rlang        1.1.3  [dl] (1.58 MB)
+ stringi      1.8.3  [dl] (15.01 MB)
+ stringr      1.5.1  [dl] (318.73 kB)
+ tiff         0.1-12 [dl] (902.85 kB)
+ vctrs        0.6.5  [dl] (1.34 MB)
ℹ Getting 20 pkgs (36.80 MB)

[...all dependencies download and install...]

✔ Installed vctrs 0.6.5  (5.1s)
✔ Installed Rcpp 1.0.12  (6.7s)
ℹ Building imager 1.0.2
Error: 
! error in pak subprocess
Caused by error:
! Could not find tools necessary to compile a package
Call `pkgbuild::check_build_tools(debug = TRUE)` to diagnose the problem.
ℹ See `$stderr` for standard error.
Type .Last.error to see the more details.

Note the [bld][cmp][dl] next to imager in the list. I thought from the help page that even if a source exists and is newer than the binary (the case for imager) it will default to the binary. However here it seems to try and build the source. For the same admin reasons as above it is not practical for me to install Rtools. Is this a bug?

I can circumvent the whole thing by forcing the download of the binary:

pak::pkg_install("pkgdepends")
        plat=pkgdepends::default_platforms()
        # remove source
        plat=setdiff(plat, "source")
        location=pak::pkg_download("imager", platforms=plat)
        location=location$fulltarget
        pak::pkg_install(glue::glue("local::{location}"))

which gives:

✔ Loading metadata database ... done
ℹ Getting 1 pkg (9.12 MB)
✔ Got imager 0.45.8 (x86_64-w64-mingw32) (9.12 MB)
✔ Downloaded 1 package (9.12 MB) in 991ms
! Optional package `pillar` is not available for pak.
  Use `pak::pak_install_extra()` to install optional packages.
  Use `options(pak.no_extra_messages = TRUE)` to suppress this message.
→ Will install 1 package.
→ Will download 1 package with unknown size.
+ imager   0.45.8 [cmp][dl]
ℹ Getting 1 pkg with unknown size
✔ Got imager 0.45.8 (x86_64-w64-mingw32) (9.12 MB)
✔ Downloaded 1 package (9.12 MB) in 130ms
✔ Installed imager 0.45.8 (local) (343ms)
✔ 1 pkg + 21 deps: kept 15, added 1, dld 1 (9.12 MB) [1.3s]

However, this feels clumsy. Any thoughts?

gaborcsardi commented 6 days ago

The default policy is to always install the latest versions of the packages specified directly, and the most convenient versions of the dependencies. So

pak::pkg_install("imager")

will always try to install the latest version of imager.

One way to work around it is to use the any:: (virtual) package source, which will default to the most convenient version:

pak::pkg_install("any::imager")
→ Will install 1 package.
→ Will download 1 CRAN package (9.12 MB).
+ imager   0.45.8 [dl] (9.12 MB)
ℹ Getting 1 pkg (9.12 MB)
✔ Got imager 0.45.8 (x86_64-w64-mingw32) (9.12 MB)
✔ Downloaded 1 package (9.12 MB) in 1.7s
✔ Installed imager 0.45.8  (371ms)
✔ 1 pkg + 21 deps: kept 12, added 1, dld 1 (9.12 MB) [3.6s]
agilly commented 5 days ago

Thanks for the prompt reply, that solves it. I was looking at the FAQ of V 0.7.2, and it does suggest that pak will choose a binary over a source even if the latter is more recent, although rereading that section it does say that this behavior is only for dependencies of packages to be installed.

From the FAQ:

How do I install a dependency from a binary package:

Sometimes it is sufficient to install the binary package of an older version of a dependency, instead of the newer source package that potentially needs compilers, system tools or libraries. pkg_install() and lockfile_create() default to upgrade = FALSE, which always chooses binaries over source packages, so if you use pkg_install() you don’t need to do anything extra. The localinstall* functions default to upgrade = TRUE, as does pak() with pkg = NULL, so for these you need to explicitly use upgrade = FALSE.

I agree that the behavior can be deduced, but it may be good to state somewhere explicitly that if the latest version of a package exists only as a source, the source will be chosen over the binary, along with the above method to override that behavior. I am guessing that R deployments without Rtools on Windows are not entirely uncommon, and this may be helpful?

Just a suggestion & food for thought. Thanks for solving the issue.

gaborcsardi commented 5 days ago

If you don't mind, I'll leave this open until the docs are fixed.