HDFGroup / hdf5

Official HDF5® Library Repository
https://www.hdfgroup.org/
Other
627 stars 256 forks source link

HDF5 finds the wrong zlib #4904

Open haampie opened 1 month ago

haampie commented 1 month ago

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)

Additional context Add any other context about the problem here.

byrnHDF commented 1 month ago

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 commented 3 weeks ago

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.