Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CMake and Zlib #831

Open
Neustradamus opened this issue Jul 30, 2023 · 69 comments
Open

CMake and Zlib #831

Neustradamus opened this issue Jul 30, 2023 · 69 comments

Comments

@Neustradamus
Copy link

Neustradamus commented Jul 30, 2023

@madler: It is possible to solve all problems and merge some PRs?

Thanks in advance.

Issues:

PRs:

I have not finished:

Linked to:
@Mizux, @albrematt, @johnb003, @miurahr, @WildCard65, @wrowe, @ScatteredRay, @jnhyatt, @Jihadist, @hwhsu1231, @mtl1979, @ClausKlein, @sum01, @craigscott-crascit, @hjmallon, @mattparks, @puneetmatharu, @vszakats, @tbeu, @fredgan, @RobinGeffroy, @jfern2011, @kirankotari, @etiennearnal, @omegacoleman, @yyzworker, @yalcinerbora, @niparx, @navidR, @lperron, @vguen, @tr1cks, @AndrewAtAvenza, @gvollant, @hopeless-programmer-online, @glebm, @jheaff1, @SpaceIm, @AraHaan, @pzychotic, @siepkes, @schultetwin1, @Bagira80, @wantehchang, @dankegel, @chanphil, @MichaelGoulding, @stkruse, next after.

@nmoinvaz

@madler
Copy link
Owner

madler commented Aug 18, 2023

There are too many cmake issues and pull requests for me to go through and disposition them, and I wouldn't know what's good or bad anyway. I very much like @Mizux 's suggestion to have a group render on, coordinate, and most importantly verify proposed cmake changes. My main concern are proposed changes that work in one case, but messes up a bunch of others. Ideally this group would be able to cover a good set of platforms.

@nmoinvaz
Copy link
Contributor

You might want to give interested parties Triage access to the repository to help manage all the GitHub issues.

You could decide to merge in PRs based on the number of GitHub code review approvals.

I’d say stick to only merging changes that are absolutely necessary or ones that fix problems that lead to many duplicate issues.

@vszakats
Copy link

vszakats commented Aug 18, 2023

It would help a lot if someone with the necessary rights could approve the CI for PRs. Mine has been pending for 1+ year with no test run.
Screen Shot 2023-08-18 at 11 52 59

@ClausKlein
Copy link

ClausKlein commented Aug 18, 2023

My Feature/improve cmake #347 is ready to merge.
And it past CI https://github.com/ClausKlein/zlib/actions

@vszakats
Copy link

vszakats commented Aug 18, 2023

@ClausKlein Neat workaround for the blocked CI.

My #677 passes green, and ready to merge too.
Screen Shot 2023-08-18 at 17 57 02

@Neustradamus
Copy link
Author

@ClausKlein: Nice :)

I hope it will be a good beginning!

@madler, can you look?

@Neustradamus
Copy link
Author

@vszakats: Can you look improvements from @ClausKlein to adapt your PR?

@vszakats
Copy link

vszakats commented Aug 18, 2023

@Neustradamus Both PRs touch the buggy if(NOT MINGW) line enabling zlib1.rc. My patch fixes it for all targets (it needs the other changes in my PR), including MSYS builds. #347 fixes it for MSYS.

Can't see anything else I could adapt from the other PR, they are targeting different issues.

UPDATE: to my RC comment above: missed a NOT when reading it up earlier today, so both patches are correct, and if(NOT MINGW) should end up as if(WIN32) to fix it proper.

@ClausKlein
Copy link

I see this diff on my branch to #667, should I apply it?

diff --git a/CMakeLists.txt b/CMakeLists.txt
index d4eb7cb..19ac18b 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -121,7 +121,7 @@ set(ZLIB_SRCS
     zutil.c
 )
 
-if(NOT MINGW AND NOT MSYS)
+if(WIN32)
     set(ZLIB_DLL_SRCS
         win32/zlib1.rc # If present will override custom build rule below.
     )
diff --git a/win32/Makefile.gcc b/win32/Makefile.gcc
index 081e391..35172fb 100644
--- a/win32/Makefile.gcc
+++ b/win32/Makefile.gcc
@@ -50,7 +50,7 @@ AR = $(PREFIX)ar
 ARFLAGS = rcs
 
 RC = $(PREFIX)windres
-RCFLAGS = --define GCC_WINDRES
+RCFLAGS =
 
 STRIP = $(PREFIX)strip
 
diff --git a/win32/zlib1.rc b/win32/zlib1.rc
index ceb4ee5..5253b6a 100644
--- a/win32/zlib1.rc
+++ b/win32/zlib1.rc
@@ -1,11 +1,7 @@
 #include <winver.h>
 #include "../zlib.h"
 
-#ifdef GCC_WINDRES
 VS_VERSION_INFO		VERSIONINFO
-#else
-VS_VERSION_INFO		VERSIONINFO	MOVEABLE IMPURE LOADONCALL DISCARDABLE
-#endif
   FILEVERSION		ZLIB_VER_MAJOR,ZLIB_VER_MINOR,ZLIB_VER_REVISION,0
   PRODUCTVERSION	ZLIB_VER_MAJOR,ZLIB_VER_MINOR,ZLIB_VER_REVISION,0
   FILEFLAGSMASK		VS_FFI_FILEFLAGSMASK

@vszakats
Copy link

