Skip to content

Commit efdec07

Browse files
Extend the netcdf API to support programmatic changes to the plugin search path
Replaces PR Unidata#3024 and PR Unidata#3033 re: Unidata#2753 As suggested by Ed Hartnett, This PR extends the netcdf.h API to support programmatic control over the search path used to locate plugins. I created several different APIs, but finally settled on the following API as being the simplest possible. It does have the disadvantage that it requires use of a global lock (not implemented) if used in a threaded environment. Specifically, note that modifying the plugin path must be done "atomically". That is, in a multi-threaded environment, it is important that the sequence of actions involved in setting up the plugin path must be done by a single processor or in some other way as to guarantee that two or more processors are not simultaneously accessing the plugin path get/set operations. As an example, assume there exists a mutex lock called PLUGINLOCK. Then any processor accessing the plugin paths should operate as follows: ```` lock(PLUGINLOCK); nc_plugin_path_get(...); <rebuild plugin path> nc_plugin_path_set(...); unlock(PLUGINLOCK); ```` ## Internal Architecture It is assumed here that there only needs to be a single set of plugin path directories that is shared by all filter code and is independent of any file descriptor; it is global in other words. This means, for example, that the path list for NCZarr and for HDF5 will always be the same. However internally, processing the set of plugin paths depends on the particular NC_FORMATX value (NC_FORMATX_NC_HDF5 and NC_FORMATX_NCZARR, currently). So the *nc_plugin_path_set* function, will take the paths it is given and propagate them to each of the NC_FORMATX dispatchers to store in a way that is appropriate to the given dispatcher. There is a complication with respect to the *nc_plugin_path_get* function. It is possible for users to bypass the netcdf API and modify the HDF5 plugin paths directly. This can result in an inconsistent plugin path between the value used by HDF5 and the global value used by netcdf-c. Since there is no obvious fix for this, we warn the user of this possibility and otherwise ignore it. ## Test Changes * New tests<br> a. unit_test/run_pluginpaths.sh -- was created to test this new capability.<br> b. A new test utility has been added as *unit_test/run_dfaltpluginpath.sh* to test the default plugin path list. * New test support utilities<br> a. unit_test/ncpluginpath.c -- report current state of the plugin path<br> b. unit_test/tst_pluginpaths.c -- test program to support run_pluginpaths.sh ## Documentation * A new file -- docs/pluginpath.md -- provides documentation of the new API. It includes some material taken fro filters.md. ## Other Major Changes 1. Cleanup the whole plugin path decision tree. This is described in the *docs/pluginpath.md* document and summarized in Addendum 2 below. 2. I noticed that the ncdump/testpathcvt.sh had been disabled, so fixed and re-enabled it. This necessitated some significant changes to dpathmgr.c. ## Misc. Changes 1. Add some path manipulation utilities to netcf_aux.h 2. Fix some minor bugs in netcdf_json.h 3. Convert netcdf_json.h and netcdf_proplist.h to BUILT_SOURCE. 4. Add NETCDF_ENABLE_HDF5 as synonym for USE_HDF5 5. Fix some size_t <-> int conversion warnings. 6. Encountered and fixed the Windows \r\n problem in tst_pluginpaths.c. 7. Cleanup some minor CMakeLists.txt problems. 8. Provide an implementation of echo -n since it appears to not be available on all platforms. 9. Add a property list mechanism to pass environmental information to filters. 10. Cleanup Doxyfile.in 11. Fixed a memory leak in libdap2; surprised that I did not find this earlier. ## Addendum 1: Proposed API The API makes use of a counted vector of strings representing the sequence of directories in the path. The relevant type definition is as follows. ```` typedef struct NCPluginList {size_t ndirs; char** dirs;} NCPluginList; ```` The API proposed in this PR looks like this (from netcdf-c/include/netcdf_filter.h). * ````int nc_plugin_path_ndirs(size_t* ndirsp);```` Arguments: *ndirsp* -- store the number of directories in this memory. This function returns the number of directories in the sequence if internal directories of the internal plugin path list. * ````int nc_plugin_path_get(NCPluginList* dirs);```` Arguments: *dirs* -- counted vector for storing the sequence of directies in the internal path list. This function returns the current sequence of directories from the internal plugin path list. Since this function does not modify the plugin path, it does not need to be locked; it is only when used to get the path to be modified that locking is required. If the value of *dirs.dirs* is NULL (the normal case), then memory is allocated to hold the vector of directories. Otherwise, use the memory of *dirs.dirs* to hold the vector of directories. * ````int nc_plugin_path_set(const NCPluginList* dirs);```` Arguments: *dirs* -- counted vector for providing the new sequence of directories in the internal path list. This function empties the current internal path sequence and replaces it with the sequence of directories argument. Using an *ndirs* argument of 0 will clear the set of plugin paths. ## Addendum 2: Build-Time and Run-Time Constants. ### Build-Time Constants <table style="border:2px solid black;border-collapse:collapse"> <tr style="outline: thin solid;" align="center"><td colspan="4">Table showing the build-time computation of NETCDF_PLUGIN_INSTALL_DIR and NETCDF_PLUGIN_SEARCH_PATH.</td> <tr style="outline: thin solid" ><th>--with-plugin-dir<th>--prefix<th>NETCDF_PLUGIN_INSTALL_DIR<th>NETCDF_PLUGIN_SEARCH_PATH <tr style="outline: thin solid" ><td>undefined<td>undefined<td>undefined<td>PLATFORMDEFALT <tr style="outline: thin solid" ><td>undefined<td>&lt;abspath-prefix&gt;<td>&lt;abspath-prefix&gt;/hdf5/lib/plugin<td>&lt;abspath-prefix&gt;/hdf5/lib/plugin&lt;SEP&gt;PLATFORMDEFALT <tr style="outline: thin solid" ><td>&lt;abspath-plugins&gt;<td>N.A.<td>&lt;abspath-plugins&gt;<td>&lt;abspath-plugins&gt;&lt;SEP&gt;PLATFORMDEFALT </table> <table style="border:2px solid black;border-collapse:collapse"> <tr style="outline: thin solid" align="center"><td colspan="2">Table showing the computation of the initial global plugin path</td> <tr style="outline: thin solid"><th>HDF5_PLUGIN_PATH<th>Initial global plugin path <tr style="outline: thin solid"><td>undefined<td>NETCDF_PLUGIN_SEARCH_PATH <tr style="outline: thin solid"><td>&lt;path1;...pathn&gt;<td>&lt;path1;...pathn&gt; </table>
1 parent 318eb36 commit efdec07

