1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100
|
---
title: "Linking to Rhdf5lib"
author:
- name: Mike L. Smith
affiliation: de.NBI & EMBL Heidelberg
package: Rhdf5lib
output:
BiocStyle::html_document
vignette: |
%\VignetteIndexEntry{Linking to Rhdf5lib}
%\VignetteEngine{knitr::rmarkdown}
%\VignetteEncoding{UTF-8}
---
# Motivation
`r Biocpkg("Rhdf5lib")` provides versions of the C and C++ HDF5 libraries. It is primarily useful to developers of other R packages who want to make use of the capabilities of the HDF5 library directly in the C or C++ code of their own packages, rather than using a higher level interface such as the [**rhdf5**](http://bioconductor.org/packages/rhdf5/) package. Using **Rhdf5lib** makes life easier for users, as they do not have to worry about installing libraries at a system level, and for developers since they can work with a defined version of the library rather than developing strategies to cope with the potential for multiple versions.
**Rhdf5lib** is very much inspired by the [**zlibbioc**](http://bioconductor.org/packages/zlibbioc/) and [**Rhtslib**](http://bioconductor.org/packages/Rhtslib/) packages.
# Usage
There is an example package,
[**usingRhdf5lib**](https://github.com/grimbough/usingRhdf5lib), that
demonstrates how packages should link to **Rhdf5lib**.
## Link to the library
To link successfully to the HDF5 library included in **Rhdf5lib** a package must include *both* a `src/Makevars.win` *and* `src/Makevars` file.
Add the following lines to both `src/Makevars` and `src/Makevars.win`
RHDF5_LIBS=$(shell "${R_HOME}/bin${R_ARCH_BIN}/Rscript" -e \
'Rhdf5lib::pkgconfig("PKG_C_LIBS")')
PKG_LIBS=$(RHDF5_LIBS)
The statement for each platform modifies the `$PKG_LIBS` variable. If your package needs to add additional information to the `$PKG_LIBS` variable, do so by adding to the `PKG_LIBS=$(RHDF5_LIBS)` line, e.g.,
PKG_LIBS=$(RHDF5_LIBS) -L/path/to/foolib -lfoo
*Note that the use of `$(shell ...)` necessitates using GNU Make, and you need to make this requirement explicit in your package's DESCRIPTION file via the entry:*
SystemRequirements: GNU make
The default behaviour of `Rhdf5lib::pkgconfig` is to report the location of the shared library as the result of `system.file("lib", package="Rhdf5lib")`. If this is inappropriate for your system e.g. a cluster with a shared file system, use the environment variable `RHDF5LIB_RPATH` to override this and set an appropriate location for your infrastructure.
Valid options to provide to `pkgconfig()` are: `PKG_C_LIBS`, `PKG_CXX_LIBS`, `PKG_C_HL_LIBS` and `PKG_CXX_HL_LIBS`. Choose the most appropriate depending upon whether your linking code requires the C++ API (`C` vs `CXX`) and/or the HDF5 'high-level' API (`HL`). Choosing options that you don't require should not harm performance, but will result in a larger library and potentially greater memory usage for your application, so it is good practice to select only the features you need.
## Locating the library headers
In order for the C/C++ compiler to find the HDF5 headers during package installation, add **Rhdf5lib** to the *LinkingTo* field of the DESCRIPTION file of your package, e.g.
LinkingTo: Rhdf5lib
In you C or C++ code files, you can then use the standard include techniques, e.g., `#include "hdf5.h"` or `#include "H5Cpp.h"`. You can inspect the header files manually to check their names and declared functions. To find their location on your system you can use the following code:
```{R headers}
system.file(package="Rhdf5lib", "include")
```
# Configuration arguments for non-standard system setups
## Non-standard ZLIB location
*Rhdf5lib* requires the ZLIB compression library to be installed on non-Windows platforms. If installation fails with a message reporting that **zlib.h** can not be found, it is possible to provide the appropriate path explicitly during installation via the `configure.args` argument e.g.
```{r, zlib-path, eval = FALSE}
BiocManager::install('Rhdf5lib', configure.args = "--with-zlib='/path/to/zlib/'")
```
Here `/path/to/zlib` should be the directory that contains both `include/zlib.h` and `lib/libz.a`. For example, on a typical Ubuntu installation this may be `/usr/` while for libraries installed via **miniconda** this location could be `/home/<USER>/miniconda3/`.
## Disabling link time optimisation (LTO)
If you have configured R with link-time optimisation enabled (see [here](https://cran.r-project.org/doc/manuals/r-devel/R-admin.html#Link_002dTime-Optimization)), but wish to turn it off for the installation of **Rhdf5lib**, you need to set both the `configure.args` and `INSTALL_opts` arguments e.g.
```{r, disable-lto, eval = FALSE}
BiocManager::install('Rhdf5lib', INSTALL_opts="--no-use-LTO", configure.args = "--disable-lto")
```
This is because building **Rhdf5lib** involves first compiling the HDF5 library, and then compiling and linking the R interface against that. The `INSTALL_opts` argument affects the latter part, but we need to use `configure.args` to ensure the HDF5 library is built with the same settings. ^[Using `"--enable-lto"` here will have no effect. To enable link-time optimisation you must have already configured R with `--enable-lto` (see [here](https://cran.r-project.org/doc/manuals/r-devel/R-admin.html#Link_002dTime-Optimization)).]
## Disabling setting rpath
If you encounter problems checking whether to use `-Wl,-rpath` to "*link shared libs in nondefault directories*" you can disable the test by passing the option `"--disable-sharedlib-rath"` to the configuration script.
```{r, disable-rpath, eval = FALSE}
BiocManager::install('Rhdf5lib', configure.args = "--disable-sharedlib-rath")
```
# Funding
MLS was supported by the BMBF-funded Heidelberg Center for Human Bioinformatics (HD-HuB) within the German Network for Bioinformatics Infrastructure ([de.NBI](https://www.denbi.de)), Grant Number #031A537B
{ width=50% }
# Session info {.unnumbered}
```{r sessionInfo, echo=FALSE}
sessionInfo()
```
|