I think we are better keeping PRs granular and each fixing distinct problems, so I'd keep them separate. I'm also fine with rebasing if necessary. This makes it easier to later bisect where a problem was introduced or track down what changed and why. Our issue IMO is that none of the CMake patches are actually merged. (Unless we want to somehow offer one "megapatch" solving all issues at once, which is possible but needs a great amount of work and testing.)

@mtl1979
Copy link

mtl1979 commented Aug 19, 2023

I see this diff on my branch to #667, should I apply it?

diff --git a/CMakeLists.txt b/CMakeLists.txt
index d4eb7cb..19ac18b 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -121,7 +121,7 @@ set(ZLIB_SRCS
     zutil.c
 )
 
-if(NOT MINGW AND NOT MSYS)
+if(WIN32)
     set(ZLIB_DLL_SRCS
         win32/zlib1.rc # If present will override custom build rule below.
     )

As far as I know, MINGW and MSYS are defined only with few most recent versions of cmake, so testing them not being defined makes very little sense. I know some people think that we all should use very latest version of cmake, but the reality is that some people still use older versions of cmake for own valid reasons. The core idea of zlib has been to support very old systems, not the very latest like some zlib forks do.

@vszakats
Copy link

My patch (#677) fixes that by deleting all MINGW uses (even though zlib has been relying on it since 2011). Also MSYS is not necessary there after that.

@mtl1979
Copy link

mtl1979 commented Aug 19, 2023

MINGW

MINGW was added in cmake 3.2 and MSYS was added in cmake 3.14. My own work PC has cmake 3.10.2 installed in /usr/bin/.

@vszakats
Copy link

vszakats commented Aug 19, 2023

CMake documented it in 3.2 (2015-03-04) indeed, but zlib's use predates that: dc5a43e (2011-09-09) by almost 4 years. Even more interestingly, the first introduction of MINGW in CMake happened on 2003-08-21: Kitware/CMake@a413160, predating its 2.4 (2006-04-18) release (their first tagged one in Git) by 3 years. (Git log goes back to year 2000.)

MINGW seems safe to use, but we don't need this macro here and it causes bugs even when defined correctly by CMake.

@mtl1979
Copy link

mtl1979 commented Aug 19, 2023

CMake documented it in 3.2 (2015-03-04) indeed, but zlib's use predates that: dc5a43e (2011-09-09) by almost 4 years. Even more interestingly, the first introduction of MINGW in CMake happened on 2003-08-21: Kitware/CMake@a413160, predating its 2.4 (2006-04-18) release (their first tagged one in Git) by 3 years. (Git log goes back to year 2000.)

MINGW seems safe to use, but we don't need this macro here and it causes bugs even when defined correctly by CMake.

MSYS2 still seems to define __CYGWIN__ on my machine and older MinGW versions did also define it. This obviously only matters due to UNIX also getting defined even though it shouldn't when using MinGW.

I agree that there is bugs in some versions of cmake when it comes to relying to correct variables getting defined. Some projects manually define these and not rely on cmake defining them automatically.

@vszakats
Copy link

vszakats commented Aug 19, 2023

Current zlib solution for RC compilation is a toolchain-specific hack, and broken. Question: Was it purposefully done that way to support ancient CMake versions? Was it an oversight? CMake does support .rc files transparently since at least August 2006, according to CMake authors. zlib sets the CMake minimum to 2.4.4 (2006-11-20). Yet, the current solution was committed in 2011. This makes me think this was an oversight rather than intentional. If so, the current hack seems safe to replace with the solution suggested in 2006 by CMake authors (as in #677).

Also, are the resource optimization flags targeting Windows 16-bit (3.11 from 1992-04-06) intentionally kept there or is it okay to delete them yet?

It'd be useful to get answers or any kind of feedback instead of guessing and pushing PRs that are perhaps wrong or not desired by zlib. This would help getting out of the CMake-stall we experience. CMake being the only standard tool to build zlib with, this also seems critical.

@vszakats
Copy link

vszakats commented Aug 19, 2023

@mtl1979: __CYGWIN__ is a C compiler macro, not CMake. It's defined by MSYS2's MSYS toolchain (but not in mingw toolchains) and by Cygwin. It's been defined from the early days of these tools, so pretty reliable.

mingw-64 (and old mingw32) (= MINGW) are always WIN32 and never UNIX. MSYS2's msys builds (MSYS) and Cygwin are UNIX and never WIN32.

IMO we should deal with those if an actual fallout is reported and not optimize for niche tool bugs upfront. I've personally found these macros working as expected.

@mtl1979
Copy link

mtl1979 commented Aug 19, 2023

@mtl1979: __CYGWIN__ is a C compiler macro, not CMake. It's defined by MSYS2's MSYS toolchain (but not in mingw toolchains) and by Cygwin. It's been defined from the early days of these tools, so pretty reliable.

cmake uses preprocessor to detect the operating system as seen on the patch posted above.

@vszakats
Copy link

cmake uses preprocessor to detect the operating system as seen on the patch posted above.

It seems correct to me. This is also the initial commit for this feature, so it doesn't tell the full story.

Anyhow I don't to seem get where this discussion is heading, so closing up my PR and will continue to patch the zlib build I maintain.

@ClausKlein
Copy link

MINGW

MINGW was added in cmake 3.2 and MSYS was added in cmake 3.14. My own work PC has cmake 3.10.2 installed in /usr/bin/.

pip install cmake ninja would help ..

@mtl1979
Copy link

mtl1979 commented Aug 19, 2023

pip install cmake ninja would help ..

pip doesn't replace anything installed in /usr/bin and Linux would still use cmake in /usr/bin as the path is cached in shell.

I also don't understand what ninja has to do with cmake being too old.

@mtl1979
Copy link

mtl1979 commented Aug 19, 2023

Also, are the resource optimization flags targeting Windows 16-bit (3.11 from 1992-04-06) intentionally kept there or is it okay to delete them yet?

zlib is supposed to support 16-bit and 32-bit operating systems... In recent days the support for 64-bit operating systems (and larger compressed files) has gotten better and more complete.

@vszakats
Copy link

vszakats commented Aug 19, 2023

@mtl1979: Re-read what I wrote, or look at the patch. This concerned three four Windows Resource (.rc) optional flags, meant to save a few bytes on Windows 3.x 16-bit, when loading ZLIB.DLL. FWIW the whole .rc is optional. No code is affected. Portability not affected. I also offered an alternate patch excluding this change and soliciting feedback. Without feedback it's impossible to read what zlib finds acceptable. What is your point?

I'm back to the less obtrusive workaround for the bug I'm hitting. #347 would also help because BUILD_SHARED_LIBS=OFF is broken too. That's a 5+ years old PR.

@Neustradamus
Copy link
Author

Maybe some people can look for this ticket:

@dbjh
Copy link

dbjh commented Feb 12, 2024

I wonder when people will start drawing the obvious conclusions about CMake. Of course there are many justifications to its use like being locked in or having no power or say, but it is clearly requiring enormous amounts of time and energy investments to just use it properly (in all its edge cases). At some point the madness has to stop.
A possible solution would be to be very accepting to each and every PR related to CMake, were it not that CMake dictates the structure of software development. It does not adapt to existing practices, but insists that its rules are followed. Perhaps an alternative could be another support project with all the bells and whistles of CMake to which zlib can be copied?

@mtl1979
Copy link

mtl1979 commented Feb 12, 2024

I wonder when people will start drawing the obvious conclusions about CMake. Of course there are many justifications to its use like being locked in or having no power or say, but it is clearly requiring enormous amounts of time and energy investments to just use it properly (in all its edge cases). At some point the madness has to stop. A possible solution would be to be very accepting to each and every PR related to CMake, were it not that CMake dictates the structure of software development. It does not adapt to existing practices, but insists that its rules are followed. Perhaps an alternative could be another support project with all the bells and whistles of CMake to which zlib can be copied?

CMake does have a lot of limitations but it's still somewhat easier to maintain than manually writing configure scripts... People have not used autoconf or automake in ages even though those were meant to help with creating configure scripts and Makefiles.

@dbjh
Copy link

dbjh commented Feb 12, 2024

I wonder when people will start drawing the obvious conclusions about CMake. Of course there are many justifications to its use like being locked in or having no power or say, but it is clearly requiring enormous amounts of time and energy investments to just use it properly (in all its edge cases). At some point the madness has to stop. A possible solution would be to be very accepting to each and every PR related to CMake, were it not that CMake dictates the structure of software development. It does not adapt to existing practices, but insists that its rules are followed. Perhaps an alternative could be another support project with all the bells and whistles of CMake to which zlib can be copied?

CMake does have a lot of limitations but it's still somewhat easier to maintain than manually writing configure scripts... People have not used autoconf or automake in ages even though those were meant to help with creating configure scripts and Makefiles.

Whichever is easier is to an extent a matter of opinion, but definitely a matter of a developer's experience. My criticism was directed towards CMake, not to suggest that the GNU Autotools are the best solution for zlib. But I can comment on that.

There are objective reasons why the infamous GNU Autotools are easier, for example one can decide to what degree to use them (generated or static Makefiles, generated config.h or not, free choice of other template files). So, there is a gentle learning curve compared to GNU Makefiles. Also, it builds on useful or already present knowledge, like shell scripting and said GNU Makefiles. There is a reason that the GNU Autotools are still widely used, but I see projects that offer support for one or more additional build systems.

You do realize that zlib is currently using something that is identical to the GNU Autotools, right? configure, Makefile template, header file templates. For minizip even Automake is used.

CMake is a very different story as any developer with enough experience can confirm. However, there is no need to convince anyone -- regardless CMake's supposed strengths or benefits we can see that support for CMake is a problem for zlib, hence this very GitHub issue.
I think it would avoid a lot of frustration to take a clear position towards the support for CMake in zlib. Either support it or not. As I said, supporting it means following its guidelines.

@robiwano
Copy link

My 2 cents on this is that CMake and Autotools are pretty much orthogonal to each other, and not supporting CMake would leave a very large community hanging. And it isn't really rocket science.

@dbjh
Copy link

dbjh commented Feb 12, 2024

My 2 cents on this is that CMake and Autotools are pretty much orthogonal to each other, and not supporting CMake would leave a very large community hanging. And it isn't really rocket science.

Thanks. I once met a rocket scientist who claimed that rocket science is not rocket science :-P I would claim that CMake is at least more frustrating than rocket science.

How would you describe the current situation? Is CMake currently supported? That is why I suggested 2 solutions:

  1. Be open to PRs regarding CMake. Clearly the current developers struggle with CMake support. There are open issues from 2016 and PRs from 2017.
  2. Have another support project run by developers who are well versed in CMake, but do not maintain zlib. It could contain a copy of zlib, or non at all, requiring developers to copy zlib to that project.

For people in favor of CMake the first option is obviousy most attractive. For the second option to work well, zlib needs to cooperate. However, now we have neither. In the end, the current developers decide, but anyone is free to fork...

@madler
Copy link
Owner

madler commented Feb 12, 2024

CMake is not rocket science, but I can attest that being a rocket scientist does not help with understanding CMake.

configure was not auto-generated — it is hand-written.

zlib will continue to support both configure/make and cmake. At least to the extent that anyone considers the current CMakeLists.txt to be supporting cmake.

No, this is not the place to debate whether 'tis better to cmake or not to cmake.

@mtl1979

There are forks of zlib that have improved CMake support, which makes it very easy to backport any applicable improvement.

@vszakats

Some long-time pending PRs are aiming for low-hanging issues and even those are not merged.

So who can be the judge of whether any given change is actually an improvement or not? It's not me. I don't just apply whatever commits willy nilly. Anyone can propose a change to CMakeLists.txt that fixes their local situation, but also screws up someone else's. Recently I reverted a CMakeLists.txt commit for that reason. In my opinion, we would need cmake testing across a wide variety of platforms, beyond what is available in github actions.

@vszakats
Copy link

vszakats commented Feb 12, 2024

@madler: I understand that. Judging contributions isn't an easy feat.

Perhaps one way to bootstrap this it is to merge the most reasonably solid-looking PRs, and/or to request peer-reviews for the most important ones. Or to require adding CI tests before merge. This would also assume that CI tests are actually allowed to run (manually or by default), because at the moment this isn't the case.

Adding CMake integration tests would also help, e.g. like this one.

Another option is to ask for as granular PRs as possible, targeting one specific issue at a time. While also separating style/format changes from logic changes.

I understand that all of this is work and not necessary a small amount, but zlib being probably the most exposed dependency out there, there is a good chance to distribute this among many interested contributors.

@joeyparrish
Copy link

@madler wrote:

zlib will continue to support both configure/make and cmake. At least to the extent that anyone considers the current CMakeLists.txt to be supporting cmake.

Please forgive me if I've misunderstood you, but does this mean that it is your position as maintainer that CMakeLists.txt is frozen now and will not change? This is an important detail for those of us who have issues using the existing cmake support for one reason or another.

@mtl1979
Copy link

mtl1979 commented Feb 12, 2024

So who can be the judge of whether any given change is actually an improvement or not? It's not me. I don't just apply whatever commits willy nilly. Anyone can propose a change to CMakeLists.txt that fixes their local situation, but also screws up someone else's. Recently I reverted a CMakeLists.txt commit for that reason. In my opinion, we would need cmake testing across a wide variety of platforms, beyond what is available in github actions.

I use three different CI providers myself, GitHub Actions is one of them. Besides Linux, MacOS and Windows, I can test pretty much any operating system that Google has CI image for, but mostly I just test different FreeBSD versions.

@madler
Copy link
Owner

madler commented Feb 12, 2024

@madler wrote:

zlib will continue to support both configure/make and cmake. At least to the extent that anyone considers the current CMakeLists.txt to be supporting cmake.

Please forgive me if I've misunderstood you, but does this mean that it is your position as maintainer that CMakeLists.txt is frozen now and will not change? This is an important detail for those of us who have issues using the existing cmake support for one reason or another.

No. Note the "At least" which you left out of your emphasis.

@Vollstrecker
Copy link

Because there are many projects out there that have the same issues with their cmake, there is a new project that tries to help. zlib is the first project that could benefit.

atm. I sorted and mostly implemented the pending pull request from here and then the issues will be worked out before reworking the rest to fit into modern times without going over the edge just to use a fancy new feature.

As for now the resources are limited I want to ask a) all the people here to wave a hand if they can test all the stuff on systems github has no runner for and/or b) to join and take an active part either for the rework of zlib and/or everything that will come in the future of https://github.com/cmake-remake

