1 Introduction

The beachmat package provides a C++ API for handling a variety of R matrix types. The aim is to abstract away the specific type of matrix object when writing C++ extensions, thus simplifying the processing of data stored in those objects. Currently, the API supports double-precision, integer, logical and character matrices. Supported classes include base matrix objects, a number of classes from the Matrix package, and disk-backed matrices from the HDF5Array package. This document describes how to link to beachmat from the C++ code of another R package.

2 Prerequisites for linking

The beachmat package currently has several dependencies:

  • The compiler should support the C++11 standard. This usually requires GCC version 4.8.1 or higher. You need to tell the build system to use C++11, by modifying the SystemRequirements field of the DESCRIPTION file:

      SystemRequirements: C++11
  • Rcpp should be installed. You also need to ensure that Rcpp is initialized when your package is loaded. This requires addition of Rcpp to the Imports field of the DESCRIPTION file:

     Imports: Rcpp

    … and a corresponding importFrom specification in the NAMESPACE file:

     importFrom(Rcpp, sourceCpp)

    (The exact function to be imported doesn’t matter, as long as the namespace is loaded. Check out the Rcpp documentation for more details.)

  • HDF5Array, DelayedArray and beachmat itself should be added to the Suggests field, as the API will perform some calls to R functions in those packages to query certain parameters. If you intend to accept instances of Matrix classes, the package should also be listed in the Suggests field, if not already in Imports or Depends:

      Suggests: beachmat, HDF5Array, DelayedArray, Matrix
  • Rhdf5lib should be installed.

3 Linking to the library

To link successfully to the beachmat library, a package must include both a src/Makevars.win and src/Makevars file.

Note: the contents of src/Makevars.win and src/Makevars are almost identical, but not quite. Be careful of the differences.

Create a src/Makevars.win file with the following lines:

BEACHMAT_LIBS=$(shell echo 'beachmat::pkgconfig("PKG_LIBS")'|\
    "${R_HOME}/bin/R" --vanilla --slave)
PKG_LIBS=$(BEACHMAT_LIBS)

… and a src/Makevars file with the following lines:

BEACHMAT_LIBS=`echo 'beachmat::pkgconfig("PKG_LIBS")'|\
    "${R_HOME}/bin/R" --vanilla --slave`
PKG_LIBS=$(BEACHMAT_LIBS)

The statement for each platfrom modifies the $PKG_LIBS variable. If your package needs to add to the $PKG_LIBS variable, do so by adding to the PKG_LIBS=$(BEACHMAT_LIBS) line. For example:

PKG_LIBS=$(BEACHMAT_LIBS) -L/path/to/foolib -lfoo

The Linux implementation embeds the location of the beachmat library in the package-specific shared object via the compiler flag -Wl,rpath,path, where path is determined by system.file("lib", package="beachmat"). The path determined by system.file() is from .libPaths() and will resolve all symbolic links. This can cause problems, e.g., when the “head” node of a cluster mimicks the cluster node via a symbolic link to the directory in which beachmat is installed. Use the environment variable BEACHMAT_RPATH to resolve this by setting it to the cluster-node accessible path. Similar arguments apply to Rhdf5lib with the environment variable RHDF5LIB_RPATH.

4 Including the headers

In order for the C/C++ compiler to find the beachmat package headers during installation, add the following to the LinkingTo field of the DESCRIPTION file:

LinkingTo: Rcpp, Rhdf5lib, beachmat

In C or C++ code files, use standard techniques to include header definitions, e.g., #include "beachmat/numeric_matrix.h" (see here for more details). Header files are available for perusal at the following location (enter in an R session):

system.file(package="beachmat", "include")
## [1] "/tmp/RtmpS3CKSB/Rinst3ae91d9a18df/beachmat/include"

5 Common problems

  • An undefined symbol error starting with _ZN2H56H5FileC1ERKNSt7_... usually indicates that Rhdf5lib was compiled with a different GCC version than beachmat, leading to incompatibilities in the binaries. This can usually be fixed by re-installing Rhdf5lib prior to installing beachmat.

  • An expected unqualified-id before 'using' error. This means that the version of GCC used to compile beachmat is out of date and does not fully support C++11.

Users can ask for help by making a post on the Bioconductor support site, labelled with the beachmat tag. This is the preferred avenue for questions. New users are advised to read the posting guide before creating a post.