This is an archive of the discontinued LLVM Phabricator instance.

[CMake] Use find_package to find zlib
AbandonedPublic

Authored by phosek on May 30 2018, 2:35 PM.

Details

Summary

Use the FindZLIB CMake function with find_package to find zlib.
This is a builtin module provided by CMake which allows overriding
the zlib location through standard mechanisms.

Diff Detail

Repository
rL LLVM

Event Timeline

phosek created this revision.May 30 2018, 2:35 PM
delcypher requested changes to this revision.May 30 2018, 4:16 PM

The idea behind this change is fine. The main problem in the implementation is not considering the scenario where LLVM_ENABLE_ZLIB is initially TRUE but is then changed at a later date. The current implementation would ignore the value of LLVM_ENABLE_ZLIB because the HAVE_LIBZ cache variable is still present from a previous configure run.

llvm/cmake/config-ix.cmake
112

If LLVM_ENABLE_ZLIB but ZLIB_FOUND is FALSE we should emit an error telling the user that Zlib couldn't be found and that should either tell CMake how to find it or set LLVM_ENABLE_ZLIB to FALSE. You also use the REQUIRED argument to find_package() as an alternative.

113

We need to handle the case that Zlib was found previously but LLVM_ENABLE_ZLIB is now FALSE. You can either do it here so that HAVE_LIBZ is set to FALSE or you can update all uses of HAVE_LIBZ to also check if LLVM_ENABLE_ZLIB is set to TRUE.

llvm/lib/Support/CMakeLists.txt
2

You shouldn't drop LLVM_ENABLE_ZLIB in the condition here, at least in the current implementation anyway. AFAIK both LLVM_ENABLE_ZLIB and HAVE_LIBZ are cache variables.

What could happen is that the user configures with LLVM_ENABLE_ZLIB and ZLIB is found and used.
Then at a later date with an existing build directory the user decides to set LLVM_ENABLE_ZLIB to FALSE.
If that happens HAVE_LIBZ will still be TRUE causing the code to continue to use Zlib despite LLVM_ENABLE_ZLIB being
set to FALSE.

llvm/lib/Support/Compression.cpp
21

Shouldn't this be HAVE_LIBZ?

27

Shouldn't this be HAVE_LIBZ?

This revision now requires changes to proceed.May 30 2018, 4:16 PM
delcypher added inline comments.May 30 2018, 4:26 PM
llvm/cmake/config-ix.cmake
113

Oh wait. HAVE_LIBZ is a regular variable and not a cache variable. Sorry I was confusing it with ZLIB_FOUND. In that case I think your implementation should work fine in the scenario I mentioned.

delcypher added inline comments.May 30 2018, 4:28 PM
llvm/lib/Support/CMakeLists.txt
2

Again. I think I confused HAVE_LIBZ with ZLIB_FOUND so your implementation is probably fine in the scenario I mentioned.

phosek updated this revision to Diff 149218.May 30 2018, 4:44 PM
phosek marked 2 inline comments as done.
phosek added inline comments.
llvm/cmake/config-ix.cmake
112

I'm fine doing that, but it'd would be a different behavior from the current one where we silently ignore the missing library?

delcypher added inline comments.May 30 2018, 5:02 PM
llvm/cmake/config-ix.cmake
112

Yes that is different behaviour. I'm pretty convinced that the current behaviour is wrong.

In KLEE we use a slightly different pattern. We initialize the default option for enabling ZLIB depending on whether or not the library is available.

See https://github.com/klee/klee/blob/843e9be8fc10c6ffb30218c5a826aab192a31955/CMakeLists.txt#L344

The advantage of this approach is that if the system has the library we use it by default, but if the user explicitly sets the option to use zlib and its not available then we emit an error.

Given that it appears the existing behaviour of LLVM right now is to silently ignore missing libraries, you don't have to fix this right now if you don't want to. This could be addressed in a separate patch. Although I'd personally like a warning at the very least instead of LLVM's build system silently ignoring the request to use zlib.