Tests will be implemented for linux, mac, windows, mingw (all flavours) and cygwin. Everyone that is able to test on other systems (also on these) is very welcome.

@nigels-com
Copy link

@Vollstrecker That's a good idea and thanks for taking the plunge. The litmus test is going to be able to come forward to new zlib releases with first-class cmake support out of the box. Our main dependencies are via libpng and the boost iostreams support for streamed gzip compression.

@madler
Copy link
Owner

madler commented Dec 1, 2024

@Vollstrecker Thank you! This sounds like exactly what I have been asking for. Please let me know when you think it's ready for prime time.

@Vollstrecker
Copy link

Sure, you'll get a PR as soon as the tests are done. FYI: I took the freedom to change the created lib to be named z on all platforms including windows. Static libs have a s suffix (zs.dll) and debug-builds get d appended (zd.dll/zsd.dll). As the export will create all targets to link against, noone will notice. For old stuff zlib1.dll is copied from z.dll. The copy can be deactivated via option but I'm not sure if it should better default to OFF.

Let me know if this is a bit too much for a start, or if something is unclear what I mean.

@vszakats
Copy link

vszakats commented Dec 1, 2024

@Vollstrecker Would it be possible to make the static suffix customisable and/or tweak it for MinGW? For MinGW specifically it's unexpected to use zs for static (as is libzlibstatic.a in current stable). On MinGW it's expected to use libz.a for static and libz.a.dll for shared by convention. This plays well with the toolchain's built-in shared/static selection logic too.

