pak 0.6.0

  Gábor Csárdi

We’re delighted to announce the release of pak 0.6.0. pak helps with the installation of R packages and many related tasks.

You can install pak from CRAN with:

If you use an older R version, or a platform that CRAN does not have binary packages for, it is faster and simpler to install pak from our repository. See the details in the manual.

This blog post focuses on the exciting new improvements in the matching and installation of system requirements on Linux systems.

You can see a full list of changes in the release notes

System requirements

Many R packages require the installation of external software, otherwise they do not work, or even load. For example, the RPostgres R package requires the PostgreSQL client library, and by default dynamically links to it on Linux systems. This means that you (or the administrators of your system) need to install this library, typically in the form of a system package: libpq-dev on Ubuntu and Debian systems, or postgresql-server-devel or postgresql-devel on Red Hat, Fedora, etc. systems.

The good news is that pak now helps you with this:

  • it looks up the required system packages when installing R packages,
  • it lets you know if any required system packages are missing from your system, before the installation, and
  • it installs them automatically, if you are a superuser, or if you can use password-less sudo to start a superuser shell.

In addition, pak now also has some functions to query system requirements and system packages.

Supported platforms

pak 0.6.0 supports the following Linux systems currently:

  • Ubuntu Linux,
  • Debian Linux,
  • Red Hat Enterprise Linux,
  • SUSE Linux Enterprise,
  • OpenSUSE,
  • CentOS,
  • Rocky Linux,
  • Fedora Linux.

Call pak::sysreqs_platforms() to query the current list of supported platforms:

pak::sysreqs_platforms()[,1:3]
#>                        name    os distribution
#> 1              Ubuntu Linux linux       ubuntu
#> 2              Debian Linux linux       debian
#> 3              CentOS Linux linux       centos
#> 4               Rocky Linux linux   rockylinux
#> 5  Red Hat Enterprise Linux linux       redhat
#> 6  Red Hat Enterprise Linux linux       redhat
#> 7  Red Hat Enterprise Linux linux       redhat
#> 8              Fedora Linux linux       fedora
#> 9            openSUSE Linux linux     opensuse
#> 10    SUSE Linux Enterprise linux          sle

Call pak::system_r_platform() to check if pak has detected your platform correctly, and pak::sysreqs_is_supported() to see if it is supported:

pak::system_r_platform()
#> [1] "x86_64-pc-linux-gnu-ubuntu-22.04"
pak::sysreqs_is_supported()
#> [1] TRUE

R package installation

If you are using pak as the root user, on a supported platform, then during package installation pak will look up the required system packages, and will install the missing ones. Here is an example:

pak::pkg_install("RPostgres")
#> i Loading metadata databasev Loading metadata database ... done
#>  
#> > Will install 12 packages.
#> > Will download 12 packages with unknown size.
#> + DBI          1.1.3  [dl]
#> + RPostgres    1.4.5  [dl] + x libpq-dev
#> + Rcpp         1.0.11 [dl]
#> + bit          4.0.5  [dl]
#> + bit64        4.0.5  [dl]
#> + blob         1.2.4  [dl]
#> + generics     0.1.3  [dl]
#> + hms          1.1.3  [dl]
#> + lubridate    1.9.2  [dl]
#> + pkgconfig    2.0.3  [dl]
#> + timechange   0.2.0  [dl]
#> + withr        2.5.0  [dl]
#> > Will install 1 system package:
#> + libpq-dev  - RPostgres
#> i Getting 12 pkgs with unknown sizes
#> v Got blob 1.2.4 (x86_64-pc-linux-gnu-ubuntu-22.04) (45.94 kB)
#> v Got generics 0.1.3 (x86_64-pc-linux-gnu-ubuntu-22.04) (76.24 kB)
#> v Got hms 1.1.3 (x86_64-pc-linux-gnu-ubuntu-22.04) (98.35 kB)
#> v Got RPostgres 1.4.5 (x86_64-pc-linux-gnu-ubuntu-22.04) (455.11 kB)
#> v Got bit64 4.0.5 (x86_64-pc-linux-gnu-ubuntu-22.04) (475.41 kB)
#> v Got pkgconfig 2.0.3 (x86_64-pc-linux-gnu-ubuntu-22.04) (17.58 kB)
#> v Got timechange 0.2.0 (x86_64-pc-linux-gnu-ubuntu-22.04) (169.26 kB)
#> v Got DBI 1.1.3 (x86_64-pc-linux-gnu-ubuntu-22.04) (759.31 kB)
#> v Got withr 2.5.0 (x86_64-pc-linux-gnu-ubuntu-22.04) (228.73 kB)
#> v Got bit 4.0.5 (x86_64-pc-linux-gnu-ubuntu-22.04) (1.13 MB)
#> v Got lubridate 1.9.2 (x86_64-pc-linux-gnu-ubuntu-22.04) (980.37 kB)
#> v Got Rcpp 1.0.11 (x86_64-pc-linux-gnu-ubuntu-22.04) (2.15 MB)
#> i Installing system requirements
#> i Executing `sh -c apt-get -y update`
#> i Executing `sh -c apt-get -y install libpq-dev`
#> v Installed DBI 1.1.3  (1.1s)
#> v Installed RPostgres 1.4.5  (1.1s)
#> v Installed Rcpp 1.0.11  (1.2s)
#> v Installed bit 4.0.5  (1.2s)
#> v Installed bit64 4.0.5  (126ms)
#> v Installed blob 1.2.4  (86ms)
#> v Installed generics 0.1.3  (83ms)
#> v Installed hms 1.1.3  (59ms)
#> v Installed lubridate 1.9.2  (1.1s)
#> v Installed pkgconfig 2.0.3  (1.1s)
#> v Installed timechange 0.2.0  (63ms)
#> v Installed withr 2.5.0  (1.1s)
#> v 1 pkg + 16 deps: kept 5, added 12, dld 12 (6.58 MB) [17.1s]

