Git Product home page Git Product logo

rules_r's Introduction

R Rules for Bazel Build Status

Overview

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.

Getting started

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")

Configuration

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

Note

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.

Examples

Some examples are available in the tests directory of this repo.

Also see Razel scripts that provide utility functions to generate BUILD files and WORKSPACE rules for external packages.

Docker

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

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

List of files, required

Source files to be included for building the package.

pkg_name

String; optional

Name of the package if different from the target name.

deps

List of labels; optional

R package dependencies of type `r_pkg`.

install_args

String; optional

Additional arguments to supply to R CMD INSTALL.

makevars_darwin

File; default to R/Makevars.darwin

Makevars file to use for macOS overrides.

makevars_linux

File; default to R/Makevars.linux

Makevars file to use for Linux overrides.

shlib_name

String; optional

Shared library name, if different from package name.

lazy_data

Bool; default to False

Set to True if the package uses the LazyData feature.

post_install_files

List of strings; optional

Additional files generated as part of the package build and installed with the package.

r_library

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

List of labels, required

Package (and dependencies) to install.

library_path

String; optional

If different from system default, default library location for installation. For runtime overrides, use bazel run [target] -- -l [path].

r_unit_test

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

List of files, required

Test scripts and test data files for the package.

pkg_name

String; required

Name of the package.

deps

List of labels; optional

R package dependencies of type `r_pkg`.

r_pkg_test

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

List of files, required

Source files to be included for building the package.

pkg_name

String; required

Name of the package.

deps

List of labels; optional

R package dependencies of type `r_pkg`.

build_args

String; default "--no-build-vignettes --no-manual"

Additional arguments to supply to R CMD build.

check_args

String; default "--no-build-vignettes --no-manual"

Additional arguments to supply to R CMD check.

r_package

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

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.

Contributing

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.

Known Issues

Please check open issues at the github repo.

We have tested only on macOS and Ubuntu (VM and Docker).

rules_r's People

Contributors

siddharthab avatar

Watchers

James Cloos avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.