The legacy decoders (lib/legacy/zstd_v01.c .. zstd_v07.c) are next in the Rust migration. Each of those files is a frozen snapshot of the FSE/Huff0 entropy coders and frame logic of one historical release, so their ports must not reuse the modern Rust entropy modules and must not share code with each other: outputs and error codes have to stay byte-identical to the frozen C forever. This commit installs the build-system scaffolding so seven per-version ports can land independently, each adding only its own module file plus a one-line registration in rust/src/legacy/mod.rs. Cargo grows features legacy-v01 .. legacy-v07. They are never default features: the C build defaults differ per build system, so each build system passes the list explicitly, derived from its own legacy configuration: - lib/Makefile and programs/Makefile map ZSTD_LEGACY_SUPPORT=N to the features for versions N..7 (0 disables legacy), mirroring the ZSTD_LEGACY_FILES selection in lib/libzstd.mk. - tests/Makefile always enables all seven features because its ZSTDLEGACY_FILES wildcard compiles every lib/legacy/*.c regardless of the dispatch level. - build/meson maps legacy_level exactly like the makefiles; build/cmake enables all seven whenever ZSTD_LEGACY_SUPPORT is ON because it always compiles all seven C files (ZSTD_LEGACY_LEVEL only selects the C dispatch). Every build system also encodes the legacy selection in the Rust target directory name (e.g. c1-d1-default-legacy5), for the same reason the HUF mode is encoded there: a cached archive built for one configuration must never be linked into a build expecting another. In tests/Makefile the legacy level additionally flows into the existing HUF C-mode stamp, so the flat C test objects (which bake -DZSTD_LEGACY_SUPPORT into the dispatch) are rebuilt whenever the level changes. In programs/Makefile the compress-only, decompress-only, and CLI archives keep level-independent directories (RUST_HUF_MODE) because they are only linked into ZSTD_LEGACY_SUPPORT=0 program variants and carry no legacy features. A feature whose version has not been ported yet gates nothing: the module registration in rust/src/legacy/mod.rs is added by each port, so enabling e.g. legacy-v05 today simply leaves that decoder in C. This is what makes mixed C/Rust legacy levels link cleanly while the seven ports land in any order. Test plan: - cd rust && cargo fmt --check && cargo clippy --all-targets -- -D warnings && cargo test --all-targets - cargo clippy with --no-default-features --features decompression,legacy-v01 and with all seven legacy features - make -C tests fuzzer && ./tests/fuzzer -i1 --no-big-tests - make -C tests test-rust-lib-smoke; make -C tests test-legacy - make -C lib libzstd.a with ZSTD_LEGACY_SUPPORT=0, 1 and default (5) - cmake configure and meson setup (including -Dlegacy_level=1) emit the expected --features lists and legacy-suffixed target directories
Meson build system for zstandard
Meson is a build system designed to optimize programmer productivity. It aims to do this by providing simple, out-of-the-box support for modern software development tools and practices, such as unit tests, coverage reports, Valgrind, CCache and the like.
This Meson build system is provided with no guarantee and maintained by Dima Krasner <dima@dimakrasner.com>.
It outputs one libzstd, either shared or static, depending on
default_library option.
The migrated compatibility modules are built with Cargo as part of every
Meson library build. Static builds flatten the Cargo object members into
libzstd.a, so external C consumers link one archive. Shared builds use a
whole-archive link for the Cargo archive, retaining Rust-only public ABI
exports.
How to build
cd to this meson directory (build/meson)
meson setup -Dbin_programs=true -Dbin_contrib=true builddir
cd builddir
ninja # to build
ninja install # to install
You might want to install it in staging directory:
DESTDIR=./staging ninja install
To configure build options, use:
meson configure
See man meson(1).
For a cross build, set the Cargo target explicitly, for example:
meson setup -Dzstd_rust_target=aarch64-unknown-linux-gnu builddir
On 32-bit Linux, the i686-unknown-linux-gnu target is selected
automatically. Set -Dzstd_rust_archiver=... when the C cross toolchain needs
a non-default archiver. The huf_force_decompress_x1 and
huf_force_decompress_x2 options select matching C and Rust decoder modes.