Pautas de empaquetamiento de R

R es un lenguaje y entorno para cálculo de estadística y gráficas. R es similar al sistema S galardonado, el cual era desarrollado en los Laboratorios Bell por John Chambers et al. Proporciona una variedad amplia de estadísticas y técnicas de gráficas (modelo lineal y no lineal, pruebas estadísticass, análisis de series de tiempo, clasificación, racimos, …​).

R está diseñado como un auténtico lenguaje de programación con construcciones de flujo de control para iteración y alternancia, y permite a los usuarios añadir funcionalidad mediante la definición de funciones nuevas. Para tareas de alto consumo computacional, se puede enlazar e invocar código C, C++ y Fortran en tiempo de ejecución. Para más información, consulte la Introducción a R.

Este documento explica cómo gestionar los paquetes complementarios de R para su inclusión en los repositorios de Fedora. Para ver un ejemplo completo, consulte el «Archivo de especificaciones de ejemplo» a continuación.

Nombrando

La fuente canónica de los paquetes de R es CRAN, la «Red Integral de Archivos de R». Existen repositorios adicionales similares a CRAN para campos específicos, como Bioconductor (Bioc para abreviar) para bioinformática. Sin embargo, dado que están diseñados para complementarse, los nombres de los paquetes no entran en conflicto entre sí.

R add-ons MUST be packaged with R-$pkg as the name of the source package, where $pkg is the name of the project on the upstream CRAN-like repository, i.e. the package DESCRIPTION's Package field. This $pkg name MUST be exactly as written upstream, including case distinctions and dots. Also:

  • The spec’s Summary field SHOULD match the package DESCRIPTION’s Title field.

  • The spec’s Description field SHOULD match the package DESCRIPTION’s Description field.

Versioning

Since upstream versions may contain characters that are invalid in RPM version strings, they MUST be translated to be RPM-compatible. Particularly, it is common for R packages to specify patch versions using the hyphen as the separator, e.g. 1.2-3. Such hyphens MUST be converted to a dot. This translation SHOULD be done via the %R_rpm_version macro as follows:

Version: %R_rpm_version 1.2-3

Apart from defining %{version} as 1.2.3 in this case, this macro sets %__R_upstream_version to keep track of the upstream version for URL generation.

Licencia

Typically, R packages do not contain license files per CRAN policy. R allows and ships a set of open source licenses, and R packages just declare which one they adhere to in the DESCRIPTION file. Following this policy, and as an exception to the general Licensing Guidelines, we do not require upstream R packages to add additional license files.

Full text licenses can be found under /usr/share/R/licenses. These texts can also be displayed in the R console using the RShowDoc() function.

Sources

Projects from standard CRAN-like repositories MUST be packaged from the sources that are published there. Packages from the following repositories MUST use the set macros provided for automatic generation of the project’s URL and package’s source URL:

  • CRAN: %{cran_url} and %{cran_source}

  • Bioc: %{bioc_url} and %{bioc_source}

Architectures

Packages that do not contain architecture-specific code (i.e. no compiled parts), MUST set BuildArch: noarch.

This affects the installation path:

  • %{_datadir}/R/library/$pkg for noarch packages;

  • %{_libdir}/R/library/$pkg otherwise;

but this is automatically handled by RPM macros as described below.

Dependencias

Automatic standardized names

All R packages will automatically produce standardized Requires and Provides via a generator in R-rpm-macros:

  • Provides are in the form R($pkg) = $version;

  • Requires are in the form R($pkg), with optional >= $version as specified in the package’s metadata if supplied;

where $pkg is the upstream package name, and $version is the RPM-compatible version as described in Versioning.

The packager MUST inspect the generated Requires for correctness. All hard dependencies (R’s LinkingTo, Depends, Imports) MUST be resolvable within the targeted Fedora version.

BuildRequires

Packages MUST declare BuildRequires: R-devel, which in turn pulls the necessary R-rpm-macros and sets the development environment (compilers, libraries, etc.).

Note that R packages inherit their compilation flags from the main R package, which stores them in %{_libdir}/R/etc/Makeconf. The design of R is such that all R add-on packages use the same optimization flags that the main R package was built with. Accordingly, this is why R addon packages do not pass %{optflags}.

