Skip to content

Commit

Permalink
switch
Browse files Browse the repository at this point in the history
  • Loading branch information
DennisHeimbigner committed Sep 28, 2024
1 parent 92c9cf3 commit a3a18d8
Show file tree
Hide file tree
Showing 11 changed files with 223 additions and 173 deletions.
34 changes: 23 additions & 11 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -653,8 +653,28 @@ if(NOT ENABLE_PLUGIN_INSTALL)
unset(NETCDF_PLUGIN_INSTALL_DIR CACHE)
endif()

if(ENABLE_PLUGIN_INSTALL)
if(NOT DEFINED NETCDF_PLUGIN_INSTALL_DIR)
# Internally, the variable HDF5_PLUGIN_PATH
# is always used as a surrogate for the default
# plugin path. If it was not defined by the user,
# then set it internally.
if(NOT DEFINED HDF5_PLUGIN_PATH OR ${HDF5_PLUGIN_PATH} STREQUAL "")
if(ISMSVC OR ISMINGW)
string(REPLACE "\\" "/" AUP "$ENV{"ALLUSERSPROFILE"}")
HDF5_PLUGIN_PATH="${AUP}/hdfd5/lib/plugin"
else()
HDF5_PLUGIN_PATH="/usr/local/hdf5/lib/plugin"
endif()
endif()

# The --with-plugin-dir gives the user control of the plugin
# directory. If set to 'yes' (the default), then the last directory in
# HDF5_PLUGIN_PATH is used (see above).
# If a specific directory is provided, it will be used.
# If 'no', then plugins will not be installed.

if(NETCDF_ENABLE_PLUGIN_INSTALL)
if(DEFINED NETCDF_PLUGIN_INSTALL_DIR)
set(NETCDF_PLUGIN_INSTALL_DIR "${HDF5_PLUGIN_PATH}")
# Default to HDF5_PLUGIN_PATH or its default directories
if(DEFINED ENV{HDF5_PLUGIN_PATH})
set(NETCDF_PLUGIN_INSTALL_DIR "$ENV{HDF5_PLUGIN_PATH}")
Expand All @@ -671,15 +691,7 @@ endif()

if(ENABLE_PLUGIN_INSTALL)
# Use the lowest priority dir in the path
if(NOT ISMSVC AND NOT ISMINGW)
string(REPLACE ":" ";" PATH_LIST ${NETCDF_PLUGIN_INSTALL_DIR})
else()
set(PATH_LIST ${NETCDF_PLUGIN_INSTALL_DIR})
endif()

# Get last element
list(GET PATH_LIST -1 NETCDF_PLUGIN_INSTALL_DIR)
set(PLUGIN_INSTALL_DIR_SETTING "${NETCDF_PLUGIN_INSTALL_DIR}")
getlastdir("${HDF5_PLUGIN_PATH}" "NETCDF_PLUGIN_INSTALL_DIR")
message(STATUS "Final value of-DPLUGIN_INSTALL_DIR=${NETCDF_PLUGIN_INSTALL_DIR}")
else() # No option specified
unset(NETCDF_PLUGIN_INSTALL_DIR)
Expand Down
14 changes: 13 additions & 1 deletion cmake/netcdf_functions_macros.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -324,4 +324,16 @@ function(is_disabled feature ret_val)
set(${ret_val} "yes" PARENT_SCOPE)
set("NC_${ret_val}" 1 PARENT_SCOPE)
endif(${feature})
endfunction()
endfunction()

# Extract the last element from a path string
function(getlastdir s ret_val)
if(NOT ISMSVC AND NOT ISMINGW)
string(REPLACE ":" ";" list "${s}")
else()
set(list ${s})
endif()
list(GET list -1 last)
set(${ret_val} "${last}" PARENT_SCOPE)
endfunction()

69 changes: 39 additions & 30 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -2128,52 +2128,61 @@ fi

AC_SUBST(STD_FILTERS,[$std_filters])

# Internally, the variable HDF5_PLUGIN_PATH
# is always used as a surrogate for the default
# plugin path. If it was not defined by the user,
# then set it internally.
if test "x${HDF5_PLUGIN_PATH}" = x ; then
if test "x$ISMSVC" = xyes || test "x$ISMINGW" = xyes; then
HDF5_PLUGIN_PATH="${ALLUSERSPROFILE}\\hdfd5\\lib\\plugin"
else
HDF5_PLUGIN_PATH="/usr/local/hdf5/lib/plugin"
fi