@Vollstrecker
Copy link

This get's more complicated, but if this was the case in the past, this needs to be preserved.

@nigels-com
Copy link

Would be nice to have optional overrides for all the static and shared library targets.
We don't want the 'd' suffix, for example, and might want to align with the zlib-ng naming we're already tied to, somewhat.

@Vollstrecker
Copy link

Sorry, but this a not a good reason. If you use zlib-ng you most likely use cmake. Then you just do find_package(zlib) and link against ZLIB::ZLIB or ZLIB:ZLIBSTATIC and don't have to care what the real name is.

Btw. zlib-ng pretents to be compatible drop-in, so any name zlib had in the past should also be supported by them. So the zlib-ng naming you already tied to should be the zlib naming like it was the past 10+ years.

The compat copy was intended for people that have a VS-project that has the old name hardcoded. If there was a different naming on mingw, then this will also be in the reworked version. This was never intended to give everyone the possibility to make up new names. I'm sure noone wants reports about failing compiles against a.dll b.dll c.dll just to find out at the end that a and c are 2 different versions of the same lib.

@nigels-com
Copy link

nigels-com commented Dec 1, 2024

I might be mis-remembering what was needed across our stack for zlib-ng. I'm confident your revamp here will get us at least 95% to cmake nirvana. (Nirvana = It "just works" without hacking at third party cmake)

Perhaps our complications are of our own making, due to a lot of static linking and a lot of things linking to zlib.

@vszakats
Copy link

vszakats commented Dec 2, 2024

Sorry, but this a not a good reason. If you use zlib-ng you most likely use cmake. Then you just do find_package(zlib) and link against ZLIB::ZLIB or ZLIB:ZLIBSTATIC and don't have to care what the real name is.

Btw. zlib-ng pretents to be compatible drop-in, so any name zlib had in the past should also be supported by them. So the zlib-ng naming you already tied to should be the zlib naming like it was the past 10+ years.

The compat copy was intended for people that have a VS-project that has the old name hardcoded. If there was a different naming on mingw, then this will also be in the reworked version. This was never intended to give everyone the possibility to make up new names. I'm sure noone wants reports about failing compiles against a.dll b.dll c.dll just to find out at the end that a and c are 2 different versions of the same lib.

In general there no guarantee that someone will use CMake to build a project depending on a CMake-built zlib. There is also no guarantee that a dependent project's CMake build will use cmake-config, or ZLIB::ZLIB.

Speaking of MinGW, -lz is expected to work with both shared and static builds.

The actual lib filenames do matter in a significant portion of the cases. (With zlib-ng this happens to work without issues with MinGW.)

edit: For debug libs, CMake has a built-in variable CMAKE_DEBUG_POSTFIX. It should be enough to control the debug suffix I think, if it can take effect. https://cmake.org/cmake/help/latest/variable/CMAKE_DEBUG_POSTFIX.html

edig 2: Speaking of MSVC (= non-MinGW) the static suffix becomes an issue

  1. if both static and shared is built and CMAKE_STATIC_LIBRARY_SUFFIX STREQUAL == CMAKE_IMPORT_LIBRARY_SUFFIX. This typically means MSVC.
    The solution is to force a different name for one of the output libs to avoid them overwriting each other throughout the build. It can be a custom suffix for one of the libs, or it can be a custom suffix for just the implib. There is no convention. Hence it's nice to allow configuration with a default matching what was used before.
  2. if a dependent has any expectation on the actual name, even if the output is shared only or static only.
    For this case it's useful to allow a custom suffix for at least one of them.

PR → cmake-remake#1

@Mr-Clam
Copy link

Mr-Clam commented Dec 2, 2024

There are some other useful patches that we have to apply to, which maybe you'd be willing to consider:

@Vollstrecker
Copy link

In general there no guarantee that someone will use CMake to build a project depending on a CMake-built zlib. There is also no guarantee that a dependent project's CMake build will use cmake-config, or ZLIB::ZLIB.

Not instantly, but it's a long term goal.

Speaking of MinGW, -lz is expected to work with both shared and static builds.

I first focused on Linux and Win, for sure everything that worked in the past has to work later also. I don't know how MinGW decides which one to choose if both are present, but I also don't really care.

The actual lib filenames do matter in a significant portion of the cases. (With zlib-ng this happens to work without issues with MinGW.)

And it will work with zlib aswell. But to be honest, zlib-ng is a different project and even if you had something to change to work with that, you can't expect that to still work here because it's a different project that does other cruel stuff. But I'm not here to talk about that.

edit: For debug libs, CMake has a built-in variable CMAKE_DEBUG_POSTFIX. It should be enough to control the debug suffix I think, if it can take effect. https://cmake.org/cmake/help/latest/variable/CMAKE_DEBUG_POSTFIX.html

Yep, and again I already have it in there and just didn't push. For 2 libs it doesn't really makes a big difference, but there is some stuff in contrib/ that needs that, too.

edig 2: Speaking of MSVC (= non-MinGW) the static suffix becomes an issue

Your'e confusing suffix and postfix. The postfix get's appended to the filename, the suffix is the actual extension. On MSVC (or plain Win in general) this is dll for both, that's why the postfix is there.

1. if both static and shared is built and `CMAKE_STATIC_LIBRARY_SUFFIX STREQUAL` == `CMAKE_IMPORT_LIBRARY_SUFFIX`. This typically means MSVC.
   The solution is to force a different name for one of the output libs to avoid them overwriting each other throughout the build. It can be a custom suffix for one of the libs, or it can be a custom suffix for just the implib. There is no convention. Hence it's nice to allow configuration with a default matching what was used before.

You mean like appending a d to libname or something like that? I'm pretty sure that is exactly what I'm doing.

2. if a dependent has any expectation on the actual name, even if the output is shared only or static only.
   For this case it's useful to allow a custom suffix for at least one of them.

This will apply for handcrafted projects (most commonly VS solutions) and I see 2 situations for this.

  1. They built zlib with the old build-scripts so they still can do and nothing changes.
  2. They already is cmake to build the lib, then there's no reason to not doing it for their stuff, too.

These 2 only occur on Windows as for any other system out there nothing changes at all.

PR → cmake-remake#1

Not that I wouldn't welcome useful PRs, but I don't like work in progress interrupts. But I can go through to clarify some points:

L83: Breaks on cygwin
L88: You use an option that only occurs there. No declaration, no documentation -> Black magic -> Not wanted.

For the rest: For me zlib1.dll is nothing for ever. If Windows would support it I would just symlink this. Somewhen in the future the compat will default to off and somewhen later it will disappear. Yes, this can take 10+ years.

It's nothing unusual that things change over time. If someone adopted the old cmake stuff here, it's no problem to adopt the new stuff also. I someone changed to zlib-ng, it's no problem to stay there or to change back. If someone builds the traditional way, it's no problem to just continue this.

I can fully understand every maintainer to not rework such stuff, as almost every time someone pops up with additional wishes and more time is used to discuss these than to do actual work on that. If something breaks, everyone can open an issue and it will get fixed. I want to use my old stuff the new way without updating is no issue.

I'm going to test this on as many platforms as I can and I'm going to also compile some other stuff against it. If you have examples that get problems, feel free to list them so I can check that, but please don't criticize work that's only half way done yet.

@vszakats
Copy link

vszakats commented Dec 2, 2024

edig 2: Speaking of MSVC (= non-MinGW) the static suffix becomes an issue

Your'e confusing suffix and postfix. The postfix get's appended to the filename, the suffix is the actual extension. On MSVC (or plain Win in general) this is dll for both, that's why the postfix is there.

Both are appended to the output filename, this particular
postfix variable first, then the suffix, which is just the end of
the filename and includes the extension.

Your draft force-adds a 3rd, initial suffix before the above postfix.

  1. if both static and shared is built and CMAKE_STATIC_LIBRARY_SUFFIX STREQUAL == CMAKE_IMPORT_LIBRARY_SUFFIX. This typically means MSVC.
    The solution is to force a different name for one of the output libs to avoid them overwriting each other throughout the build. It can be a custom suffix for one of the libs, or it can be a custom suffix for just the implib. There is no convention. Hence it's nice to allow configuration with a default matching what was used before.

You mean like appending a d to libname or something like that? I'm pretty sure that is exactly what I'm doing.

You're doing it for both debug and static, also unconditinally
and without a means to override. Your implementation also
does these by overriding the filename, instead of modifying
the SUFFIX property.

This will apply for handcrafted projects (most commonly VS solutions) and I see 2 situations for this.

  1. They built zlib with the old build-scripts so they still can do and nothing changes.

That makes this effort pointless IMO. The point would be to enable zlib CMake
build to replace the non-standard solution. If not pointless, it's an unnecessarily
lost opportunity.

Not that I wouldn't welcome useful PRs, but I don't like work in progress interrupts. But I can go through to clarify some points:

L83: Breaks on cygwin

Easy to fix by extending the condition to CYGWIN/MSYS.

Though as said there that GCC_WINDRES macro should
probably not exist in the first place.

edit: on a second look: the .rc is not supposed to be compiled
for Cygwin builds due to $<$<BOOL:${WIN32}>:win32/zlib1.rc>,
so I'm not sure how that could fail either with or without the
suggested MINGW fix.

The MINGW error:

[11/41] Building RC object CMakeFiles/zlib.dir/win32/zlib1.rc.res
FAILED: CMakeFiles/zlib.dir/win32/zlib1.rc.res 
/usr/local/bin/x86_64-w64-mingw32-windres -O coff -DNO_FSEEKO -DZLIB_DLL -D_LARGEFILE64_SOURCE=1 -I /.../zlib-cmake/_build-cmake-win -I /.../zlib-cmake  /.../zlib-cmake/win32/zlib1.rc CMakeFiles/zlib.dir/win32/zlib1.rc.res
/usr/local/bin/x86_64-w64-mingw32-windres: /.../zlib-cmake/win32/zlib1.rc:7: syntax error

L88: You use an option that only occurs there. No declaration, no documentation -> Black magic -> Not wanted.

There is nothing black magic in it. It's checking if the two output
filenames would collide. If you prefer you may replace it with
MSVC, which is most likely the same in practice.

For the rest: For me zlib1.dll is nothing for ever. If Windows would support it I would just symlink this. Somewhen in the future the compat will default to off and somewhen later it will disappear. Yes, this can take 10+ years.

It's nothing unusual that things change over time. If someone adopted the old cmake stuff here, it's no problem to adopt the new stuff also. I someone changed to zlib-ng, it's no problem to stay there or to change back. If someone builds the traditional way, it's no problem to just continue this.

I can fully understand every maintainer to not rework such stuff, as almost every time someone pops up with additional wishes and more time is used to discuss these than to do actual work on that. If something breaks, everyone can open an issue and it will get fixed. I want to use my old stuff the new way without updating is no issue.

I'm going to test this on as many platforms as I can and I'm going to also compile some other stuff against it. If you have examples that get problems, feel free to list them so I can check that, but please don't criticize work that's only half way done yet.

I'm not criticizing your work, but raising issues that I had found in
the last two years dealing with CMake builds of curl and libssh2.

And apparently no, nobody can open an issue and get anything fixed,
that's the reason this particular issue exists. Apparently your effort
also rejects improvements and fixes.