vitalybuka resigned from this revision.May 30 2018, 6:00 PM
phosek added inline comments.May 30 2018, 10:20 PM
llvm/cmake/config-ix.cmake
112

I agree that the approach you're following in KLEE is better, but in that case we'll probably have to change all the code to check LLVM_ENABLE_ZLIB rather than HAVE_LIBZ because even if HAVE_LIBZ is set to TRUE and we use it to se the default value of LLVM_ENABLE_ZLIB, user may still override that and set LLVM_ENABLE_ZLIB to FALSE. Does that sound fine to you?

labath added a subscriber: labath.May 31 2018, 1:34 AM
labath added inline comments.
llvm/lib/Support/CMakeLists.txt
3

What would be the new value of ZLIB_LIBRARIES here? One of my previous attempts to refactor this failed because we have code which assumes system_libs is a list bare library names z dl ... that can then be prefixed with -l and passed to the linker. This fails horribly if you specify a full path to a library (which cmake likes to to).
Please make sure that llvm-config --system-libs produces something reasonable after this patch.

delcypher added inline comments.May 31 2018, 11:49 AM
llvm/cmake/config-ix.cmake
112

Sounds good to me. You may have to refactor the code a bit more because it looks like the declaration for LLVM_ENABLE_ZLIB is nowhere near where it's used. In fact it's not even in the same file.

llvm/lib/Support/CMakeLists.txt
3

Sounds like we should have a better test case then. It looks like test/tools/llvm-config/system-libs.test is too weak to check what you asking for.

labath added inline comments.Jun 1 2018, 1:07 AM
llvm/lib/Support/CMakeLists.txt
3

Yes, a better test case would be useful certainly (but don't worry you will get test failures, they will just be in compiler-rt, or other projects which use llvm-config to invoke the linker :)).

Anyway, I am not asking for anything. I don't have a horse in this game; as long as the main cmake project builds I am happy. I'm just giving you a heads up that you are likely to run into issues down this road.

phosek added inline comments.Jun 5 2018, 12:08 PM
llvm/lib/Support/CMakeLists.txt
3

Isn't this actually more correct? In our case, I'd like to use our own version of zlib and libxml2 rather than the system ones using the CMAKE_FIND_ROOT_PATH option. If llvm-config --system-libs prints -lz -lxml2, it's ambiguous which zlib and libxml2 it's referring to. Furthermore, in our case we want to link zlib and libxml2 statically, so presumably llvm-config --system-libs shouldn't print -lz -lxml2 at all but that's not currently the case.

labath added inline comments.Jun 6 2018, 1:20 AM
llvm/lib/Support/CMakeLists.txt
3

Isn't this actually more correct?

You could argue it's more correct if you also fixed --system-libs to output the library as /usr/lib/libz.so or something else that the linker can consume. As it stands now it will print -l/usr/lib/libz.so which will just blow up. I don't know much about the scenarios in which llvm-config is used (I just know that when I tried something like this I found a dozen angry emails waiting for me the next day), but this change might actually be enough to appease people relying on it.

Furthermore, in our case we want to link zlib and libxml2 statically, so presumably llvm-config --system-libs shouldn't print -lz -lxml2 at all but that's not currently the case.

The intended audience of llvm-config is people who want to link against llvm. For that the modality (shared/static) of libz doesn't matter. What matters is the modality of llvm. If you built llvm as a bunch of static libraries, when using them, you will need to pass libz to the linker (static or otherwise). If you built llvm as a single shared library, then you don't need to pass anything as shared libraries can track their dependencies (and I believe in this case the output of --system-libs will already be empty).

phosek abandoned this revision.Feb 5 2020, 3:36 PM

This was done in D70764.

Herald added a project: Restricted Project. · View Herald TranscriptFeb 5 2020, 3:36 PM
Herald added a subscriber: kristina. · View Herald Transcript