# The --with-plugin-dir gives the user control of the plugin
# directory. If set to 'yes' (the default), then first directory in
# the HDF5_PLUGIN_PATH, or /usr/local/hdf5/lib/plugin (the default
# HDF5 plugin dir) will be used. If another directory is provided, it
# will be used. If 'no', then plugins will not be installed.
# directory. If set to 'yes' (the default), then the last directory in
# HDF5_PLUGIN_PATH is used (see above).
# If a specific directory is provided, it will be used.
# If 'no', then plugins will not be installed.

AC_MSG_CHECKING([whether and where we should install plugins])
AC_ARG_WITH([plugin-dir], [AS_HELP_STRING([--with-plugin-dir=<absolute directory>|yes|no|--without-plugin-dir],
[Install selected standard filters in specified or default directory])],
[],[with_plugin_dir=no])
AC_MSG_RESULT([$with_plugin_dir])
# Using selected filter options forces installation
if test "x$have_zstd" = xyes; then
if test "x$enable_plugins" = xyes && test "x$with_plugin_dir" = xno; then
AC_MSG_WARN([--enable_filter-zstd => --with-plugin-dir.])
with_plugin_dir=yes
fi
fi
AC_MSG_RESULT([$with_plugin_dir])
if test "x$with_plugin_dir" = xno ; then # option missing|disabled
with_plugin_dir=no
with_plugin_dir_setting="N.A."
enable_plugin_dir=no
elif test "x$with_plugin_dir" = xyes ; then # --with-plugin-dir, no argument
# Default to last dir (lowest search priority) in HDF5_PLUGIN_PATH
PLUGIN_PATH="$HDF5_PLUGIN_PATH"
if test "x${PLUGIN_PATH}" = x ; then
if test "x$ISMSVC" = xyes || test "x$ISMINGW" = xyes; then
PLUGIN_PATH="${ALLUSERSPROFILE}\\hdfd5\\lib\\plugin"
else
PLUGIN_PATH="/usr/local/hdf5/lib/plugin"
fi
fi
# Use the lowest priority dir in the path
if test "x$ISMSVC" = xyes || test "x$ISMINGW" = xyes; then
PLUGIN_DIR=`echo "$PLUGIN_PATH" | tr ';' ' '`
else
PLUGIN_DIR=`echo "$PLUGIN_PATH" | tr ':' ' '`
elif test "x$with_plugin_dir" != x ; then
if test "x$with_plugin_dir" != xyes && test "x$with_plugin_dir" != xno ; then
# Presume true directory
HDF5_PLUGIN_PATH="${with_plugin_dir}"
fi
for pp in ${PLUGIN_DIR} ; do last="$pp"; done
PLUGIN_DIR="$last"
with_plugin_dir_setting="$PLUGIN_DIR"
# canonical form is all forward slashes
with_plugin_dir=`echo "$PLUGIN_DIR" | tr '\\\\' '/'`
enable_plugin_dir=yes
AC_MSG_NOTICE([Defaulting to --with-plugin-dir=$with_plugin_dir])
else # --with-plugin-dir=<dir|path>
with_plugin_dir_setting="$with_plugin_dir"
enable_plugin_dir=yes
fi

