Please help comment on hdf/netcdf compatability
Patrice Dumas
pertusus at free.fr
Sat Feb 18 12:01:34 UTC 2006
> I also maintain gdl, which can be linked against both hdf and netcdf,
> but I get complaints. I don't know if gdl can use the netcdf API in the
> hdf library or not - looking into it (if you know, tell me!).
I have read the code (now that I understand a bit more those issues), and
it seems to me that
- for netcdf gdl uses the netcdf 3 api exclusively.
- for hdf, gdl uses the SD* api, and not the netcdf-2 api.
So, as long as static libs are used it seems possible to mix hdf library
containing the netcdf 2 api and netcdf libray also containing the netcdf
2 api, as gdl don't use any of those api. I have tested, ld gives
warnings about symbols that changed size, but none of those symbols are
used. I have only tested on i386 maybe it breaks on other platform.
Once shared libs are used, it is likely that using the sd_ interface will
be required for gdl. So I believe keeping -DHAVE_NETCDF is the right
thing to do.
> Those of you who use both, what would you like to see?
grads uses the netcdf API of hdf, so I could not rebuild it anymore. However
I think that grads should be able to detect that it should use the sd_
variant (that is hdf compiled with -DHAVE_NETCDF). I have allready
contacted the upstream about that. I also have fixed grads to use both
hdf versions. So it is fine with me.
Maybe the best solution would be to have 2 libraries coming with hdf, one
that defines sd_ symbols, which could be the allready existing mfhdf lib,
and another that only defines the netcdf 2 api symbols. Some C
preprocessing could be used to generate 2 object files from the same
source, and the library that only defines the netcdf 2 api could be
named otherwise, for example dfnetcdf. And the headers should be rearranged
accordingly.
note1: unrelated, but if you contact the gdl upstream, tests for missing
numarray/numarray.h (from python-numarray) are not in configure, so it
fails during make).
note2: I made autoconf macros for hdf and netcdf detection, I personally
think that they are better than the one in gdl, as they search in more
places, and try to find the right version for the netcdf api. But they are
much more complicated and would require a change in the configure.in,
so... (I think i allready did my advertising, but I don't abandon so
easily now that I know that these macros could really be usefull for
gdl...).
--
Pat
-------------- next part --------------
dnl AC_CHECK_HDF : Check for hdf4
dnl args : action-if-yes, action-if-no
AC_DEFUN([AC_CHECK_HDF4],
[
AC_ARG_WITH([hdf4],
[AS_HELP_STRING([--with-hdf4=ARG],[hdf4 directory])],
[HDF4_PATH=$withval],
[HDF4_PATH=""])
AC_ARG_WITH([hdf4_include],
[AS_HELP_STRING([--with-hdf4-include=ARG],[hdf 4 include directory])],
[HDF4_PATH_INC=$withval],
[HDF4_PATH_INC=""])
AC_ARG_WITH([hdf4_libdir],
[AS_HELP_STRING([--with-hdf4-libdir=ARG],[hdf 4 library directory])],
[HDF4_PATH_LIBDIR=$withval],
[HDF4_PATH_LIBDIR=""])
dnl This is a very common location for the hdf4 code. jhrg 10/11/05
dnl AS_IF([test -d /usr/local/hdf], [HDF4_PATH="/usr/local/hdf"])
AS_IF([test "z$HDF4_PATH" != "z"],
[
AS_IF([test "z$HDF4_PATH_LIBDIR" = "z"],
[HDF4_PATH_LIBDIR="$HDF4_PATH/lib"])
AS_IF([test "z$HDF4_PATH_INC" = "z"],
[HDF4_PATH_INC="$HDF4_PATH/include"])
])
ac_hdf4_lib_ok='no'
ac_hdf4_save_LDFLAGS=$LDFLAGS
HDF4_LIBS=
AS_IF([test "z$HDF4_PATH_LIBDIR" != "z"],
[
HDF4_LDFLAGS="-L$HDF4_PATH_LIBDIR"
LDFLAGS="$LDFLAGS $HDF4_LDFLAGS"
AC_CHECK_HDF4_LIB([ac_hdf4_lib_ok='yes'])
],
[
for ac_hdf4_libdir in "" /usr/local/hdf4.2r1/lib /opt/hdf4.2r1/lib \
/usr/hdf4.2r1/lib /usr/local/lib/hdf4.2r1 /opt/lib/hdf4.2r1 \
/usr/lib/hdf4.2r1 /usr/local/hdf/lib/ /opt/hdf/lib /usr/hdf/lib \
/usr/local/lib/hdf /opt/lib/hdf /usr/lib/hdf ; do
AS_IF([test "z$ac_hdf4_libdir" = 'z'],
[HDF4_LDFLAGS=],
[
AC_MSG_NOTICE([searching hdf libraries in $ac_hdf4_libdir])
HDF4_LDFLAGS="-L$ac_hdf4_libdir"
])
LDFLAGS="$LDFLAGS $HDF4_LDFLAGS"
AC_CHECK_HDF4_LIB([ac_hdf4_lib_ok='yes'])
AS_IF([test $ac_hdf4_lib_ok = 'yes'],[break])
LDFLAGS=$ac_hdf4_save_LDFLAGS
done
])
LDFLAGS=$ac_hdf4_save_LDFLAGS
ac_hdf4_h='no'
HDF4_CPPFLAGS=
ac_hdf4_save_CPPFLAGS=$CPPFLAGS
AS_IF([test "z$HDF4_PATH_INC" != "z"],
[
HDF4_CPPFLAGS="-I$HDF4_PATH_INC"
CPPFLAGS="$CPPFLAGS $HDF4_CPPFLAGS"
AC_CHECK_HEADER_NOCACHE_HDF4([mfhdf.h],[ac_hdf4_h='yes'])
],
[
for ac_hdf4_incdir in "" /usr/local/hdf4.2r1/include /opt/hdf4.2r1/include \
/usr/hdf4.2r1/include /usr/local/include/hdf4.2r1 \
/opt/include/hdf4.2r1 /usr/include/hdf4.2r1 /usr/local/hdf/include \
/opt/hdf/include /usr/hdf/include /usr/local/include/hdf \
/opt/include/hdf /usr/include/hdf ; do
AS_IF([test "z$ac_hdf4_incdir" = 'z'],
[HDF4_CPPFLAGS=],
[
AC_MSG_NOTICE([searching hdf includes in $ac_hdf4_incdir])
HDF4_CPPFLAGS="-I$ac_hdf4_incdir"
])
CPPFLAGS="$CPPFLAGS $HDF4_CPPFLAGS"
AC_CHECK_HEADER_NOCACHE_HDF4([mfhdf.h],[ac_hdf4_h='yes'])
AS_IF([test $ac_hdf4_h = 'yes'],[break])
CPPFLAGS=$ac_hdf4_save_CPPFLAGS
done
])
CPPFLAGS=$ac_hdf4_save_CPPFLAGS
AS_IF([test "$ac_hdf4_h" = 'yes' -a "$ac_hdf4_lib_ok" = 'yes'],
[m4_if([$1], [], [:], [$1])],
[m4_if([$2], [], [:], [$2])])
AC_SUBST([HDF4_LIBS])
AC_SUBST([HDF4_CPPFLAGS])
AC_SUBST([HDF4_LDFLAGS])
])
dnl check for the netcdf 2 interface provided by hdf
dnl it defines the C preprocessor macro HDF_NETCDF_NAME(name) which
dnl prepends sd_ to name if needed and otherwise keep the name
dnl as is.
dnl
dnl args action-if-found,
dnl action-if-found with sd_ appended to netcdf symbols,
dnl action-if-no-found
dnl
dnl in case it is detected that sd_ should be appended, the C preprocessor
dnl symbol HDF_SD_NETCDF is defined.
AC_DEFUN([AC_CHECK_HDF4_NETCDF],
[
ac_hdf4_netcdf_lib='no'
ac_hdf4_sd_netcdf_lib='no'
ac_hdf4_netcdf_h='no'
AC_CHECK_HDF4([
ac_hdf4_netcdf_save_LDFLAGS=$LDFLAGS
ac_hdf4_netcdf_save_LIBS=$LIBS
LIBS="$LIBS $HDF4_LIBS"
LDFLAGS="$LDFLAGS $HDF4_LDFLAGS"
AC_MSG_CHECKING([for sd_ncopen])
AC_LINK_IFELSE([AC_LANG_CALL([],[sd_ncopen])],
[
AC_MSG_RESULT([yes])
ac_hdf4_sd_netcdf_lib='yes'
],
[
AC_MSG_RESULT([no])
ac_hdf4_sd_netcdf_lib='no'
])
AS_IF([test "$ac_hdf4_sd_netcdf_lib" = 'no'],
[
AC_MSG_CHECKING([for ncopen with hdf link flags])
AC_LINK_IFELSE([AC_LANG_CALL([],[ncopen])],
[
AC_MSG_RESULT([yes])
ac_hdf4_netcdf_lib='yes'
],
[
AC_MSG_RESULT([no])
ac_hdf4_netcdf_lib='no'
])
])
LDFLAGS=$ac_hdf4_netcdf_save_LDFLAGS
LIBS=$ac_hdf4_netcdf_save_LIBS
ac_hdf4_netcdf_save_CPPFLAGS=$CPPFLAGS
CPPFLAGS="$CPPFLAGS $HDF4_CPPFLAGS"
AC_CHECK_NETCDF_HEADER([],[ac_hdf4_netcdf_h='yes'])
CPPFLAGS=$ac_hdf4_netcdf_save_CPPFLAGS
])
AH_TEMPLATE([HDF_NETCDF_NAME],[A macro that append sd_ to netcdf symbols if needed])
AS_IF([test $ac_hdf4_netcdf_h = 'yes' -a $ac_hdf4_sd_netcdf_lib = 'yes'],
[
AC_DEFINE([HDF_SD_NETCDF],[],[Define if hdf prefixes netcdf symbols by sd])
AC_DEFINE([HDF_NETCDF_NAME(name)], [sd_ ## name])
m4_if([$2], [], [:], [$2])
],
[
AC_DEFINE([HDF_NETCDF_NAME(name)], [name])
AS_IF([test $ac_hdf4_netcdf_h = 'yes' -a $ac_hdf4_netcdf_lib = 'yes'],
[m4_if([$1], [], [:], [$1])],
[m4_if([$3], [], [:], [$3])])
])
])
AC_DEFUN([AC_CHECK_HDF4_LIB],
[
HDF4_LIBS=
ac_hdf4_save_LIBS=$LIBS
AC_CHECK_LIB_NOCACHE_HDF4([sz], [SZ_BufftoBuffCompress],
[
LIBS="$LIBS -lsz"
HDF4_LIBS='-lsz'
])
dnl -lsz is not required because due to licencing it may not be present
dnl nor required everywhere
ac_hdf4_lib='no'
AC_CHECK_LIB_NOCACHE_HDF4([z],[deflate],
[ AC_CHECK_LIB_NOCACHE_HDF4([jpeg],[jpeg_start_compress],
[ AC_CHECK_LIB_NOCACHE_HDF4([df],[Hopen],
[ AC_CHECK_LIB_NOCACHE_HDF4([mfhdf],[SDstart],
[ ac_hdf4_lib="yes"
HDF4_LIBS="-lmfhdf -ldf -ljpeg -lz $HDF4_LIBS"
],[],[-ldf -ljpeg -lz])
],[],[-ljpeg -lz])
])
])
LIBS=$ac_hdf4_save_LIBS
AS_IF([test "$ac_hdf4_lib" = 'yes'],
[m4_if([$1], [], [:], [$1])],
[m4_if([$2], [], [:], [$2])])
])
AC_DEFUN([AC_CHECK_LIB_NOCACHE_HDF4],
[
AS_TR_SH([ac_check_lib_nocache_ok_$1_$2])='no'
AS_TR_SH([ac_check_lib_nocache_$1_$2_LIBS])=$LIBS
LIBS="-l$1 $5 $LIBS"
AC_MSG_CHECKING([for $2 in -l$1])
AC_LINK_IFELSE([AC_LANG_CALL([], [$2])],
[
AS_TR_SH([ac_check_lib_nocache_ok_$1_$2])='yes'
AC_MSG_RESULT([yes])
],[
AC_MSG_RESULT([no])
])
LIBS=$AS_TR_SH([ac_check_lib_nocache_$1_$2_LIBS])
AS_IF([test $AS_TR_SH([ac_check_lib_nocache_ok_$1_$2]) = 'yes'],
[m4_if([$3], [], [:], [$3])],
[m4_if([$4], [], [:], [$4])])
])
AC_DEFUN([AC_CHECK_HEADER_NOCACHE_HDF4],
[
AS_TR_SH([ac_check_header_nocache_compile_$1])='no'
AS_TR_SH([ac_check_header_nocache_preproc_$1])='no'
AC_MSG_CHECKING([for $1 with compiler])
AC_COMPILE_IFELSE([AC_LANG_SOURCE([[#include <$1>]])],
[
AC_MSG_RESULT([yes])
AS_TR_SH([ac_check_header_nocache_compile_$1])='yes'
],
[
AC_MSG_RESULT([no])
])
AC_MSG_CHECKING([for $1 with preprocessor])
AC_PREPROC_IFELSE([AC_LANG_SOURCE([[#include <$1>]])],
[
AC_MSG_RESULT([yes])
AS_TR_SH([ac_check_header_nocache_preproc_$1])='yes'
],
[
AC_MSG_RESULT([no])
AS_IF([test "$AS_TR_SH([ac_check_header_nocache_compile_$1])" = 'yes'],
[AC_MSG_WARN([trusting compiler result, ignoring preprocessor error])])
])
AS_IF([test "$AS_TR_SH([ac_check_header_nocache_compile_$1])" = 'yes'],
[m4_if([$2], [], [:], [$2])],
[m4_if([$3], [], [:], [$3])])
])
-------------- next part --------------
# Check for the netcdf header.
# AC_CHECK_NETCDF_HEADER([INCLUDE-DIR],[ACTION-IF-FOUND],
# [ACTION-IF-NOT-FOUND],[INTERFACE-NR])
# if interface number is given, check for a specific interface
# sets NC_CPPFLAGS and maybe NC_NETCDF_3_CPPFLAG
AC_DEFUN([AC_CHECK_NETCDF_HEADER],
[
NC_CPPFLAGS=
ac_netcdf_h='no'
ac_netcdf_h_compile='no'
ac_netcdf_h_preproc='no'
ac_nc_include_dir=
ac_nc_header_interface=
ac_nc_save_CPPFLAGS=$CPPFLAGS
m4_if([$1],[],[:],[
ac_nc_include_dir="$1"
AS_IF([test "z$ac_nc_include_dir" != "z"],
[CPPFLAGS="$CPPFLAGS -I$ac_nc_include_dir"])
])
m4_if([$4],[],[:],[ac_nc_header_interface=$4])
dnl dont use AC_CHECK_HEADERS to avoid autoconf internal caching
AC_MSG_CHECKING([for netcdf.h with compiler])
AC_COMPILE_IFELSE([AC_LANG_SOURCE([[#include <netcdf.h>]])],
[
AC_MSG_RESULT([yes])
ac_netcdf_h_compile='yes'
],
[
AC_MSG_RESULT([no])
ac_netcdf_h_compile='no'
])
AC_MSG_CHECKING([for netcdf.h with preprocessor])
AC_PREPROC_IFELSE([AC_LANG_SOURCE([[#include <netcdf.h>]])],
[
AC_MSG_RESULT([yes])
ac_netcdf_h_preproc='yes'
],
[
AC_MSG_RESULT([no])
ac_netcdf_h_preproc='no'
])
CPPFLAGS="$ac_nc_save_CPPFLAGS"
AS_IF([test $ac_netcdf_h_compile = 'yes'],
[ac_netcdf_h='yes'
AS_IF([test "z$ac_nc_header_interface" = 'z3'],
[AC_CHECK_NETCDF_3_HEADER([$1],
[ac_netcdf_h='yes'],[ac_netcdf_h='no'])])
])
AS_IF([test "$ac_netcdf_h" = 'yes'],
[
AS_IF([test "z$ac_nc_include_dir" != "z"],
[NC_CPPFLAGS="-I$ac_nc_include_dir"])
m4_if([$2], [], [:], [$2])
],
[m4_if([$3], [], [:], [$3])])
AC_SUBST([NC_CPPFLAGS])
])
AC_DEFUN([AC_CHECK_NETCDF_3_HEADER],
[
NC_NETCDF_3_CPPFLAG=
ac_check_netcdf_3_include=
ac_check_netcdf_3_header='no'
ac_nc_save_CPPFLAGS=$CPPFLAGS
AC_MSG_CHECKING([for netcdf 3 interface])
m4_if([$1],[],[:],[
ac_check_netcdf_3_include="$1"
])
AS_IF([test "z$ac_check_netcdf_3_include" != "z"],
[CPPFLAGS="$CPPFLAGS -I$ac_check_netcdf_3_include"])
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <netcdf.h>]],
[[int status;
int ncid;
status = nc_open("foo.nc", 0, &ncid);
char vernum;
vernum = *nc_inq_libvers();]])],
[
AS_IF([test "z$ac_check_netcdf_3_include" != "z"],
[NC_NETCDF_3_CPPFLAG="-I$ac_check_netcdf_3_include"])
ac_check_netcdf_3_header='yes'
],[ac_check_netcdf_3_header='no'])
CPPFLAGS=$ac_nc_save_CPPFLAGS
AS_IF([test "$ac_check_netcdf_3_header" = 'yes'],
[
AC_MSG_RESULT([yes])
m4_if([$2], [], [:], [$2])
],
[
AC_MSG_RESULT([no])
m4_if([$3], [], [:], [$3])
])
AC_SUBST([NC_NETCDF_3_CPPFLAG])
])
-------------- next part --------------
dnl example of use
dnl AC_CHECK_NETCDF(
dnl [
dnl LIBS="$LIBS $NC_LIBS"
dnl LDFLAGS="$LDFLAGS $NC_LDFLAGS"
dnl CPPFLAGS="$CPPFLAGS $NC_CPPFLAGS"
dnl ],
dnl [
dnl echo "*** Use --with-netcdf for the root netcdf directory."
dnl echo "*** Otherwise use --with-netcdf-include switch for includes directory"
dnl echo "*** and --with-netcdf-libdir switch for libraries directory."
dnl AC_MSG_ERROR([netcdf library and netcdf headers are required.])
dnl ]
dnl )
# Check for the netcdf library.
# AC_CHECK_NETCDF([ACTION-IF-FOUND],[ACTION-IF-NOT-FOUND],[INTERFACE-NR])
# if interface number is given, check for a specific interface
# sets NC_LDFLAGS, NC_LIBS, and, by calling other macros
# NC_CPPFLAGS and maybe NC_NETCDF_3_CPPFLAG
AC_DEFUN([AC_CHECK_NETCDF],
[
AC_ARG_WITH([netcdf],
[AS_HELP_STRING([--with-netcdf=ARG],[netcdf directory])],
[NC_PATH=$withval],
[NC_PATH=""])
AC_ARG_WITH([netcdf_include],
[AS_HELP_STRING([--with-netcdf-include=ARG],[netcdf include directory])],
[NC_PATH_INC=$withval],
[NC_PATH_INC=""])
AC_ARG_WITH([netcdf_libdir],
[AS_HELP_STRING([--with-netcdf-libdir=ARG],[netcdf library directory])],
[NC_PATH_LIBDIR=$withval],
[NC_PATH_LIBDIR=""])
AS_IF([test "z$NC_PATH" != "z"],
[
AS_IF([test "z$NC_PATH_LIBDIR" = "z"],[NC_PATH_LIBDIR="$NC_PATH/lib"])
AS_IF([test "z$NC_PATH_INC" = "z"],[NC_PATH_INC="$NC_PATH/include"])
])
ac_netcdf_ok='no'
NC_LIBS=
NC_LDFLAGS=
ac_nc_save_LDFLAGS=$LDFLAGS
ac_nc_save_LIBS=$LIBS
ac_check_nc_func_checked='ncopen'
ac_check_nc_interface=
dnl the interface number isn't quoted with "" otherwise a newline
dnl following the number isn't stripped.
m4_if([$3],[],[ac_check_nc_interface=2],[ac_check_nc_interface=$3])
AS_IF([test "z$ac_check_nc_interface" = 'z3'],
[ac_check_nc_func_checked='nc_open'])
AS_IF([test "z$NC_PATH_LIBDIR" != "z"],
[
NC_LDFLAGS="-L$NC_PATH_LIBDIR"
LDFLAGS="$LDFLAGS $NC_LDFLAGS"
dnl the autoconf internal cache isn't avoided because we really check for
dnl libnetcdf, other libraries that implement the same api have other names
dnl AC_LINK_IFELSE([AC_LANG_CALL([],[$ac_check_func_checked])],
AC_CHECK_LIB([netcdf],[$ac_check_nc_func_checked],
[
NC_LIBS='-lnetcdf'
ac_netcdf_ok='yes'
])
],
[
for ac_netcdf_libdir in "" \
/usr/local/netcdf-${ac_check_nc_interface}/lib \
/opt/netcdf-${ac_check_nc_interface}/lib \
/usr/netcdf-${ac_check_nc_interface}/lib \
/usr/local/lib/netcdf-${ac_check_nc_interface} \
/opt/lib/netcdf-${ac_check_nc_interface} \
/usr/lib/netcdf-${ac_check_nc_interface} \
/usr/local/netcdf/lib /opt/netcdf/lib \
/usr/netcdf/lib /usr/local/lib/netcdf /opt/lib/netcdf \
/usr/lib/netcdf ; do
AS_IF([test "z$ac_netcdf_libdir" = 'z'],
[NC_LDFLAGS=],
[
AC_MSG_CHECKING([for netcdf libraries in $ac_netcdf_libdir])
NC_LDFLAGS="-L$ac_netcdf_libdir"
])
LDFLAGS="$LDFLAGS $NC_LDFLAGS"
LIBS="$LIBS -lnetcdf"
dnl we have to avoid the autoconf internal cache in that case
AC_LINK_IFELSE([AC_LANG_CALL([],[$ac_check_nc_func_checked])],
[
NC_LIBS='-lnetcdf'
ac_netcdf_ok='yes'
AS_IF([test "z$ac_netcdf_libdir" != 'z'],[AC_MSG_RESULT([yes])])
],
[
AS_IF([test "z$ac_netcdf_libdir" != 'z'],[AC_MSG_RESULT([no])])
])
AS_IF([test $ac_netcdf_ok = 'yes'],[break])
LDFLAGS=$ac_nc_save_LDFLAGS
LIBS=$ac_nc_save_LIBS
done
])
LDFLAGS=$ac_nc_save_LDFLAGS
LIBS=$ac_nc_save_LIBS
AC_SUBST([NC_LDFLAGS])
AC_SUBST([NC_LIBS])
ac_netcdf_header='no'
AS_IF([test "z$NC_PATH_INC" != "z"],
[
AC_CHECK_NETCDF_HEADER([$NC_PATH_INC],
[ac_netcdf_header='yes'],
[ac_netcdf_header='no'],
[$ac_check_nc_interface])
],
[
for ac_netcdf_incdir in "" \
/usr/local/netcdf-${ac_check_nc_interface}/include \
/opt/netcdf-${ac_check_nc_interface}/include \
/usr/netcdf-${ac_check_nc_interface}/include \
/usr/local/include/netcdf-${ac_check_nc_interface} \
/opt/include/netcdf-${ac_check_nc_interface} \
/usr/include/netcdf-${ac_check_nc_interface} \
/usr/local/netcdf/include \
/opt/netcdf/include /usr/netcdf/include /usr/local/include/netcdf \
/opt/include/netcdf /usr/include/netcdf ; do
AC_MSG_NOTICE([searching netcdf includes in $ac_netcdf_incdir])
AC_CHECK_NETCDF_HEADER([$ac_netcdf_incdir],[ac_netcdf_header='yes'],
[ac_netcdf_header='no'],[$ac_check_nc_interface])
AS_IF([test $ac_netcdf_header = 'yes'],[break])
done
])
AS_IF([test "$ac_netcdf_ok" = 'no' -o "$ac_netcdf_header" = 'no'],
[m4_if([$2], [], [:], [$2])],
[m4_if([$1], [], [:], [$1])])
])
More information about the fedora-extras-list
mailing list