Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

some packages do not default to binary on Windows #654

Open
agilly opened this issue Jun 25, 2024 · 3 comments
Open

some packages do not default to binary on Windows #654

agilly opened this issue Jun 25, 2024 · 3 comments

Comments

@agilly
Copy link

agilly commented Jun 25, 2024

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 ... doneWill 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
Copy link
Member

gaborcsardi commented Jun 25, 2024

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
Copy link
Author

agilly commented Jun 25, 2024

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 local_install_* 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.

@agilly agilly closed this as completed Jun 25, 2024
@gaborcsardi
Copy link
Member

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants