Skip to content

Conversation

sgoth
Copy link
Contributor

@sgoth sgoth commented May 26, 2025

Contains two changes around how zlib-ng/zlib is handled in cmake.

  1. Fixes minizip-ng-config.cmake relies on non-existant zlib-ng-config.cmake #722 by renaming FindZLIBNG to FindZLIB-NG (and all internal naming for consistency)
    It works with ZLIBNG to build minizip-ng itself but leads cmake to put a call to find_dependency(ZLIBNG REQUIRED) that searches for zlibng-config.cmake in its generated minizip-ng-config.cmake when the actual config is called zlib-ng-config.cmake

  2. Adds a new MZ_ZLIB_FLAVOR cmake variable that allows either auto|zlib-ng|zlib defaulting to auto (unchanged behavior).
    This puts users in control of the used zlib implementation should both be available.
    Especially via package managers the old situation leads to "silently" linking the wrong library if the package manager provides zlib but zlib-ng is still found as a system wide installation.

Let me know if i should split these into 2 PRs.

sgoth added 2 commits May 26, 2025 14:07
Instead of assuming zlib-ng preference over zlib as a dependency, let
the user decide.

New cmake variable MZ_ZLIB_FLAVOR can be set to auto | zlib-ng | zlib
defaults to auto.
@sgoth
Copy link
Contributor Author

sgoth commented May 26, 2025

I tested against a system wide zlib-ng 2.2.4, zlib 1.3.1 and vcpkg zlib 1.3.1

@fekstrom
Copy link

fekstrom commented Jun 6, 2025

I was running into the same problem, so am happy to see that it's being worked on :) The proposed fix improves things for me but there are still some wrinkles.

My use case is to make a local installation of minizip-ng built against zlib-ng, and then build a project against that. Starting from

