- add zstd to llvm::compression namespace
- add a CMake option LLVM_ENABLE_ZSTD with behavior mirroring that of LLVM_ENABLE_ZLIB
- add tests for zstd to llvm/unittests/Support/CompressionTest.cpp
- debian users should install libzstd when using LLVM_ENABLE_ZSTD=FORCE_ON from source due to this bug https://bugs.launchpad.net/ubuntu/+source/libzstd/+bug/1941956
Details
- Reviewers
phosek leonardchan alexander-shaposhnikov rupprecht jhenderson MaskRay - Commits
- rGe939bf67e340: [llvm] add zstd to `llvm::compression` namespace
rGd449c6007672: [llvm] add zstd to llvm::compression namespace
rGcef07169ec9f: [llvm] add zstd to `llvm::compression` namespace
rGadf1ffe95854: [llvm] cmake config groundwork to have ZSTD in LLVM
rGf07caf20b9d3: [llvm] cmake config groundwork to have ZSTD in LLVM
Diff Detail
- Repository
- rG LLVM Github Monorepo
Unit Tests
Event Timeline
Fix missing cmake findZstd, remove unused crc32 from compression namespaces and simplify some code
I think this patch should be broken into at least two:
- Refactor llvm/include/llvm/Support/Compression.h and llvm/lib/Support/Compression.cpp to introduce a generic interface and use it throughout the codebase.
- zstd support in llvm/include/llvm/Support/Compression.h including the CMake bits.
When uploading future changes, please also make sure to include full context.
llvm/include/llvm/Support/Compression.h | ||
---|---|---|
67–87 | I think think that this should be a runtime rather than compile time selection. Many (if not most) toolchain vendors would likely want to enable both zstd and zlib and choose the algorithm based an option or file content. For example, in the case of profiles, we want to be able to read existing profiles that use zlib, but for newly created profiles we may want to use zstd if available. To make it possible, I suspect we may want to wrap the existing functions into a class that implements a common interface. I expect we would also need a function to detect the compression type based on the buffer content. |
Agree. As soon as the namespace refactoring is in a good enough shape, I think you may land the refactoring part before the rest of zstd patches.
Note: if you have a deep stacked patches, it may be useful to have a branch somewhere (e.g. your llvm-project fork on Github) so that interested folks can get the whole picture more easily.
(arc patch Dxxxxx can technically apply a deep stack, but it often fails to apply changes cleanly.)
- feat: add zstd compression
- Merge branch 'ckissane.refactor-compression-namespace' into ckissane.add-zstd-compression
- Merge branch 'ckissane.refactor-compression-namespace' into ckissane.add-zstd-compression
llvm/cmake/modules/FindZSTD.cmake | ||
---|---|---|
1 ↗ | (On Diff #441114) | How did you derive this? The file seems contributed by you (I don't think facebook/zstd has such a file). It should not have a Meta Platforms, Inc notice. |
3 ↗ | (On Diff #441114) | Search SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception from other .cmake files |
LGTM although I think I'd be more comfortable with Petr's +2 for cmake changes.
Would it be better instead to expose LLVM_ENABLE_ZSTD to subrepos like clangd or flang until they're needed there? Not sure in this case if this will need +2s from their respective owners.
Please check both LLVM_ENABLE_ZSTD={on,off} work. Ideally, check that when zstd' cmake (libzstd-dev on Debian) is unavailable, LLVM_ENABLE_ZSTD=on works (there is no zstd functionality but the cmake invocation should succeed).
llvm/cmake/modules/FindZSTD.cmake | ||
---|---|---|
3 ↗ | (On Diff #441114) | Delete // |
Consider adding have_zstd to compiler-rt/test/lit.common.cfg.py and several other lit.site.cfg.py.in files
llvm/cmake/modules/FindZSTD.cmake | ||
---|---|---|
1 ↗ | (On Diff #441114) | We usually don't include the copyright header in .cmake files at all. |
- Merge remote-tracking branch 'origin/main' into ckissane.add-zstd.0-cmake
- added have_zstd to compiler-rt/test/lit.common.cfg.py, clang-tools-extra/clangd/test/lit.cfg.py and several lit.site.cfg.py.in files
llvm/CMakeLists.txt | ||
---|---|---|
441 | This broke builds that do not specify LLVM_ENABLE_ZSTD=OFF explicitly on macOS, and I suspect on other platforms as well: ld: library not found for -lzstd clang: error: linker command failed with exit code 1 (use -v to see invocation) It looks to me like the build should not require zstd to be installed by default. |
This patch has changed a lot from what I have reviewed. The CMake change should be added along with llvm::compression::zstd::* functions.
Otherwise the change just introduces some CMake variables which cannot be tested.
Since you haven't touched flang, compiler-rt, etc. The patch should not updated their CMake files.
For lld/ELF, I've created D129406 to add the support. It will need to wait until you have landed these zstd changes.
As I mentioned, the proper approach is to add zstd functionality along with the CMake change, instead of adding CMake to all llvm-project components without a way to test them.
lld/test/lit.site.cfg.py.in | ||
---|---|---|
21 ↗ | (On Diff #443316) | During cmake, ensure that LLVM_ENABLE_PROJECTS contains lld I posted the patch link to another patch of yours: https://reviews.llvm.org/D129406 |
@MaskRay, I have now done this and ran the ldd tests as requested:
With LLVM_ENABLE_ZSTD=ON $ ninja check-lld Testing Time: 8.98s Unsupported : 17 Passed : 2638 Expectedly Failed: 1 With LLVM_ENABLE_ZSTD=OFF $ ninja check-lld Testing Time: 8.95s Unsupported : 17 Passed : 2638 Expectedly Failed: 1
I request that you abandon this patch and incorporate the llvm cmake part into the llvm patch which you actually use zstd.
It is not appropriate to add zstd cmake to llvm-project components which don't use zstd.
Let me see if I understand this correctly:
Are you saying that I should abandon this patch, and create a new patch that:
- adds findZSTD.cmake
- adds zstd to compression namespace
- adds tests to CompressionTest.cpp
- and does the minimal amount of cmake work to have the flags and test work
- thus differing per component cmake config to patches like how you are doing in https://reviews.llvm.org/D129406
Is this correct?
I realize though that then https://reviews.llvm.org/D129406 or similar would be "the [first] llvm patch which actually use[s] zstd"
You can find a component in llvm which uses zstd (e.g. lib/Support). Add the functionality with tests (e.g. a CompressionTest.cpp unittest) along with the CMake/(optional Bazel, gn) changes.
Keep clang, clang-tools-extra, lld, etc unchanged. These components don't yet use zstd and the CMake changes in this patch will be untestable.
Got it!, this patch already has such tests (CompressionTest.cpp unittest) in lib/Support, so I should just remove the untestable cmake config.
The patch looks mostly good but please fix the subject and the summary.
Note: if you fix the local commit message, you can use arc diff --head=HEAD 'HEAD^' --verbatim to update the subject and the summary.
llvm/lib/Support/Compression.cpp | ||
---|---|---|
88 |
llvm/lib/Support/Compression.cpp | ||
---|---|---|
68 |
- Merge remote-tracking branch 'origin/main' into ckissane.add-zstd
- [Support] update zstd interface to use uint8_t * and ArrayRef<uint8_t>
Why was this reverted? Please make extensive tests especially for something dealing with the build system. When reverting a commit, briefly describe what happened.
This breaks builds when LLVM is included with CMake’s add_subdirectory.
I think the zstd target needs to be marked as imported.
The following patch fixes the problem, although I’m not familiar enough with CMake to know if this is the right way to go:
diff --git a/llvm/cmake/modules/FindZSTD.cmake b/llvm/cmake/modules/FindZSTD.cmake index 43ccf7232138..8e6ec6e8a988 100644 --- a/llvm/cmake/modules/FindZSTD.cmake +++ b/llvm/cmake/modules/FindZSTD.cmake @@ -12,6 +12,10 @@ find_package_handle_standard_args( ZSTD_LIBRARY ZSTD_INCLUDE_DIR) if(ZSTD_FOUND) + if(NOT TARGET Zstd::zstd) + add_library(Zstd::zstd UNKNOWN IMPORTED) + set_target_properties(Zstd::zstd PROPERTIES IMPORTED_LOCATION "${ZSTD_LIBRARY}") + endif() set(ZSTD_LIBRARIES ${ZSTD_LIBRARY}) set(ZSTD_INCLUDE_DIRS ${ZSTD_INCLUDE_DIR}) endif() diff --git a/llvm/lib/Support/CMakeLists.txt b/llvm/lib/Support/CMakeLists.txt index 52b95c5377d3..031adfa33ba8 100644 --- a/llvm/lib/Support/CMakeLists.txt +++ b/llvm/lib/Support/CMakeLists.txt @@ -26,7 +26,7 @@ if(LLVM_ENABLE_ZLIB) endif() if(LLVM_ENABLE_ZSTD) - list(APPEND imported_libs zstd) + list(APPEND imported_libs Zstd::zstd) endif() if( MSVC OR MINGW )
I just reverted this in 6e6be5f9504d because it seems to have broken macOS builds:
llvm/lib/Support/Compression.cpp:24:10: fatal error: 'zstd.h' file not found #include <zstd.h> ^~~~~~~~
@aemerson Could you provide the output of your cmake command?
(I can't easily reproduce because I don't have a mac on hand)
@aemerson can you let me know if https://reviews.llvm.org/D129786 works on MacOS?
I am continuing work on that revision because this one has a lot of outdated unrelated history.
FWIW I hit this last night on my mac desktop - it looked like I had zstd installed by homebrew (as a dependency on something I installed), and cmake was able to find it in /opt/homebrew (somehow) but when Compression.cpp was built, nothing had added -I/opt/homebrew/include so the header wasn't found. I hacked the FindZSTD.cmake to not find it, to finish what I was working on before bedtime. This might not be related to what @aemerson saw though.
@jasonmolenda Thank you for the info, I believe it is similar, could you try: https://reviews.llvm.org/D129786 for me?
I applied the patch from https://reviews.llvm.org/D129786 on a clean checkout, cmake ../llvm -G Ninja -DCMAKE_BUILD_TYPE=Debug -DLLVM_ENABLE_ASSERTIONS=1 -DLLVM_ENABLE_PROJECTS='llvm;lldb;clang' '-DLLVM_ENABLE_RUNTIMES=libcxx;libcxxabi' -DLLDB_ENABLE_PYTHON=1 (my normal cmake line) and got
-- Found ZSTD: /opt/homebrew/lib/libzstd.dylib -- Looking for ZSTD_compress -- Looking for ZSTD_compress - found [...] FAILED: lib/Support/CMakeFiles/LLVMSupport.dir/Compression.cpp.o /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/c++ -DGTEST_HAS_RTTI=0 -D_DEBUG -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -I/Users/jason/k/llvm/llvm-project/build/lib/Support -I/Users/jason/k/llvm/llvm-project/llvm/lib/Support -I/Users/jason/k/llvm/llvm-project/build/include -I/Users/jason/k/llvm/llvm-project/llvm/include -fPIC -fvisibility-inlines-hidden -Werror=date-time -Werror=unguarded-availability-new -Wall -Wextra -Wno-unused-parameter -Wwrite-strings -Wcast-qual -Wmissing-field-initializers -pedantic -Wno-long-long -Wc++98-compat-extra-semi -Wimplicit-fallthrough -Wcovered-switch-default -Wno-noexcept-type -Wnon-virtual-dtor -Wdelete-non-virtual-dtor -Wsuggest-override -Wstring-conversion -Wmisleading-indentation -fdiagnostics-color -g -arch arm64 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX12.3.sdk -std=c++14 -fno-exceptions -fno-rtti -MD -MT lib/Support/CMakeFiles/LLVMSupport.dir/Compression.cpp.o -MF lib/Support/CMakeFiles/LLVMSupport.dir/Compression.cpp.o.d -o lib/Support/CMakeFiles/LLVMSupport.dir/Compression.cpp.o -c /Users/jason/k/llvm/llvm-project/llvm/lib/Support/Compression.cpp /Users/jason/k/llvm/llvm-project/llvm/lib/Support/Compression.cpp:24:10: fatal error: 'zstd.h' file not found #include <zstd.h> ^~~~~~~~ 1 error generated. % file /opt/homebrew/lib/libzstd.dylib /opt/homebrew/lib/libzstd.dylib: Mach-O 64-bit dynamically linked shared library arm64 % head -2 /opt/homebrew/include/zstd.h /* * Copyright (c) Yann Collet, Facebook, Inc. % % grep -i zstd CMakeCache.txt //Use zstd for compression/decompression if available. Can be ON, LLVM_ENABLE_ZSTD:STRING=ON ZSTD_INCLUDE_DIR:PATH=/opt/homebrew/include ZSTD_LIBRARY:FILEPATH=/opt/homebrew/lib/libzstd.dylib //Details about finding ZSTD FIND_PACKAGE_MESSAGE_DETAILS_ZSTD:INTERNAL=[/opt/homebrew/lib/libzstd.dylib][/opt/homebrew/include][v()] //Have symbol ZSTD_compress HAVE_ZSTD:INTERNAL=1 //ADVANCED property for variable: ZSTD_INCLUDE_DIR ZSTD_INCLUDE_DIR-ADVANCED:INTERNAL=1 //ADVANCED property for variable: ZSTD_LIBRARY ZSTD_LIBRARY-ADVANCED:INTERNAL=1
Instead of marking a differential [OLD] (which may confuse readers whether this is to be abandoned), you can mark a differential Request Reviews/Request Changes. Then it will not be in the green state.
I clicked "Reopen" to make it clear the patch hasn't relanded.
Oh, sorry about that!
I had actually created https://reviews.llvm.org/D129786 instead of reopening this one because at the time I tried, reopening didn't seem to work.
That's fine :) We need to learn the web UI.
I had actually created https://reviews.llvm.org/D129786 instead of reopening this one because at the time I tried, reopening didn't seem to work.
A reverted patch by default is still in the "Closed" state. You can "reopen" it so that people know it hasn't relanded.
When repairing a differential, just reuse the existing patch. It keeps all discussions (including past suggestions and issues a previous commit did not address) in one thread.
If the new patch is very similar to this one, you probably need to abandon it in favor of this one.
If you revert B because you haven't done A, and A and B are somewhat not so related (e.g. B addresses an existing brittle build system issue which happens to affect some platform when A is added), then having A as a separate differential is fine.
- move try_find_dependency into it's own file
- add newline to end of TryFindDependencyMacro.cmake
- clarify comment in TryFindDependencyMacro.cmake
@ckissane
I took fresh sources of LLVM and when I run cmake I get the following warning:
-- Looking for compress2 -- Looking for compress2 - found CMake Warning at cmake/config-ix.cmake:149 (find_package): By not providing "Findzstd.cmake" in CMAKE_MODULE_PATH this project has asked CMake to find a package configuration file provided by "zstd", but CMake did not find one. Could not find a package configuration file provided by "zstd" with any of the following names: zstdConfig.cmake zstd-config.cmake Add the installation prefix of "zstd" to CMAKE_PREFIX_PATH or set "zstd_DIR" to a directory containing one of the above files. If "zstd" provides a separate development package or SDK, be sure it has been installed. Call Stack (most recent call first): CMakeLists.txt:768 (include)
Ubuntu 22.04 LTS
cmake version 3.22.3
llvm/cmake/config-ix.cmake | ||
---|---|---|
146 | Since there's no Findzstd.cmake module shipped with CMake, and we don't provide in LLVM, we should use the config mode. |
I've quieted the warnings in https://github.com/llvm/llvm-project/commit/a71a01bc10d509bd4e746e7d277c4613ef886875, though I'm just now seeing @phosek's suggestion to use CONFIG I'm not sure what that does
llvm/include/llvm/Support/Compression.h | ||
---|---|---|
48 | I missed the values here. Why is -5 picked for NoCompression? What does it mean? zstd.h says ZSTD_maxCLevel() is currently 22. The CLI program mentions 19. Why is BestSizeCompression 12? ZSTD_CLEVEL_DEFAULT/the CLI CLI uses 3 for the default level. Why is DefaultCompression 5? |
if(LLVM_ENABLE_ZSTD) list(APPEND imported_libs zstd::libzstd_shared) endif()
This hard codes shared linking which breaks the use case of static linking LLVM.
Also LLVM needs to now include a Findzstd.cmake file or else we get this error:
CMake Error at cmake/config-ix.cmake:144 (find_package): By not providing "Findzstd.cmake" in CMAKE_MODULE_PATH this project has asked CMake to find a package configuration file provided by "zstd", but CMake did not find one. Could not find a package configuration file provided by "zstd" with any of the following names: zstdConfig.cmake zstd-config.cmake Add the installation prefix of "zstd" to CMAKE_PREFIX_PATH or set "zstd_DIR" to a directory containing one of the above files. If "zstd" provides a separate development package or SDK, be sure it has been installed. Call Stack (most recent call first): CMakeLists.txt:774 (include)
It is impossible to satisfy this dependency when bootstrapping a static build of zig without patching LLVM.
zstd provides GNU Makefile, CMake, and Meson. The CMake files are only installed when configured with CMake. Debian and Ubuntu lack them.
The pkg-config file libzstd.pc probably provides the best portability on at least *NIX systems. (I have also used it for a binutils-gdb patch.)
I think we can then avoid the
zstdConfig.cmake zstd-config.cmake
issue.
Compiler infrastructure should not assume the existence of a Linux distribution. The portable way is simple and can easily be supported. One should be able to install $prefix/lib/libzstd.a and $prefix/include/zstd.h, then have that prefix searched as part of the standard CMAKE_PREFIX_PATH.
If LLVM will not carry Findzstd.cmake then it should not use FIND_PACKAGE in the case of -DLLVM_ENABLE_ZSTD=FORCE_ON; it should just throw -lzstd on the linker line instead of throwing rakes in my path for no reason.
This was addressed by D132870 and D133222.
Also LLVM needs to now include a Findzstd.cmake file or else we get this error:
CMake Error at cmake/config-ix.cmake:144 (find_package): By not providing "Findzstd.cmake" in CMAKE_MODULE_PATH this project has asked CMake to find a package configuration file provided by "zstd", but CMake did not find one. Could not find a package configuration file provided by "zstd" with any of the following names: zstdConfig.cmake zstd-config.cmake Add the installation prefix of "zstd" to CMAKE_PREFIX_PATH or set "zstd_DIR" to a directory containing one of the above files. If "zstd" provides a separate development package or SDK, be sure it has been installed. Call Stack (most recent call first): CMakeLists.txt:774 (include)It is impossible to satisfy this dependency when bootstrapping a static build of zig without patching LLVM.
It should be possible to use CMAKE_FIND_PACKAGE_PREFER_CONFIG=ON to pick up config file that's part of the zstd installation, but I'd be also fine including Findzstd.cmake in LLVM to avoid needing that.
Is anyone working on a solution that would work for people using a zstd install method that's actually supported upstream?
This broke builds that do not specify LLVM_ENABLE_ZSTD=OFF explicitly on macOS, and I suspect on other platforms as well:
It looks to me like the build should not require zstd to be installed by default.