26 files changed

+529
-436
lines changed

CMakeLists.txt

Lines changed: 50 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -626,93 +626,63 @@ option(NETCDF_ENABLE_FILTER_BZ2 "Enable use of Bz2 compression library if it i
626626
option(NETCDF_ENABLE_FILTER_BLOSC "Enable use of blosc compression library if it is available." ON)
627627
option(NETCDF_ENABLE_FILTER_ZSTD "Enable use of Zstd compression library if it is available." ON)
628628

629-
# If user wants, then install selected plugins (default on)
630-
set(NETCDF_PLUGIN_INSTALL_DIR "YES" CACHE STRING "Whether and where we should install plugins; defaults to yes")
631-
if(NOT NETCDF_ENABLE_PLUGINS)
632-
unset(NETCDF_PLUGIN_INSTALL_DIR CACHE)
633-
endif()
634-
635-
# This is ugly, but seems necessary because of CMake's boolean structure
636-
set(boolval FALSE)
637-
if(DEFINED NETCDF_PLUGIN_INSTALL_DIR)
638-
booleanize(${NETCDF_PLUGIN_INSTALL_DIR} boolval)
639-
if(boolval)
640-
set(ENABLE_PLUGIN_INSTALL YES)
641-
# No actual value was specified
642-
unset(NETCDF_PLUGIN_INSTALL_DIR CACHE)
643-
else()
644-
if(boolval STREQUAL "NOTFOUND")
645-
# Must be an actual value
646-
set(ENABLE_PLUGIN_INSTALL YES)
647-
else()
648-
set(ENABLE_PLUGIN_INSTALL NO)
649-
endif()
650-
endif()
629+
# If user wants, then install selected plugins (default off)
630+
option(NETCDF_PLUGIN_INSTALL "Enable plugin installation" NO)
631+
632+
# Note: the term PLATFORMDEFAULT stands for:
633+
# -- /usr/loca/hdf5/lib/plugin If on a *nix* machine
634+
# -- %ALLUSERSPROFILE%/hdf5/lib/plugins If on a windows or Mingw platform
635+
if(ISMSVC OR ISMINGW)
636+
set(PLATFORMDEFAULT "$ENV{ALLUSERSPROFILE}\\hdf5\\lib\\plugin")
637+
set(PLATFORMSEP ";")
651638
else()
652-
set(ENABLE_PLUGIN_INSTALL NO)
639+
set(PLATFORMDEFAULT "/usr/local/hdf5/lib/plugin")
640+
set(PLATFORMSEP ":")
653641
endif()
654642

655-
# Ensure no defined plugin dir if not enabled
656-
if(NOT ENABLE_PLUGIN_INSTALL)
657-
unset(NETCDF_PLUGIN_INSTALL_DIR CACHE)
658-
endif()
643+
# Internally, the variable DEFAULT_PLUGIN_INSTALL_DIR is the default
644+
# directory into which plugins are installed; this may be undefined if
645+
# plugin installation is disabled (the usual case). It is exported as
646+
# NETCDF_DEFAULT_PLUGIN_INSTALL_DIR.
647+
#
648+
# Similarly the variable DEFAULT_PLUGIN_SEARCH_PATH is the default list
649+
# of directories to search to locate plugins.
650+
#
651+
# See configure.ac to see a table defining the rules for computing these two variables.
659652

660-
# Internally, the variable HDF5_PLUGIN_PATH
661-
# is always used as a surrogate for the default
662-
# plugin path. If it was not defined by the user,
663-
# then set it internally.
664-
if((NOT DEFINED HDF5_PLUGIN_PATH) OR ("${HDF5_PLUGIN_PATH}" STREQUAL ""))
665-
if(ISMSVC OR ISMINGW)
666-
string(REPLACE "\\" "/" AUP "$ENV{ALLUSERSPROFILE}")
667-
set(HDF5_PLUGIN_PATH "${AUP}/hdf5/lib/plugin")
668-
else()
669-
if(NOT DEFINED CMAKE_INSTALL_PREFIX)
670-
set(HDF5_PLUGIN_PATH "/usr/local/hdf5/lib/plugin")
671-
else()
672-
set(HDF5_PLUGIN_PATH "${CMAKE_INSTALL_PREFIX}/hdf5/lib/plugin")
673-
endif(NOT DEFINED CMAKE_INSTALL_PREFIX)
674-
endif()
675-
set(ENV{HDF5_PLUGIN_PATH} "${HDF5_PLUGIN_PATH}")
676-
endif()
677-
678-
# The --with-plugin-dir gives the user control of the plugin
679-
# directory. If set to 'yes' (the default), then the last directory in
680-
# HDF5_PLUGIN_PATH is used (see above).
681-
# If a specific directory is provided, it will be used.
682-
# If 'no', then plugins will not be installed.
683-
684-
if(NETCDF_ENABLE_PLUGIN_INSTALL)
685-
if(DEFINED NETCDF_PLUGIN_INSTALL_DIR)
686-
set(NETCDF_PLUGIN_INSTALL_DIR "${HDF5_PLUGIN_PATH}")
687-
# Default to HDF5_PLUGIN_PATH or its default directories
688-
if(DEFINED ENV{HDF5_PLUGIN_PATH})
689-
set(NETCDF_PLUGIN_INSTALL_DIR "$ENV{HDF5_PLUGIN_PATH}")
690-
else()
691-
if(ISMSVC OR ISMINGW)
692-
set(NETCDF_PLUGIN_INSTALL_DIR "$ENV{ALLUSERSPROFILE}\\hdf5\\lib\\plugin")
693-
else()
694-
if(NOT DEFINED CMAKE_INSTALL_PREFIX)
695-
set(NETCDF_PLUGIN_INSTALL_DIR "/usr/local/hdf5/lib/plugin")
696-
else()
697-
set(NETCDF_PLUGIN_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/hdf5/lib/plugin")
698-
endif(NOT DEFINED CMAKE_INSTALL_PREFIX)
699-
endif(ISMSVC OR ISMINGW)
700-
endif(DEFINED ENV{HDF5_PLUGIN_PATH})
701-
message(STATUS "Defaulting to -DPLUGIN_INSTALL_DIR=${NETCDF_PLUGIN_INSTALL_DIR}")
702-
endif()
703-
endif(NETCDF_ENABLE_PLUGIN_INSTALL)
653+
# Inferences about plugins
704654

705-
if(ENABLE_PLUGIN_INSTALL)
706-
# Use the lowest priority dir in the path
707-
getlastdir("${HDF5_PLUGIN_PATH}" "NETCDF_PLUGIN_INSTALL_DIR")
708-
message(STATUS "Final value of-DPLUGIN_INSTALL_DIR=${NETCDF_PLUGIN_INSTALL_DIR}")
709-
else() # No option specified
710-
unset(NETCDF_PLUGIN_INSTALL_DIR)
711-
unset(NETCDF_PLUGIN_INSTALL_DIR CACHE)
712-
set(PLUGIN_INSTALL_DIR_SETTING "N.A.")
655+
if(NETCDF_WITH_PLUGIN_DIR)
656+
set(NETCDF_ENABLE_PLUGINS yes)
713657
endif()
714658

715-
message(STATUS "ENABLE_PLUGIN_INSTALL=${ENABLE_PLUGIN_INSTALL} PLUGIN_INSTALL_DIR=${NETCDF_PLUGIN_INSTALL_DIR}")
659+
if(NOT NETCDF_ENABLE_PLUGINS)
660+
unset(NETCDF_PLUGIN_INSTALL)
661+
unset(NETCDF_WITH_PLUGIN_DIR)
662+
endif()
663+
664+
if (DEFINED NETCDF_WITH_PLUGIN_DIR) # Table row 3
665+
set(DEFAULT_PLUGIN_INSTALL_DIR "${NETCDF_WITH_PLUGIN_DIR}")
666+
set(DEFAULT_PLUGIN_SEARCH_PATH "${NETCDF_WITH_PLUGIN_DIR}${PLATFORMSEP}${PLATFORMDEFAULT}")
667+
elseif (DEFINED CMAKE_INSTALL_PREFIX) # Table row 2
668+
set(DEFAULT_PLUGIN_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/hdf5/lib/plugin")
669+
set(DEFAULT_PLUGIN_SEARCH_PATH "${DEFAULT_PLUGIN_INSTALL_DIR}${PLATFORMSEP}${PLATFORMDEFAULT}")
670+
else() # Table row 1
671+
unset(DEFAULT_PLUGIN_INSTALL_DIR)
672+
set(DEFAULT_PLUGIN_SEARCH_PATH "${PLATFORMDEFAULT}")
673+
endif()
674+
# canonical form is all forward slashes
675+
string(REPLACE "\\" "/" DEFAULT_PLUGIN_INSTALL_DIR "${DEFAULT_PLUGIN_INSTALL_DIR}")
676+
string(REPLACE "\\" "/" DEFAULT_PLUGIN_SEARCH_PATH "${DEFAULT_PLUGIN_SEARCH_PATH}")
677+
678+
# Inferences
679+
if (DEFINED DEFAULT_PLUGIN_INSTALL_DIR)
680+
set(ENABLE_PLUGIN_DIR yes)
681+
else()
682+
set(ENABLE_PLUGIN_DIR no)
683+
endif()
684+
set(NETCDF_PLUGIN_INSTALL_DIR "${DEFAULT_PLUGIN_INSTALL_DIR}")
685+
set(NETCDF_PLUGIN_SEARCH_PATH "${DEFAULT_PLUGIN_SEARCH_PATH}")
716686

717687
# Try to enable NCZarr zip support
718688
option(NETCDF_ENABLE_NCZARR_ZIP "Enable NCZarr ZIP support." ${NETCDF_ENABLE_NCZARR})

cmake/modules/FindBlosc.cmake

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -26,17 +26,14 @@ IF(Blosc_INCLUDE_DIRS)
2626
GET_FILENAME_COMPONENT(Blosc_LIBRARY_DIRS ${Blosc_LIBRARY_DIRS} PATH)
2727
ENDIF("${Blosc_LIBRARY_DIRS}" MATCHES "/include$")
2828

29-
IF(EXISTS "${Blosc_LIBRARY_DIRS}/lib")
30-
SET(Blosc_LIBRARY_DIRS ${Blosc_LIBRARY_DIRS}/lib)
31-
ENDIF(EXISTS "${Blosc_LIBRARY_DIRS}/lib")
32-
3329
# Find Blosc libraries
3430
FIND_LIBRARY(Blosc_DEBUG_LIBRARY NAMES bloscd blosc_d libbloscd libblosc_d libblosc
3531
PATH_SUFFIXES Debug ${CMAKE_LIBRARY_ARCHITECTURE} ${CMAKE_LIBRARY_ARCHITECTURE}/Debug
36-
PATHS ${Blosc_LIBRARY_DIRS} NO_DEFAULT_PATH)
32+
PATHS ${Blosc_LIBRARY_DIRS} ${Blosc_LIBRARY_DIRS}/lib ${Blosc_LIBRARY_DIRS}/lib64 NO_DEFAULT_PATH)
3733
FIND_LIBRARY(Blosc_RELEASE_LIBRARY NAMES blosc libblosc
3834
PATH_SUFFIXES Release ${CMAKE_LIBRARY_ARCHITECTURE} ${CMAKE_LIBRARY_ARCHITECTURE}/Release
39-
PATHS ${Blosc_LIBRARY_DIRS} NO_DEFAULT_PATH)
35+
PATHS ${Blosc_LIBRARY_DIRS} ${Blosc_LIBRARY_DIRS}/lib ${Blosc_LIBRARY_DIRS}/lib64 NO_DEFAULT_PATH)
36+
4037

4138
SET(Blosc_LIBRARIES )
4239
IF(Blosc_DEBUG_LIBRARY AND Blosc_RELEASE_LIBRARY)

cmake/modules/FindSzip.cmake

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -29,17 +29,13 @@ IF(Szip_INCLUDE_DIRS)
2929
GET_FILENAME_COMPONENT(Szip_LIBRARY_DIRS ${Szip_LIBRARY_DIRS} PATH)
3030
ENDIF("${Szip_LIBRARY_DIRS}" MATCHES "/include$")
3131

32-
IF(EXISTS "${Szip_LIBRARY_DIRS}/lib")
33-
SET(Szip_LIBRARY_DIRS ${Szip_LIBRARY_DIRS}/lib)
34-
ENDIF(EXISTS "${Szip_LIBRARY_DIRS}/lib")
35-
3632
# Find Szip libraries
3733
FIND_LIBRARY(Szip_DEBUG_LIBRARY NAMES szipd szip_d libszipd libszip_d szip libszip sz2 libsz2
3834
PATH_SUFFIXES Debug ${CMAKE_LIBRARY_ARCHITECTURE} ${CMAKE_LIBRARY_ARCHITECTURE}/Debug
39-
PATHS ${Szip_LIBRARY_DIRS} NO_DEFAULT_PATH)
35+
PATHS ${Szip_LIBRARY_DIRS} ${Szip_LIBRARY_DIRS}/lib ${Szip_LIBRARY_DIRS}/lib64 NO_DEFAULT_PATH)
4036
FIND_LIBRARY(Szip_RELEASE_LIBRARY NAMES szip libszip sz libsz sz2 libsz2
4137
PATH_SUFFIXES Release ${CMAKE_LIBRARY_ARCHITECTURE} ${CMAKE_LIBRARY_ARCHITECTURE}/Release
42-
PATHS ${Szip_LIBRARY_DIRS} NO_DEFAULT_PATH)
38+
PATHS ${Szip_LIBRARY_DIRS} ${Szip_LIBRARY_DIRS}/lib ${Szip_LIBRARY_DIRS}/lib64 NO_DEFAULT_PATH)
4339