I think any renaming effort should be separated from the actual CMake
fixes zlib would badly need, try to retain compatibility by default or at
least with options.

My 2 cents.

@Vollstrecker
Copy link

Both are appended to the output filename, this particular postfix variable first, then the suffix, which is just the end of the filename and includes the extension.

Your draft force-adds a 3rd, initial suffix before the above postfix.

The suffix is (on Win) .dll, and you are setting it to be .dll. So you try to postfix the name by prefixing the suffix. And yes, I'm adding a 3rd level by marking static builds and debug builds. As you know i.e. MSVC is able to produce debug and release from one config created by cmake, so you can either make sure that all have different names, or you would have to configure different install-dirs to select between debug or not. This way you can have all in one with just one run of cmake.

  1. if both static and shared is built and CMAKE_STATIC_LIBRARY_SUFFIX STREQUAL == CMAKE_IMPORT_LIBRARY_SUFFIX. This typically means MSVC.
    The solution is to force a different name for one of the output libs to avoid them overwriting each other throughout the build. It can be a custom suffix for one of the libs, or it can be a custom suffix for just the implib. There is no convention. Hence it's nice to allow configuration with a default matching what was used before.

Here you write it: Force a different name. z.dll vs. zs.dll. But here's the trick: If you build an installer, it's able to see that another installer already installed zlib and therefor doesn't need to install another copy. I know this is new and pure magic for Windows users, but it works. But it only works if the lib is named the same, so if the other app that installed zlib decided the want it named different, the installer sees in the registry that there's an installation and skips this part, but the app is not able to find it. There's no benefit (at least noone showed me a valid reason atm.) in allowing to change that, but huge potential that it makes things worse.

This will apply for handcrafted projects (most commonly VS solutions) and I see 2 situations for this.

  1. They built zlib with the old build-scripts so they still can do and nothing changes.

That makes this effort pointless IMO. The point would be to enable zlib CMake build to replace the non-standard solution. If not pointless, it's an unnecessarily lost opportunity.

If they want to stick with their old method, even the first introduction of cmake here was pointless. If someone wants to use cmake, then it should be done right. In this case right means cmake switched from find_package with modules to find_package with configs (for a reason) and so should everyone that wants to use cmake. The module takes care of everything and provides a target to use. In this case it's completely irrelevant how the lib is named. Problems only occur if they use find_package to make sure zlib is there (maybe with altered names to search for) and then use the name instead of the target in the call to link_libraries. In this case everyone should realize that not only code needs maintenance, abuild-system does also.

Not that I wouldn't welcome useful PRs, but I don't like work in progress interrupts. But I can go through to clarify some points:
L83: Breaks on cygwin

Easy to fix by extending the condition to CYGWIN/MSYS.

Sure, but do you know where else it is needed. I would prefer to decide based on COMPILER_ID but for whatever reason this is not implemented for RC. It's possible that it's behind one of the others and I just don't know because I'm not a windows guy. If so, let me know. As you can see in cmake's source they set the .obj based on the filename of rc_compiler, so I guess they also don't rely on the platform-var for reason and by now this is the only way to see if windres is used somewhere else.

Though as said there that GCC_WINDRES macro should probably not exist in the first place.

That's code decisions I wont judge upon.

edit: on a second look: the .rc is not supposed to be compiled for Cygwin builds due to $<$<BOOL:${WIN32}>:win32/zlib1.rc>, so I'm not sure how that could fail either with or without the suggested MINGW fix.

Not on my local, not pushed yet, code. I don't understand why this is there at all (no windows guy). But it seems to me that it is something for dll's to be used in windows and as it's possible to compile against libs in cygwin from outside of cygwin, I guess it's needed there also. And as I don't get any error so far, I'm pretty sure it's not completely wrong to include it there also.

L88: You use an option that only occurs there. No declaration, no documentation -> Black magic -> Not wanted.

There is nothing black magic in it. It's checking if the two output filenames would collide. If you prefer you may replace it with MSVC, which is most likely the same in practice.

You use ZLIB_STATIC_LIB_SUFFIX which is no cmake var and not set on any system I'm testing atm. (linux/windows/mingw32/mingw64/cygwin) so I guess it's supposed to be set via -D on cmdline (or something similar) but not created with option to be documented. It's an hidden option that can be found when reading the source and therefor I consider it black magic.

I'm not criticizing your work, but raising issues that I had found in the last two years dealing with CMake builds of curl and libssh2.

You're raising issues without pointing them out. I see "would be nice to allow" and there can be problems without pointing out which ones. I you say problems with curl, then I can check if it works without any modification to their code, that's more helpful than everything I've seen before.

And apparently no, nobody can open an issue and get anything fixed, that's the reason this particular issue exists. Apparently your effort also rejects improvements and fixes.

As you may have noticed, there are many things missing there atm. I didn't test, but I didn't deactivate issues so they should work. But yes, issues would distract from the work itself. I'm currently trying to sort all the pr's (so they can be referenced) identify what's duplicated or does the same in different ways, then adressing the issues already reported. Getting issues in that phase for half done work just slows this process down.

Not to mention that this project should not be the place to report issues as it's not the projects repo. Imagine there comes a pr that fixes an issue reported but the maintainer doesn't know about it. Issues should always be associated with the project and not with an outside contributor, regardless if he intends to maintain that stuff in the future or not.