If other libraries and utilities (e.g. cmake) are required for building, they MUST be declared explicitly as BuildRequires.

Build-time dependencies on other R packages are automatically handled by the %R_buildrequires macro, which MUST be called in the %generate_buildrequires scriptlet.

  • All hard dependencies (R’s LinkingTo, Depends, Imports) are declared as BuildRequires using standardized names (see Automatic standardized names).

  • Soft dependencies (R’s Suggests, Enhances) are skipped, except for packages used to develop the test suite (currently, testthat, tinytest or RUnit).

Bundled dependencies

Following the general guidelines, packages SHOULD unbundle other dependencies found in R package sources whenever possible. Whenever bundled dependencies are used, they MUST be declared with virtual Provides.

Sub-packages

Some R packages expose header files under the standard path R/library/$pkg/include (defined by CRAN and expected by R), so that other packages can link to them via LinkingTo. The Rcpp package is a notable example. Sometimes, these headers are required at build-time, sometimes at build- as well as run-time and therefore they are essential for proper functioning…​ For these and a variety of other reasons, these headers MUST NOT be split off into a -devel sub-package.

If a particular package contains a large number of examples or documentation that do not impact the package’s functionality, these parts MAY be split off into a sub-package, but sub-packages in general are highly discouraged.

Walkthrough

Preparing the sources

The rest of the scriptlets expect package sources to be extracted in a subdirectory named after the package. Therefore, in %prep, the call to %setup or %autosetup MUST set the -c option.

%prep
%autosetup -c

Other code for unbundling, fixes and workarounds MAY be placed here.

Dynamic BuildRequires

The %R_buildrequires macro MUST be called in the %generate_buildrequires scriptlet to generate the dynamic BuildRequires.

%generate_buildrequires
%R_buildrequires

Testing packages such as testthat, which are declared in Suggests are whitelisted in %{__R_whitelist}, and added as BuildRequires by %R_buildrequires.

Building and Installing

R packages are built and installed in a single stage via R CMD INSTALL. Therefore, the %build section MUST be empty.

Two macros are provided and MUST be called in the %install section. First, %R_install builds and installs the package, then %R_save_files generates a list of files corresponding to the given importable module, and saves it as %{R_files}.

%build

%install
%R_install
%R_save_files

The %R_install macro ensures reprodubility by setting the package’s build timestamp as $SOURCE_DATE_EPOCH.

R package installation generates a new R.css file that conflicts with the master R.css file included in the main R package. The %R_install macro deletes this file.

The %R_install macro calls %_R_libdir_check to ensure that a noarch package did not produce a shared library, or an archful package actually contains a shared library; otherwise, it fails with an informative error message. If the packager does not want this check, %_R_libdir_check can be set e.g. to an empty string.

Testing

The %R_check macro MUST be called in the %check section to run R package checks.

%check
%R_check

According to CRAN’s guidelines, R packages MUST work without soft dependencies. If package checks fail because soft dependencies are used unconditionally (e.g. in examples or tests), this is considered a bug and SHOULD be reported upstream. Meanwhile, a workaround MUST be put in place:

  • If the failure happens in an example, the --no-examples flag MAY be appended to %R_check.

  • If the failure happens in a test, a skip() call MAY be added in the proper place to skip a test, or a test file MAY be removed, or even the --no-tests flag MAY be appended to %R_check for more complicated situations.

Listing files

Module files MUST be added via the -f option as follows:

%files -f %{R_files}

If necessary, any additional files outside the package’s path SHOULD be added explicitly afterwards.

Ejemplo del archivo spec

This is an example spec file for a hypothetical R package called "foo", with upstream version 1.2-3:

Name:           R-foo
Version:        %R_rpm_version 1.2-3
Release:        %autorelease
Summary:        Adds foo functionality for R

License:        GPL-2.0-or-later
URL:            %{cran_url}
Source:         %{cran_source}

# BuildArch:      noarch
BuildRequires:  R-devel
# BuildRequires:  somelib-devel

%description
R Interface to foo, enables bar!

%prep
%autosetup -c

%generate_buildrequires
%R_buildrequires

%build

%install
%R_install
%R_save_files

%check
%R_check

%files -f %{R_files}

%changelog
%autochangelog