# Use the last dir (lowest search priority) in HDF5_PLUGIN_PATH
PLUGIN_PATH="$HDF5_PLUGIN_PATH"
if test "x$ISMSVC" = xyes || test "x$ISMINGW" = xyes; then
PLUGIN_DIR=`echo "$PLUGIN_PATH" | tr ';' ' '`
else
PLUGIN_DIR=`echo "$PLUGIN_PATH" | tr ':;' ' '`
fi
for pp in ${PLUGIN_DIR} ; do last="$pp"; done
PLUGIN_DIR="$last"
with_plugin_dir_setting="$PLUGIN_DIR"
# canonical form is all forward slashes
with_plugin_dir=`echo "$PLUGIN_DIR" | tr '\\\\' '/'`
enable_plugin_dir=yes
AC_MSG_NOTICE([Final --with-plugin-dir=$with_plugin_dir])
done
AM_CONDITIONAL([ENABLE_PLUGIN_DIR], [test "x$enable_plugin_dir" = xyes])
AC_SUBST([PLUGIN_INSTALL_DIR], [$with_plugin_dir])
# Better value for libnetcdf.settings
Expand Down
1 change: 1 addition & 0 deletions docs/Doxyfile.in
Original file line number Diff line number Diff line change
Expand Up @@ -964,6 +964,7 @@ INPUT = @abs_top_srcdir@/docs/mainpage.dox \
@abs_top_srcdir@/docs/file_format_specifications.md \
@abs_top_srcdir@/docs/all-error-codes.md \
@abs_top_srcdir@/docs/filters.md \
@abs_top_srcdir@/docs/pluginpath.md \
@abs_top_srcdir@/docs/quickstart_filters.md \
@abs_top_srcdir@/docs/quickstart_paths.md \
@abs_top_srcdir@/docs/quickstart_env.md \
Expand Down
97 changes: 7 additions & 90 deletions docs/filters.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,8 @@ should be aware.
* ***Auto Install of filters***<br>
An option is now provided to automatically install
HDF5 filters into a default location, or optionally
into a user-specified location. This is described in
[Appendix H](#filters_appendixh)
(with supporting information in [Appendix G](#filters_appendixg)).
into a user-specified location.
This is described in the *pluginpath.md* document.

* ***NCZarr Filter Support***<br>
[NCZarr filters](#filters_nczarr) are now supported.
Expand Down Expand Up @@ -367,32 +366,8 @@ The details for writing such a filter are defined in the HDF5 documentation[1,2]
### Plugin directory {#filters_plugindir}

The HDF5 loader searches for plugins in a number of directories.
This search is contingent on the presence or absence of the environment
variable named ***HDF5\_PLUGIN\_PATH***.

As with all other "...PATH" variables, it is a sequence of absolute
directories separated by a separator character. For *nix* operating systems,
this separator is the colon (':') character. For Windows and Mingw, the
separator is the semi-colon (';') character. So for example:

* Linux: `export HDF5_PLUGIN_PATH=/usr/lib:/usr/local/lib`
* Windows: `export HDF5_PLUGIN_PATH=c:\\ProgramData\\hdf5\\plugin;c:\\tools\\lib`

If HDF5\_PLUGIN\_PATH is defined, then the loader will search each directory
in the path from left to right looking for shared libraries with specific
exported symbols representing the entry points into the library.

If HDF5\_PLUGIN\_PATH is not defined, the loader defaults to using
these default directories:

* Linux: `/usr/local/hdf5/lib/plugin`
* Windows: `%ALLUSERSPROFILE%\\hdf5\\lib\\plugin`

It should be noted that there is a difference between the search order
for HDF5 versus NCZarr. The HDF5 loader will search only the directories
specificed in HDF5\_PLUGIN\_PATH. In NCZarr, the loader
searches HDF5\_PLUGIN\_PATH and as a last resort,
it also searches the default directory.
The netcdf-c process for installing and locating plugins is described
in detail in the *pluginpath.md* document.

### Plugin Library Naming {#filters_Pluginlib}

Expand Down Expand Up @@ -1164,7 +1139,7 @@ When installing the netcdf library, the following other libraries must be instal
2. The HDF5 wrapper for *libzstd.so* -- There are several options for obtaining this (see [Appendix G](#filters_appendixg).)
3. (Optional) The Zarr wrapper for *libzstd.so* -- you need this if you intend to read/write Zarr datasets that were compressed using zstandard; again see [Appendix G](#filters_appendixg).

## Appendix G. Finding Filters {#filters_appendixg}
## Appendix G. Finding Filter Implementations {#filters_appendixg}

A major problem for filter users is finding an implementation of an HDF5 filter wrapper and (optionally)
its corresponding NCZarr wrapper. There are several ways to do this.
Expand All @@ -1190,40 +1165,7 @@ so they are only usable with netcdf-4. This will change in the future.
As part of the overall build process, a number of filter wrappers are built as shared libraries in the "plugins" directory.
These wrappers can be installed as part of the overall netcdf-c installation process.
WARNING: the installer still needs to make sure that the actual filter/compression libraries are installed: e.g. libzstd and/or libblosc.

The target location into which libraries in the "plugins" directory are installed is specified
using a special *./configure* option

````
--with-plugin-dir=<directorypath>
or
--with-plugin-dir
````
or its corresponding *cmake* option.

````
-DPLUGIN_INSTALL_DIR=<directorypath>
or
-DPLUGIN_INSTALL_DIR=YES
````
This option defaults to the value "yes", which means that filters are
installed by default. This can be disabled by one of the following options.

````
--without-plugin-dir (automake)
or
--with-plugin-dir=no (automake)
or
-DPLUGIN_INSTALL_DIR=NO (CMake)
````

If the option is specified with no argument (automake) or with the value "YES" (CMake),
then it defaults (in order) to the following directories:

1. If the HDF5\_PLUGIN\_PATH environment variable is defined, then last directory in the list of directories in the path is used.
2. (a) `/usr/local/hdf5/lib/plugin` for linux/unix operating systems (including Cygwin)<br>
(b) `%ALLUSERSPROFILE%\\hdf5\\lib\\plugin` for Windows and MinGW

See the document *pluginpaths.md* for details on the installation process.
If NCZarr is enabled, then in addition to wrappers for the standard filters,
additional libraries will be installed to support NCZarr access to filters.
Currently, this list includes the following:
Expand All @@ -1243,31 +1185,6 @@ provided by the *lib__nczh5filters.so* shared library. Note also that
if you disable HDF5 support, but leave NCZarr support enabled,
then all of the above filters should continue to work.

### HDF5\_PLUGIN\_PATH

At the moment, NetCDF uses the existing HDF5 environment variable
*HDF5\_PLUGIN\_PATH* to locate the directories in which filter wrapper
shared libraries are located. This is used both for the HDF5 filter
wrappers but also the NCZarr codec wrappers.

*HDF5\_PLUGIN\_PATH* is a typical Windows or Unix style
path-list. That is it is a sequence of absolute directory paths
separated by a specific separator character. For Windows, the
separator character is a semicolon (';') and for Unix, it is a a
colon (':').

So, if HDF5\_PLUGIN\_PATH is defined at build time, and
*--with-plugin-dir* is specified with no argument then the last
directory in the path will be the one into which filter wrappers are
installed. Otherwise the default directories are used.

The important thing to note is that at run-time, there are several cases to consider:

1. HDF5\_PLUGIN\_PATH is defined and is the same value as it was at build time -- no action needed
2. HDF5\_PLUGIN\_PATH is defined and is has a different value from build time -- the user is responsible for ensuring that the run-time path includes the same directory used at build time, otherwise this case will fail.
3. HDF5\_PLUGIN\_PATH is not defined at either run-time or build-time -- no action needed
4. HDF5\_PLUGIN\_PATH is not defined at run-time but was defined at build-time -- this will probably fail

## Appendix I. A Warning on Backward Compatibility {#filters_appendixi}

The API defined in this document should accurately reflect the
Expand All @@ -1293,6 +1210,6 @@ For additional information, see [Appendix B](#filters_appendixb).
## Point of Contact {#filters_poc}

*Author*: Dennis Heimbigner<br>
*Email*: dmh at ucar dot edu<br>
*Email*: [email protected]<br>
*Initial Version*: 1/10/2018<br>
*Last Revised*: 5/18/2022
2 changes: 2 additions & 0 deletions include/ncplugins.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,14 @@ extern "C" {
EXTERNL int NCZ_plugin_path_initialize(void);
EXTERNL int NCZ_plugin_path_finalize(void);

EXTERNL int NCZ_plugin_path_ndirs(size_t* ndirsp);
EXTERNL int NCZ_plugin_path_get(struct NCPluginList* dirs);
EXTERNL int NCZ_plugin_path_set(struct NCPluginList* dirs);

EXTERNL int NC4_hdf5_plugin_path_initialize(void);
EXTERNL int NC4_hdf5_plugin_path_finalize(void);

EXTERNL int NC4_hdf5_plugin_path_ndirs(size_t* ndirsp);
EXTERNL int NC4_hdf5_plugin_path_get(struct NCPluginList* dirs);
EXTERNL int NC4_hdf5_plugin_path_set(struct NCPluginList* dirs);

Expand Down
13 changes: 12 additions & 1 deletion include/netcdf_filter.h
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,16 @@ typedef struct NCPluginList {
extern "C" {
#endif

/**
* Return the length of the current sequence of directories
* in the internal global plugin path list.
* @param ndirsp length is returned here
* @return NC_NOERR | NC_EXXX
*
* @author Dennis Heimbigner
*/
EXTERNL int nc_plugin_path_ndirs(size_t* ndirsp);

/**
* Return the current sequence of directories in the internal global
* plugin path list. Since this function does not modify the plugin path,
Expand All @@ -143,7 +153,7 @@ extern "C" {
* vector will be allocated. If not NULL, then the specified space will
* be overwritten with the vector.
*
* Author: Dennis Heimbigner
* @author: Dennis Heimbigner
*/
EXTERNL int nc_plugin_path_get(NCPluginList* dirs);

Expand All @@ -155,6 +165,7 @@ EXTERNL int nc_plugin_path_get(NCPluginList* dirs);
* @param dirs pointer to an NCPluginList object containing
* the number and vector of directory paths
* @return NC_NOERR | NC_EXXX
*
* @author Dennis Heimbigner
*/
EXTERNL int nc_plugin_path_set(NCPluginList* dirs);
Expand Down
Loading

0 comments on commit a3a18d8

Please sign in to comment.