.
|-- a_project
|-- minizip-ng
`-- zlib-ng

where minizip-ng is at sgoth:zlib-ng-fixes (57d1e28), I run

cmake -S zlib-ng -B build/zlib-ng \
  -D CMAKE_BUILD_TYPE=Release \
  -D CMAKE_INSTALL_PREFIX=$PWD/install
cmake --build build/zlib-ng --config Release --target install

cmake -S minizip-ng -B build/minizip-ng -D MZ_FETCH_LIBS=OFF \
    -D CMAKE_BUILD_TYPE=Release \
    -D CMAKE_INSTALL_PREFIX=$PWD/install \
    -D CMAKE_PREFIX_PATH=$PWD/install
cmake --build build/minizip-ng --config Release --target install

cmake -S a_project -B build/a_project \
    -D CMAKE_BUILD_TYPE=Release \
    -D CMAKE_PREFIX_PATH=$PWD/install
cmake --build build/a_project --config Release

A couple of observations:

  1. On Ubuntu, the find_package(ZLIB-NG) call of the minizip-ng build uses FindZLIB-NG.cmake and not the zlib-ng-config.cmake that is provided by zlib-ng. The transitive call to find_package(ZLIB-NG) in the a_project build on the other hand uses zlib-ng-config.cmake and not FindZLIB-NG.cmake (because FindZLIB-NG.cmake is not in the CMake module path at that point). This can be seen by adding -D CMAKE_FIND_DEBUG_MODE=ON in the CMake configuration steps.
  2. On Windows, the configuration of minizip-ng doesn't find the local installation of zlib-ng, as indicated by the message "ZLIB library not found". Using -D CMAKE_FIND_DEBUG_MODE=ON shows that the find_library call in FindZLIB-NG.cmake fails. The names of the installed libraries are zlib-ng.lib, zlib-ng2.dll, zlibstatic-ng.lib, whereas find_library is looking for (variations of) z-ng, libz-ng, libz-ng.a.

Now that zlib-ng provides zlib-ng-config.cmake, is FindZLIB-NG.cmake still needed? In most cases I think it's preferable to rely on the config file provided by the dependency (e.g., zlib-ng) rather than implementing a find script in the consumer (e.g., minizip-ng), because

  • The config file is mostly generated by CMake, with current knowledge of the names of things in the dependency project, so it's more likely to be correct and cover all cases,
  • If some special handling is needed for the dependency, it's better to have a single implementation of that in the dependency project than to have one implementation in every consumer.

In my case, the inconsistency in 1 and the issue in 2 can be fixed by removing FindZLIB-NG.cmake and replacing the lines

list(APPEND MINIZIP_INC ${ZLIB-NG_INCLUDE_DIRS})
list(APPEND MINIZIP_LIB ${ZLIB-NG_LIBRARIES})
list(APPEND MINIZIP_LBD ${ZLIB-NG_LIBRARY_DIRS})

by

list(APPEND MINIZIP_LIB zlib-ng::zlib)

This links ${MINIZIP_TARGET} against the zlib-ng::zlib target, which adds both include directories and link libraries. (I'm not familiar with the CMake conventions of minizip-ng, so I don't know whether MINIZIP_LIB is the right variable to use for CMake targets, as opposed to just library names.)

Note that zlib-ng-config.cmake was added in zlib-ng 2.1.7, so if it's important for minizip-ng to be compatible with earlier versions, FindZLIB-NG.cmake would still be needed (perhaps only used as a fallback for that case). Of course, there may also be other reasons for keeping FindZLIB-NG.cmake that I'm not aware of.

@sgoth
Copy link
Contributor Author

sgoth commented Jun 10, 2025

Thanks for testing!

A couple of observations:

1. On Ubuntu, the find_package(ZLIB-NG) call of the minizip-ng build uses FindZLIB-NG.cmake and not the zlib-ng-config.cmake that is provided by zlib-ng. The transitive call to find_package(ZLIB-NG) in the a_project build on the other hand uses zlib-ng-config.cmake and not FindZLIB-NG.cmake (because FindZLIB-NG.cmake is not in the CMake module path at that point). This can be seen by adding `-D CMAKE_FIND_DEBUG_MODE=ON` in the CMake configuration steps.

That's totally fine - as long as both ways find the same things it doesn't really matter.

2. On Windows, the configuration of minizip-ng doesn't find the local installation of zlib-ng, as indicated by the message "ZLIB library not found". Using `-D CMAKE_FIND_DEBUG_MODE=ON` shows that the find_library call in FindZLIB-NG.cmake fails. The names of the installed libraries are zlib-ng.lib, zlib-ng2.dll, zlibstatic-ng.lib, whereas find_library is looking for (variations of) z-ng, libz-ng, libz-ng.a.

FindZLIB-NG sounds just broken for Windows then...

Now that zlib-ng provides zlib-ng-config.cmake, is FindZLIB-NG.cmake still needed? In most cases I think it's preferable to rely on the config file provided by the dependency (e.g., zlib-ng) rather than implementing a find script in the consumer
[...]
Note that zlib-ng-config.cmake was added in zlib-ng 2.1.7, so if it's important for minizip-ng to be compatible with earlier versions, FindZLIB-NG.cmake would still be needed (perhaps only used as a fallback for that case). Of course, there may also be other reasons for keeping FindZLIB-NG.cmake that I'm not aware of.

I'd second that. Could replace 1176a22 but the other change would stay the same.

To just disable zlib-ng usage i ended up using CMAKE_DISABLE_FIND_PACKAGE_ZLIBNG=1 in vcpkg.

@Coeur
Copy link
Collaborator

Coeur commented Jun 18, 2025

@nmoinvaz @sgoth @fekstrom is that fine to merge this PR in its current state?

I was thinking yes.

@sgoth
Copy link
Contributor Author

sgoth commented Jun 18, 2025

@nmoinvaz @sgoth @fekstrom is that fine to merge this PR in its current state?

I was thinking yes.

In short: yes

  • it fixes consuming minizip-ng on all systems that can be built against zlib-ng (all but Windows seemingly)
  • it provides a dedicated switch to select between zlib-ng and zlib instead of always preferring zlib-ng when it is there but doesn't change the current behavior by default

For Windows, building minizip-ng against zlib-ng doesn't seem to work at all. That is unchanged by this PR.
This is best fixed by depending on zlib-ngs cmake config but raises the depended version of zlib-ng as @fekstrom suggested/noted.

If it were my project i'd merge this and treat the rest as separate issues.
Either follow up with fixing FindZLIB-NG.cmake for Windows or removing the file completely and bumping the zlib-ng version dependency.

Copy link
Member

@nmoinvaz nmoinvaz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry for the delay, I have not been in the best of health.

@@ -39,6 +39,16 @@ message(STATUS "Using CMake version ${CMAKE_VERSION}")
option(MZ_COMPAT "Enables compatibility layer" ON)
# Compression library options
option(MZ_ZLIB "Enables ZLIB compression" ON)

# Controls to select either zlib-ng or zlib
set(MZ_ZLIB_FLAVOR "auto" CACHE STRING "Select the preferred zlib flavor - auto searches for zlib-ng then zlib")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it possible to use option() here?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should the README be updated to include the new option?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, updating the readme for that is a good idea

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it possible to use option() here?

option is boolean - it could be framed as MZ_ZLIB_PREFER_ZLIB-NG or something like that.
Not sure if that's any better but i can do that if you provide the name 😅

With MZ_SANITIZER we already do it with a string "option".

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should the README be updated to include the new option?

Done

@nmoinvaz nmoinvaz enabled auto-merge (rebase) June 19, 2025 15:51
@nmoinvaz nmoinvaz merged commit 0969e94 into zlib-ng:develop Jun 19, 2025
28 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

minizip-ng-config.cmake relies on non-existant zlib-ng-config.cmake
4 participants