As this is the first attempt under the new project, I still need to figure out the best way to do things. In this case I tried to let everyone know that there is someone that addresses all the issues and come to the conclusion it's better for the future to work silently until the PR is ready and discuss problems there (as they belong there).

I think any renaming effort should be separated from the actual CMake fixes zlib would badly need, try to retain compatibility by default or at least with options.

I try to retain compat with an option that is on by default. I don't know the complete history of zlib1.dll, but it seems that there was an api-change and no other way to make sure to get the right one. As it's the same with every workaround, they just stay there. With cmake there is a proper way to ask for specific versions, so there's no need for this workaround, it just stays there to ease migration but is clearly marked as a temporary solution.

The renaming shouldn't cause any problems. If they do I'm happy to fix that if it's not based on other workarounds. If there are conventions on platforms like it seems for MinGW, then they have to be implemented (and will be after I found the docs about it).

My 2 cents.

Noted.

@Vollstrecker
Copy link

There are some other useful patches that we have to apply to, which maybe you'd be willing to consider:

* Static or shared build, not both: https://github.com/microsoft/vcpkg/blob/master/ports/zlib/0002-build-static-or-shared-not-both.patch

There are already options to choose from. ZLIB_BUILD_STATIC=OFF gives you only the shared one. Your patch relies on CMAKE_BUILD_SHARED_LIBS which makes it impossible to get both in one run. If the static suffix is needed if only static is built is debatable, but this causes problems with you don't see what it is. I'm sure vcpkg users are able to just link against ZLIB::ZLIBSTATIC if the want have only a static link.

* Android and MinGW fixes: https://github.com/microsoft/vcpkg/blob/master/ports/zlib/0003-android-and-mingw-fixes.patch

The first half is already there (not sure if pushed already) the second half shoudn't be a problem. Is it just not working on android or is this for some crosscompiling? I'm asking because I guess if it's for crosscompiling it's better to check for rc compiler existence to not get the same problem with other combinations.

* Use /Z7 on Windows for static zlib builds to incorporate debug information.  This avoids downstream linker warnings about missing debug symbols.  This is an internal patch where we use a regex to replace any /Z parameters in CMAKE_C_FLAGS, CMAKE_C_FLAGS_DEBUG, etc.

Isn't that what CMAKE_FLAGS_INIT is meant for?

* Choose Visual C++ static or dynamic C runtime (/MT vs /MD).  This is another internal patch that either uses CMAKE_MSVC_RUNTIME_LIBRARY or a regex to update the CMAKE_C_FLAGS depending on CMake version.

I remember problems with missmatch of these and I'm not near enough to this world to understand these options but iirc the problems came from mixing variants that should be sorted out with using the right targets to link.

@Mr-Clam
Copy link

Mr-Clam commented Dec 2, 2024

  • Choose Visual C++ static or dynamic C runtime (/MT vs /MD). This is another internal patch that either uses CMAKE_MSVC_RUNTIME_LIBRARY or a regex to update the CMAKE_C_FLAGS depending on CMake version.

I remember problems with missmatch of these and I'm not near enough to this world to understand these options but iirc the problems came from mixing variants that should be sorted out with using the right targets to link.

They end up as separate C runtimes. You can't link two objects built against the different types. You have to use extreme caution when crossing DLL boundaries (e.g. memory pointers can cross, but don't try to free() in one place when it was malloc()'ed in the other, and don't ever pass a FILE pointer between the two).

@mtl1979
Copy link

mtl1979 commented Dec 2, 2024

They end up as separate C runtimes. You can't link two objects built against the different types. You have to use extreme caution when crossing DLL boundaries (e.g. memory pointers can cross, but don't try to free() in one place when it was malloc()'ed in the other, and don't ever pass a FILE pointer between the two).

This can be extended to linking zlib both statically and dynamically on same project... In almost all cases, dynamically linked version should be used. Visual C++ gives no guarantee which library each symbol is resolved from, so there is chance that you get same symbol in zlib itself and another library that use zlib internally. Depending on version used, they might internally use different memory allocation functions.

@joeyparrish
Copy link

As for now the resources are limited I want to ask a) all the people here to wave a hand if they can test all the stuff on systems github has no runner for...

@Vollstrecker, you can find my contact at https://joeyparrish.github.io/. I can test builds for you if you need me to. I have both x64 & arm64 Macs, x64 Windows, and both x64 & arm64 Linux. And one of my best friends has a huge collection of ancient Unix machines of various flavors and architectures, and I can easily bribe him to let me SSH in if you need me to test a build on something exotic. I usually respond to email within a week, more often within a day or two.

@Neustradamus
Copy link
Author

@Adenilson, @bahaa-cpl: About your PR: [mini_zip][build] Add minizip build target:

cc: @gvolant.

@Vollstrecker
Copy link

To be honest, I'm just doing exactly that. I'm currently investigating a warning about a conversion __int64 to long in ioapi.cL190 which I don't get fixed.

About the fact that @madler doesn't want it to be included, the CMakelists.txt in there will work completely independet from the main one, so it can be called on it's own, but there is an option (default to OFF) that it can be included in the main-build.

@nigels-com
Copy link

@Vollstrecker I'm on summer holidays now, so I look a minute to give this new CMakeLists.txt a go on Ubuntu 24.04 amd64. Worked fine for me, has some needed options such as optional shared and static libraries. There might be some odds and ends that I'd follow up with later, such as optional -fPIC and checking that the exported symbols are minimal. But thumbs up, this is at least 99% of what zlib needs for wrangling as a long-term dependency of various things. Cheers!

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

No branches or pull requests