4440
SET(Szip_LIBRARIES)
4541
SET(Szip_LIBRARY)

config.h.cmake.in

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,12 @@ are set when opening a binary file on Windows. */
163163
/* if true, Allow dynamically loaded plugins */
164164
#cmakedefine NETCDF_ENABLE_PLUGINS 1
165165

166+
/* Define the plugin install dir */
167+
#cmakedefine NETCDF_PLUGIN_INSTALL_DIR "${NETCDF_PLUGIN_INSTALL_DIR}"
168+
169+
/* Define the plugin search path */
170+
#cmakedefine NETCDF_PLUGIN_SEARCH_PATH "${NETCDF_PLUGIN_SEARCH_PATH}"
171+
166172
/* if true, enable S3 support */
167173
#cmakedefine NETCDF_ENABLE_S3 1
168174

configure.ac

Lines changed: 62 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -2143,67 +2143,82 @@ fi
21432143

21442144
AC_SUBST(STD_FILTERS,[$std_filters])
21452145

2146-
# Internally, the variable HDF5_PLUGIN_PATH
2147-
# is always used as a surrogate for the default
2148-
# plugin path. If it was not defined by the user,
2149-
# then set it internally.
2150-
if test "x${HDF5_PLUGIN_PATH}" = x ; then
2151-
if test "x$ISMSVC" = xyes || test "x$ISMINGW" = xyes; then
2152-
HDF5_PLUGIN_PATH="${ALLUSERSPROFILE}\\hdfd5\\lib\\plugin"
2153-
else
2154-
HDF5_PLUGIN_PATH="/usr/local/hdf5/lib/plugin"
2155-
fi
2156-
fi
2157-
2158-
# The --with-plugin-dir gives the user control of the plugin
2159-
# directory. If set to 'yes' (the default), then the last directory in
2160-
# HDF5_PLUGIN_PATH is used (see above).
2146+
# The --with-plugin-dir option gives the user control of the plugin install
2147+
# directory. This also used as one of the default plugin directory when
2148+
# searching for plugins.
21612149
# If a specific directory is provided, it will be used.
2162-
# If 'no', then plugins will not be installed.
2163-
2150+
# If not defined or defined with the value no, or --without-plugin-dir, then
2151+
# plugin installation will be suppressed (but see below).
21642152
AC_MSG_CHECKING([whether and where we should install plugins])
2165-
AC_ARG_WITH([plugin-dir], [AS_HELP_STRING([--with-plugin-dir=<absolute directory>|yes|no|--without-plugin-dir],
2153+
AC_ARG_WITH([plugin-dir], [AS_HELP_STRING([--with-plugin-dir=<absolute directory>|no|--without-plugin-dir],
21662154
[Install selected standard filters in specified or default directory])],
21672155
[],[with_plugin_dir=no])
21682156
AC_MSG_RESULT([$with_plugin_dir])
2157+
21692158
# Using selected filter options forces installation
21702159
if test "x$have_zstd" = xyes; then
2171-
if test "x$enable_plugins" = xyes && test "x$with_plugin_dir" = xno; then
2172-
AC_MSG_WARN([--enable_filter-zstd => --with-plugin-dir.])
2173-
with_plugin_dir=yes
2174-
fi
2175-
fi
2176-
if test "x$with_plugin_dir" = xno ; then # option missing|disabled
2177-
with_plugin_dir=no
2178-
with_plugin_dir_setting="N.A."
2179-
enable_plugin_dir=no
2180-
elif test "x$with_plugin_dir" != x ; then
2181-
if test "x$with_plugin_dir" != xyes && test "x$with_plugin_dir" != xno ; then
2182-
# Presume true directory
2183-
HDF5_PLUGIN_PATH="${with_plugin_dir}"
2184-
fi
2160+
AC_MSG_WARN([--enable_filter-zstd => --enable-plugins.])
2161+
enable_plugins=yes
21852162
fi
21862163

2187-
# Use the last dir (lowest search priority) in HDF5_PLUGIN_PATH
2188-
PLUGIN_PATH="$HDF5_PLUGIN_PATH"
2164+
# Note: the term PLATFORMDEFAULT stands for:
2165+
# -- /usr/loca/hdf5/lib/plugin If on a *nix* machine
2166+
# -- %ALLUSERSPROFILE%/hdf5/lib/plugins If on a windows or Mingw platform
21892167
if test "x$ISMSVC" = xyes || test "x$ISMINGW" = xyes; then
2190-
PLUGIN_DIR=`echo "$PLUGIN_PATH" | tr ';' ' '`
2168+
PLATFORMDEFAULT="${ALLUSERSPROFILE}\\hdf5\\lib\\plugin"
2169+
PLATFORMSEP=";"
21912170
else
2192-
PLUGIN_DIR=`echo "$PLUGIN_PATH" | tr ':;' ' '`
2171+
PLATFORMDEFAULT="/usr/local/hdf5/lib/plugin"
2172+
PLATFORMSEP=":"
2173+
fi
2174+
2175+
# Internally, the variable DEFAULT_PLUGIN_INSTALL_DIR is the default
2176+
# directory into which plugins are installed; this may be undefined if
2177+
# plugin installation is disabled (the usual case). It is exported as
2178+
# NETCDF_PLUGIN_INSTALL_DIR.
2179+
#
2180+
# Similarly the variable DEFAULT_PLUGIN_SEARCH_PATH is the default list
2181+
# of directories to search to locate plugins. It is exported as
2182+
# NETCDF_PLUGIN_SEARCH_PATH
2183+
#
2184+
# See the document docs/pluginpath.md for a more detailed discussion
2185+
# of how NETCDF_PLUGIN_INSTALL_DIR and NETCDF_PLUGIN_SEARCH_PATH are
2186+
# computed.
2187+
2188+
# Canonicalize --with-prefix-dir and --prefix
2189+
if test "x$with_plugin_dir" = xno ; then unset with_plugin_dir ; fi
2190+
if test "xprefix" = x ; then prefix=NONE ; fi
2191+
if test "x$with_plugin_dir" != x ; then # Table row 3
2192+
DEFAULT_PLUGIN_INSTALL_DIR="${with_plugin_dir}"
2193+
DEFAULT_PLUGIN_SEARCH_PATH="${with_plugin_dir}${PLATFORMSEP}${PLATFORMDEFAULT}"
2194+
elif test "x$prefix" != xNONE ; then # Table row 2
2195+
DEFAULT_PLUGIN_INSTALL_DIR="${prefix}/hdf5/lib/plugin"
2196+
DEFAULT_PLUGIN_SEARCH_PATH="${prefix}/hdf5/lib/plugin${PLATFORMSEP}${PLATFORMDEFAULT}"
2197+
else # Table row 1
2198+
unset DEFAULT_PLUGIN_INSTALL_DIR
2199+
DEFAULT_PLUGIN_SEARCH_PATH="${PLATFORMDEFAULT}"
21932200
fi
2194-
last=
2195-
for pp in ${PLUGIN_DIR} ; do last="$pp"; done
2196-
PLUGIN_DIR="$last"
2197-
with_plugin_dir_setting="$PLUGIN_DIR"
21982201
# canonical form is all forward slashes
2199-
with_plugin_dir=`echo "$PLUGIN_DIR" | tr '\\\\' '/'`
2200-
enable_plugin_dir=yes
2201-
AC_MSG_NOTICE([Final --with-plugin-dir=$with_plugin_dir])
2202+
DEFAULT_PLUGIN_INSTALL_DIR=`echo "$DEFAULT_PLUGIN_INSTALL_DIR" | tr '\\\\' '/'`
2203+
DEFAULT_PLUGIN_SEARCH_PATH=`echo "$DEFAULT_PLUGIN_SEARCH_PATH" | tr '\\\\' '/'`
2204+
2205+
# Inferences
2206+
if test "x$DEFAULT_PLUGIN_INSTALL_DIR" = x ; then # option missing|disabled
2207+
enable_plugin_dir=no
2208+
else
2209+
enable_plugin_dir=yes
2210+
fi
2211+
2212+
if test "x$enable_plugin_dir" = xyes ; then
2213+
AC_DEFINE([ENABLE_PLUGIN_DIR], [1], [If true, enable filter installation])
2214+
fi
2215+
22022216
AM_CONDITIONAL([ENABLE_PLUGIN_DIR], [test "x$enable_plugin_dir" = xyes])
2203-
AC_SUBST([PLUGIN_INSTALL_DIR], [$with_plugin_dir])
2204-
# Better value for libnetcdf.settings
2205-
AC_SUBST([PLUGIN_INSTALL_DIR_SETTING], [$with_plugin_dir_setting])
2206-
AC_SUBST(NETCDF_PLUGIN_INSTALL_DIR, [$PLUGIN_INSTALL_DIR])
2217+
AC_DEFINE_UNQUOTED([NETCDF_PLUGIN_INSTALL_DIR], ["${DEFAULT_PLUGIN_INSTALL_DIR}"], [Final Install Dir])
2218+
AC_DEFINE_UNQUOTED([NETCDF_PLUGIN_SEARCH_PATH], ["${DEFAULT_PLUGIN_SEARCH_PATH}"], [Final Search Path])
2219+
AC_SUBST([NETCDF_PLUGIN_INSTALL_DIR], [${DEFAULT_PLUGIN_INSTALL_DIR}])
2220+
AC_SUBST([NETCDF_PLUGIN_SEARCH_PATH], [${DEFAULT_PLUGIN_SEARCH_PATH}])
2221+
22072222
# Access netcdf specific version of config.h
22082223
AH_BOTTOM([#include "ncconfigure.h"])
22092224

docs/pluginpath.md

Lines changed: 41 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -75,30 +75,52 @@ This initial global plugin path will be propagated to HDF5 and NCZarr.
7575
At build-time, the target location directory into which libraries implementing plugins are installed is specified using a special *./configure* option
7676
````
7777
--with-plugin-dir=<directorypath>
78-
or
79-
--with-plugin-dir
8078
````
8179
or its corresponding *cmake* option.
8280
````
83-
-DNETCDF_PLUGIN_INSTALL_DIR=<directorypath>
84-
or
85-
-DNETCDF_PLUGIN_INSTALL_DIR=YES
81+
-DNETCDF_WITH_PLUGIN_DIR=<directorypath>
8682
````
87-
If this option is specified but with no specific directory,
88-
then it defaults to one of three values:
89-
1. If *HDF5\_PLUGIN\_PATH* defined, then use the last directory in that path,
90-
2. else use `/usr/local/hdf5/lib/plugin` for linux/unix operating systems (including Cygwin) else use
91-
3. `%ALLUSERSPROFILE%\\hdf5\\lib\\plugin` for Windows and MinGW.
9283

93-
If the option is specified with an absolute directory path, then all plugin libraries will be installed in that directory only.
94-
95-
If the option is not specified at all, or one of the following options is used,
96-
then no attempt will be made to install plugins.
97-
````
98-
--without-plugin-dir
99-
or (cmake)
100-
-DNETCDF_PLUGIN_INSTALL_DIR=NO
101-
````
84+
## Build-Time Operations
85+
86+
At build time, certain plugin-related constants are constructed.
87+
1. NETCDF_PLUGIN_INSTALL_DIR -- the directory into which compiled plugins should be installed
88+
2. NETCDF_PLUGIN_SEARCH_PATH -- the default search path to be used at run-time if not over-ridden by the *HDF5_PLUGIN_PATH* environment variable.
89+
90+
<table style="border:2px solid black;border-collapse:collapse">
91+
<tr style="outline: thin solid;" align="center"><td colspan="4">Table showing the build-time computation of DEFAULT_PLUGIN_INSTALL_DIR and DEFAULT_PLUGIN_SEARCH_PATH.</td>
92+
<tr style="outline: thin solid" ><th>--with-plugin-dir<th>--prefix<th>DEFAULT_PLUGIN_INSTALL_DIR<th>DEFAULT_PLUGIN_SEARCH_PATH
93+
<tr style="outline: thin solid" ><td>undefined<td>undefined<td>undefined<td>PLATFORMDEFALT
94+
<tr style="outline: thin solid" ><td>undefined<td>&lt;abspath-prefix&gt;<td>&lt;abspath-prefix&gt;/hdf5/lib/plugin<td>&lt;abspath-prefix&gt;/hdf5/lib/plugin&lt;SEP&gt;PLATFORMDEFALT
95+
<tr style="outline: thin solid" ><td>&lt;abspath-plugins&gt;<td>N.A.<td>&lt;abspath-plugins&gt;<td>&lt;abspath-plugins&gt;&lt;SEP&gt;PLATFORMDEFALT
96+
</table>
97+
98+
Notes:
99+
1. HDF5_PLUGIN_PATH is ignored at build time.
100+
101+
2. ';' is used as a placeholder for PLATFORMSEP.
102+
103+
3. The term PLATFORMDEFAULT stands for:
104+
- /usr/local/hdf5/lib/plugin If on a *nix* machine
105+
- %ALLUSERSPROFILE%/hdf5/lib/plugins If on a windows or Mingw platform
106+
4. The term SEP stands for:
107+
- ':' If on a *nix* machine
108+
- ';' If on a windows or Mingw platform
109+
110+
## Run-Time Operations
111+
112+
When the netcdf-c library initializes itself (at runtime), it chooses an
113+
initial global plugin path for the config.h value.
114+
This value defaults to *NETCDF_PLUGIN_SEARCH_PATH*.
115+
If, however, HDF5_PLUGIN_PATH is defined, then it is used to override
116+
*NETCDF_PLUGIN_SEARCH_PATH*.
117+
118+
<table style="border:2px solid black;border-collapse:collapse">
119+
<tr style="outline: thin solid" align="center"><td colspan="2">Table showing the computation of the initial global plugin path</td>
120+
<tr style="outline: thin solid"><th>HDF5_PLUGIN_PATH<th>Initial global plugin path
121+
<tr style="outline: thin solid"><td>undefined<td>NETCDF_PLUGIN_SEARCH_PATH
122+
<tr style="outline: thin solid"><td>&lt;path1;...pathn&gt;<td>&lt;path1;...pathn&gt;
123+
</table>
102124

103125
## Multi-Threaded Access to the Plugin Path.
104126
Specifically, note that modifying the plugin path must be done "atomically".

0 commit comments

Comments
 (0)