Running R as a regular user

If you don’t want to use R as the superuser, but you can set up sudo without a password, that works as well. pak will detect the password-less sudo capability, and use it to install system packages, as needed.

If you run R as a regular (not root) user, and password-less sudo is not available, then pak will print the system requirements, but it will not try to install or update them.

If you are compiling R packages from source, and they need to link to system libraries, then their installation will probably fail, until you install these system packages.

If you are installing binary R packages (e.g. from P3M), then the installation typically succeeds, but you won’t be able to load these packages into R, until you install the required system packages.

To demonstrate this, let’s remove the system package for the PostgreSQL client library:

system("apt-get remove -y libpq5")

If now we (re)install the binary RPostgres R package, the installation will succeed, but then library() fails because of the missing system package. (We will fix the broken R package below.)

#> i Loading metadata databasev Loading metadata database ... done
#>  
#> > Will install 1 package.
#> > Will download 1 package with unknown size.
#> + RPostgres   1.4.5 [dl] + x libpq-dev
#> x Missing 1 system package. You'll probably need to install it manually:
#> + libpq-dev  - RPostgres
#> i Getting 1 pkg with unknown size
#> v Cached copy of RPostgres 1.4.5 (x86_64-pc-linux-gnu-ubuntu-22.04) is the latest build
#> v Installed RPostgres 1.4.5  (1.1s)
#> v 1 pkg + 16 deps: kept 16, added 1 [5.7s]
library(RPostgres)
#> Error: package or namespace load failed for 'RPostgres' in dyn.load(file, DLLpath = DLLpath, ...):
#>  unable to load shared object '/root/R/x86_64-pc-linux-gnu-library/4.3/RPostgres/libs/RPostgres.so':
#>   libpq.so.5: cannot open shared object file: No such file or directory
#> Execution halted

Opting out

If you don’t want pak to install system packages for you, set the PKG_SYSREQS environment variable to false, or the pkg.sysreqs option to FALSE. See the complete list of configuration options in the config?pak manual page.

System requirements queries

pak 0.6.0 also has a number of functions to query system requirements and system packages. The pak::pkg_sysreqs() function is similar to pak::pkg_deps() but in addition to looking up package dependencies, it also looks up system dependencies, and only reports the latter:

pak::pkg_sysreqs(c("curl", "r-lib/xml2", "devtools", "CHRONOS"))
#> i Loading metadata databasev Loading metadata database ... done
#> -- Install scripts --------------------------------------------- Ubuntu 22.04 --
#> apt-get -y update
#> apt-get -y install libcurl4-openssl-dev libssl-dev git make libgit2-dev \
#>   zlib1g-dev pandoc libfreetype6-dev libjpeg-dev libpng-dev libtiff-dev \
#>   libicu-dev libfontconfig1-dev libfribidi-dev libharfbuzz-dev libxml2-dev \
#>   libglpk-dev libgmp3-dev default-jdk
#> R CMD javareconf
#> R CMD javareconf
#> 
#> -- Packages and their system dependencies --------------------------------------
#> CHRONOS     -- default-jdk, pandoc
#> credentials -- git
#> curl        -- libcurl4-openssl-dev, libssl-dev
#> fs          -- make
#> gert        -- libgit2-dev
#> gitcreds    -- git
#> httpuv      -- make, zlib1g-dev
#> igraph      -- libglpk-dev, libgmp3-dev, libxml2-dev
#> knitr       -- pandoc
#> openssl     -- libssl-dev
#> pkgdown     -- pandoc
#> png         -- libpng-dev
#> ragg        -- libfreetype6-dev, libjpeg-dev, libpng-dev, libtiff-dev
#> RCurl       -- libcurl4-openssl-dev, make
#> remotes     -- git
#> rJava       -- default-jdk, make
#> rmarkdown   -- pandoc
#> sass        -- make
#> stringi     -- libicu-dev
#> systemfonts -- libfontconfig1-dev, libfreetype6-dev
#> textshaping -- libfreetype6-dev, libfribidi-dev, libharfbuzz-dev
#> XML         -- libxml2-dev
#> xml2        -- libxml2-dev

See the manual of pak::pkg_sysreqs() to learn how to programmatically extract information from its return value.

pak::sysreqs_check_installed() is a handy function that checks if all system requirements are installed for some or all R packages in your library. This should report our broken RPostgres package:

pak::sysreqs_check_installed()
#> system package installed required by
#> -------------- --        -----------
#> libpq-dev      x         RPostgres

pak::sysreqs_fix_installed() goes one step further and also tries to install the missing system requirements:

pak::sysreqs_fix_installed()
#> i Need to install 1 system package.
#> i Installing system requirements
#> i Executing `sh -c apt-get -y update`
#> i Executing `sh -c apt-get -y install libpq-dev`

Now we can load RPostgres again:

Configuration

There are several pak configuration options you can use to adjust how system requirements are handled. See the complete list in the config?pak manual page.

More information

Acknowledgements

A big thank you to all those who have contributed to pak, or one of its workhorse packages since the v0.5.1 release:

@alexpate30, @averissimo, @ArnaudKunzi, @billdenney, @Darxor, @drmowinckels, @Fan-iX, @gongyh, @hadley, @idavydov, @jefferis, @joan-yanqiong, @kevinushey, @kkmann, @klmr, @krlmlr, @lgaborini, @maelle, @maxheld83, @maximsmol, @michaelmayer2, @mine-cetinkaya-rundel, @olivroy, @pascalgulikers, @pawelru, @royfrancis, @tanho63, @thomasyu888, @vincent-hanlon, and @VincentGuyader.