These rules are used for building R packages with Bazel. Although R has an excellent package management system, there is no continuous build and integration system for entire R package repositories. An advantage of using Bazel, over a custom solution of tracking the package dependency graph and triggering builds accordingly on each commit, is that R packages can be built and tested as part of one build system in multi-language monorepos.
The following assumes that you are familiar with how to use Bazel in general.
In order to use the rules, you must have bazel 0.5.3 or later and add the following to your WORKSPACE file:
http_archive(
name = "com_grail_rules_r",
strip_prefix = "rules_r-0.1.1",
urls = ["https://github.com/grailbio/rules_r/archive/0.1.1.tar.gz"],
)
You can load the rules in your BUILD file like so:
load("@com_grail_rules_r//R:defs.bzl",
"r_pkg", "r_library", "r_unit_test", "r_pkg_test")
There are also convenience macros available which create multiple implicit targets:
load("@com_grail_rules_r//R:defs.bzl", "r_package")
and
load("@com_grail_rules_r//R:defs.bzl", "r_package_with_test")
These rules assume that you have R installed on your system and can be located
using the PATH
environment variable. They also assume that packages with
priority recommended
are in the default R library (given by .Library
variable in R).
For each package, you can also specify a different Makevars file that can be
used to have finer control over native code compilation. For macOS, the
Makevars file used as default helps find gfortran
.
For macOS, this setup will help you cover the requirements for a large number of packages:
brew install gcc pkg-config icu4c openssl
For Ubuntu, this (or equivalent for other Unix systems) helps:
apt-get install pkgconf libssl-dev libxml2-dev libcurl4-openssl-dev
For no interference from other packages during the build (possibly other
versions installed manually by the user), it is recommended that packages other
than those with recommended priority be installed in the directory pointed to
by R_LIBS_USER
. The Bazel build process will then be able to hide all the
other packages from R by setting a different value for R_LIBS_USER
.
When moving to Bazel for installing R packages on your system, we recommend cleaning up existing machines:
Rscript \
-e 'options("repos"="https://cloud.r-project.org")' \
-e 'pkgs <- available.packages()' \
-e 'install.packages(pkgs[which(pkgs[, "Priority"] == "recommended"), "Package"], lib=.Library)' \
-e 'remove.packages(installed.packages(priority="NA")[, "Package"], lib=.Library)'
# If not set up already, fix a directory for R_LIBS_USER.
echo 'R_LIBS_USER="/opt/r-libs/"' >> ~/.Renviron
For more details on how R searches different paths for packages, see libPaths.
Some examples are available in the tests directory of this repo.
- See tests/exampleA for a barebones R package.
- See tests/exampleB for a barebones R package that depends on another package.
- See tests/exampleC for an R package that depends on external R packages.
Also see Razel scripts that provide utility functions to generate BUILD
files
and WORKSPACE
rules for external packages.
You can also create Docker images of R packages using Bazel.
In your WORKSPACE
file, load the Docker rules and specify the base R image.
git_repository(
name = "io_bazel_rules_docker",
remote = "https://github.com/bazelbuild/rules_docker.git",
tag = "v0.1.0",
)
load(
"@io_bazel_rules_docker//docker:docker.bzl",
"docker_repositories",
"docker_pull",
)
docker_repositories()
docker_pull(
name = "r",
registry = "index.docker.io",
repository = "rocker/r-ver",
tag = "latest",
)
And then, in a BUILD
file, define your library of R packages and install them
in a Docker image. Dependencies are installed implicitly.
r_library(
name = "my_r_library",
pkgs = [
"//path/to/packageA:r_pkg_target",
"//path/to/packageB:r_pkg_target",
],
)
docker_build(
name = "dev",
base = "@r//image",
directory = "/r-libs",
env = {"R_LIBS_USER": "/r-libs"},
tars = [":my_r_library"],
repository = "my_repo",
cmd = ["R"]
)
r_pkg(srcs, pkg_name, deps, install_args, makevars_darwin, makevars_linux,
shlib_name, lazy_data, post_install_files)
Rule to install the package and its transitive dependencies in the Bazel sandbox, so it can be depended upon by other package builds.
Attributes | |
---|---|
srcs |
Source files to be included for building the package. |
pkg_name |
Name of the package if different from the target name. |
deps |
R package dependencies of type `r_pkg`. |
install_args |
Additional arguments to supply to R CMD INSTALL. |
makevars_darwin |
Makevars file to use for macOS overrides. |
makevars_linux |
Makevars file to use for Linux overrides. |
shlib_name |
Shared library name, if different from package name. |
lazy_data |
Set to True if the package uses the LazyData feature. |
post_install_files |
Additional files generated as part of the package build and installed with the package. |
r_library(pkgs, library_path)
Executable rule to install the given packages and all dependencies to a user provided or system default R library. Run the target with --help for usage information.
Attributes | |
---|---|
pkgs |
Package (and dependencies) to install. |
library_path |
If different from system default, default library location for installation. For runtime overrides, use bazel run [target] -- -l [path]. |
r_unit_test(srcs, pkg_name, deps)
Rule to keep all deps in the sandbox, and run the provided R test scripts. The package itself must be one of the deps.
Attributes | |
---|---|
srcs |
Test scripts and test data files for the package. |
pkg_name |
Name of the package. |
deps |
R package dependencies of type `r_pkg`. |
r_pkg_test(srcs, pkg_name, deps, build_args, check_args)
Rule to keep all deps of the package in the sandbox, build a source archive of this package, and run R CMD check on the package source archive in the sandbox.
Attributes | |
---|---|
srcs |
Source files to be included for building the package. |
pkg_name |
Name of the package. |
deps |
R package dependencies of type `r_pkg`. |
build_args |
Additional arguments to supply to R CMD build. |
check_args |
Additional arguments to supply to R CMD check. |
r_package(pkg_name, pkg_srcs, pkg_deps, pkg_suggested_deps=[])
Convenience macro to generate the r_pkg
and r_library
targets.
r_package_with_test(pkg_name, pkg_srcs, pkg_deps, pkg_suggested_deps=[], test_timeout="short")
Convenience macro to generate the r_pkg
, r_library
,
r_unit_test
, and r_pkg_test
targets.
Contributions are most welcome. Please submit a pull request giving the owners of this github repo access to your branch for minor style related edits, etc.
Please check open issues at the github repo.
We have tested only on macOS and Ubuntu (VM and Docker).