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.2option, as the HDF5 library does not utilize anH5_USE_210_API_DEFAULTmacro internally. To build against the 2.2.x series, useapi = 2.0or 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);
#endifhdf5lib’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:
