Skip to contents

The HDF5 library maintains excellent backward compatibility. When function signatures or data structures change, the old versions are often kept available. A key feature of hdf5lib is that it exposes an easy way to compile your C/C++ code against a specific, older version of the HDF5 API.

Why Target a Specific API?

The primary reason is stability. By locking your package to a specific HDF5 API version, you prevent your package from breaking unexpectedly when hdf5lib is updated with a new version of HDF5. This gives you, the package developer, control over the upgrade cycle. You can choose to increase the API version when you are ready to test your code against newer HDF5 features and behaviors.

How to Set the API Version

You can control the API version by passing the api argument to hdf5lib::c_flags() and hdf5lib::ld_flags() in your package’s src/Makevars file. This automatically adds the correct preprocessor directive (e.g., -DH5_USE_114_API_DEFAULT) during compilation.

For example, to ensure your code uses the HDF5 1.14 API, you would modify src/Makevars as follows:

# In your package's src/Makevars
PKG_CPPFLAGS = `$(R_HOME)/bin/Rscript -e "cat(hdf5lib::c_flags(api = 1.14))"`
PKG_LIBS     = `$(R_HOME)/bin/Rscript -e "cat(hdf5lib::ld_flags(api = 1.14))"`

The HDF5 headers included via hdf5lib will then expose the 1.14-compatible function signatures. Because the static library bundled by hdf5lib contains the implementations for multiple API versions, your code will compile and link correctly.

If you want to use the newest available API, you can simply omit the api argument.

Supported Versions

The api argument accepts the following values:

  • 2.0 (HDF5 2.2.x)
  • 1.14 (HDF5 1.14.x)
  • 1.12 (HDF5 1.12.x)
  • 1.10 (HDF5 1.10.x)
  • 1.8 (HDF5 1.8.x)
  • 1.6 (HDF5 1.6.x)

Note: You must choose from the explicit list above. There is no api = 2.2 option, as the HDF5 library does not utilize an H5_USE_210_API_DEFAULT macro internally. To build against the 2.2.x series, use api = 2.0 or simply omit the argument.

Checking the hdf5lib Version

The api argument pins HDF5’s functions. To use something a later hdf5lib release added, such as hdf5lib_set_blosc_nthreads(), while still building against earlier releases, test the version that hdf5lib.h defines:

#include <hdf5lib.h>

#if defined(HDF5LIB_VERSION) && HDF5LIB_VERSION >= 2020001   /* 2.2.0.1 or later */
  hdf5lib_set_blosc_nthreads(4);
#endif

hdf5lib’s version is the version of HDF5 it bundles followed by a revision of the package, and hdf5lib.h defines:

Macro Value in 2.2.0.1
HDF5LIB_VERSION_MAJOR, HDF5LIB_VERSION_MINOR, HDF5LIB_VERSION_PATCH 2, 2, 0 (HDF5’s version)
HDF5LIB_VERSION_REVISION 1
HDF5LIB_VERSION_STRING "2.2.0.1"
HDF5LIB_VERSION 2020001: major × 1000000 + minor × 10000 + patch × 100 + revision
HDF5LIB_VERSION_NUMBER(major, minor, patch, revision) Packs any version the same way

These macros first appear in 2.2.0.1. In earlier headers HDF5LIB_VERSION is undefined, so the test above is false. Compare against a plain number, as above: an #if that calls HDF5LIB_VERSION_NUMBER() is a syntax error against those headers, even behind defined(). For the version of HDF5 itself, hdf5.h provides H5_VERSION_GE(2, 2, 0).

If your package simply requires a newer hdf5lib, a version requirement is simpler than #if tests. R checks it when your package is installed:

LinkingTo: hdf5lib (>= 2.2.0.1)