hdf5 icon indicating copy to clipboard operation
hdf5 copied to clipboard

HDF5 finds the wrong zlib

Open haampie opened this issue 1 year ago • 5 comments

Describe the bug

HDF5 uses find_package(ZLIB ... COMPONENTS ...) before it falls back to find_package(ZLIB) in CMakeFilters.cmake. The former call scans the system for a CMake config file (due to COMPONENTS). The latter call uses the builtin FindZLIB.cmake module.

Calling find_package twice is problematic because it messes up the search order: if a user configures HDF5 with CMAKE_PREFIX_PATH=/path/to/my/zlib, and this zlib does not have an associated CMake config file, HDF5 will ignore it and pick up a system zlib if it has a config file.

The problem happens for example on Fedora 40 after dnf install zlib-devel, which installs the file

/usr/lib64/cmake/ZLIB/ZLIB.cmake

which is picked up by the first find_package call. The second find_package call which would have found the intended zlib in the higher priority search directory is then ignored.

Expected behavior

As a user, if I pass -DCMAKE_PREFIX_PATH=/path/to/zlib (without cmake config file), HDF5 should use this zlib, not system zlib (with cmake config file).

Further, I would not expect HDF5 to prefer CMake config files at all, given that the promoted build system for zlib is their configure script, which obviously does not create a CMake config file.

I would strongly suggest to use one and only one find_package call, and use ZLIB_USE_STATIC_LIBS introduced in CMake 3.24 instead of rolling your own.

Platform (please complete the following information)

  • HDF5 version: any version in the last decade, specifically any after 4d0187a4832a60d56bc077a43855b91b8518271c
  • OS and version: any OS that has a system ZLIB.cmake, for example Fedora 40 with zlib-devel installed
  • Build system and version: CMake at any version.

Additional context Add any other context about the problem here.

haampie avatar Oct 01 '24 08:10 haampie

I would prefer a different solution then this as this is not a guarantee for all the systems we support. CMake has a number of options to find_package: [NO_DEFAULT_PATH] [NO_CMAKE_ENVIRONMENT_PATH] [NO_CMAKE_PATH] [NO_SYSTEM_ENVIRONMENT_PATH] [NO_CMAKE_PACKAGE_REGISTRY] [NO_CMAKE_BUILDS_PATH] [NO_CMAKE_SYSTEM_PATH] [NO_CMAKE_SYSTEM_PACKAGE_REGISTRY] [CMAKE_FIND_ROOT_PATH_BOTH | ONLY_CMAKE_FIND_ROOT_PATH | NO_CMAKE_FIND_ROOT_PATH])

Furthermore: `The CMake variable CMAKE_FIND_ROOT_PATH specifies one or more directories to be prepended to all other search directories. This effectively “re-roots” the entire search under given locations. Paths which are descendants of the CMAKE_STAGING_PREFIX are excluded from this re-rooting, because that variable is always a path on the host system. By default the CMAKE_FIND_ROOT_PATH is empty.

The CMAKE_SYSROOT variable can also be used to specify exactly one directory to use as a prefix. Setting CMAKE_SYSROOT also has other effects. See the documentation for that variable for more.

These variables are especially useful when cross-compiling to point to the root directory of the target environment and CMake will search there too. By default at first the directories listed in CMAKE_FIND_ROOT_PATH are searched, then the CMAKE_SYSROOT directory is searched, and then the non-rooted directories will be searched. The default behavior can be adjusted by setting CMAKE_FIND_ROOT_PATH_MODE_PACKAGE. This behavior can be manually overridden on a per-call basis. By using CMAKE_FIND_ROOT_PATH_BOTH the search order will be as described above. If NO_CMAKE_FIND_ROOT_PATH is used then CMAKE_FIND_ROOT_PATH will not be used. If ONLY_CMAKE_FIND_ROOT_PATH is used then only the re-rooted directories and directories below CMAKE_STAGING_PREFIX will be searched.`

One of these might be useful

byrnHDF avatar Oct 01 '24 14:10 byrnHDF

I will be investigating all the issues with the zlib and szip functionality in the HDF5 CMake code. There are a variety of ways to build hdf5 with zlib/szip support and it's time to re-evaluate that code before the end of the year.

byrnHDF avatar Oct 29 '24 16:10 byrnHDF

Any news?

In my opinion HDF5 should not decide for the user to enforce config mode search for zlib. Just do ordinary find_package. Users can pass -DCMAKE_FIND_PACKAGE_PREFER_CONFIG=ON. See also #5155 where a user accidentally has a cmake config file for zlib in their search path, but they mean to link to system libz from macOS.

haampie avatar Jan 24 '25 15:01 haampie

I second @haampie suggestion that since zlib does not ship its config.cmake (Since last week they started to provided a config file https://github.com/madler/zlib/blob/develop/zlibConfig.cmake.in) files there is no need to use the find_package(CONFIG) invocation, in fact as @haampie the basic invocation of find_package will search for the config if the module is not found.

I recommend to specify the locations of the your packages using Package_ROOT which should be understood by your ZLIB_ROOT=zlibinstallationprefix, here is an extract of the cmake findzlib:

Hints
^^^^^

A user may set ``ZLIB_ROOT`` to a zlib installation root to tell this
module where to look.

This will have a greater preference compared to CMAKE_PREFIX_PATH and avoid you to use the system zlib.

vicentebolea avatar Feb 08 '25 00:02 vicentebolea

#5280 should address these concerns.

byrnHDF avatar Feb 10 '25 14:02 byrnHDF