build(rust): select archives by target and HUF mode

Derive the Rust static-library configuration from the effective C HUF decoder
flags and place each mode in its own Cargo target directory. This prevents a
forced X1/X2 C build from silently reusing the default Rust archive.

The test and program makefiles now also build and link an i686 Rust archive
for their 32-bit targets, including zstd32. zstd-small retains its existing
default configuration while preserving an explicitly requested HUF mode.

Test Plan:
- cargo clippy; cargo clippy --benches; cargo clippy --tests
- cargo +nightly fmt, then repeat the Clippy checks
- cargo test --all-targets for default, forced X1, and forced X2 modes
- cargo build --release --target i686-unknown-linux-gnu for each mode
- make -n checks for default, forced, direct -D, and 32-bit test/CLI targets

Refs: rust/README.md
This commit is contained in:
2026-07-10 20:46:23 +02:00
parent 58a50db413
commit d89ebb31e3
4 changed files with 109 additions and 11 deletions
+49 -3
View File
@@ -41,12 +41,55 @@ TESTARTEFACT := versionsTest
CARGO ?= cargo
RUST_DIR := ../rust
RUST_MANIFEST := $(RUST_DIR)/Cargo.toml
RUST_STATICLIB := $(RUST_DIR)/target/release/libzstd_rs.a
RUST_SOURCES := $(RUST_MANIFEST) $(RUST_DIR)/Cargo.lock \
$(shell find $(RUST_DIR)/src -type f -name '*.rs' -print)
# Keep Rust's HUF implementation in lockstep with libzstd.mk's C selection.
# Forced modes may arrive as libzstd.mk variables or as direct -D flags in
# MOREFLAGS/CFLAGS/CPPFLAGS, as used by the C-only build matrix.
RUST_HUF_FORCE_X1 := $(HUF_FORCE_DECOMPRESS_X1)
RUST_HUF_FORCE_X2 := $(HUF_FORCE_DECOMPRESS_X2)
ifneq ($(filter -DHUF_FORCE_DECOMPRESS_X1 -DHUF_FORCE_DECOMPRESS_X1=%,$(CPPFLAGS) $(CFLAGS) $(MOREFLAGS)),)
RUST_HUF_FORCE_X1 := 1
endif
ifneq ($(filter -DHUF_FORCE_DECOMPRESS_X2 -DHUF_FORCE_DECOMPRESS_X2=%,$(CPPFLAGS) $(CFLAGS) $(MOREFLAGS)),)
RUST_HUF_FORCE_X2 := 1
endif
# A separate target directory per mode prevents a forced build from reusing the
# default archive, and also gives link targets a configuration-specific input.
ifneq ($(RUST_HUF_FORCE_X1),0)
ifneq ($(RUST_HUF_FORCE_X2),0)
$(error HUF_FORCE_DECOMPRESS_X1 and HUF_FORCE_DECOMPRESS_X2 are mutually exclusive)
endif
endif
RUST_HUF_FEATURE :=
RUST_BUILD_CONFIG := default
ifneq ($(RUST_HUF_FORCE_X1),0)
RUST_HUF_FEATURE := huf-force-decompress-x1
RUST_BUILD_CONFIG := huf-force-decompress-x1
endif
ifneq ($(RUST_HUF_FORCE_X2),0)
RUST_HUF_FEATURE := huf-force-decompress-x2
RUST_BUILD_CONFIG := huf-force-decompress-x2
endif
RUST_TARGET_DIR := $(RUST_DIR)/target/$(RUST_BUILD_CONFIG)
RUST_STATICLIB := $(RUST_TARGET_DIR)/release/libzstd_rs.a
RUST_TARGET_32 ?= i686-unknown-linux-gnu
RUST_STATICLIB_32 := $(RUST_TARGET_DIR)/$(RUST_TARGET_32)/release/libzstd_rs.a
RUST_CARGO_FLAGS := --manifest-path $(RUST_MANIFEST) --release \
--target-dir $(RUST_TARGET_DIR)
ifneq ($(RUST_HUF_FEATURE),)
RUST_CARGO_FLAGS += --features $(RUST_HUF_FEATURE)
endif
$(RUST_STATICLIB): $(RUST_SOURCES)
$(CARGO) build --manifest-path $(RUST_MANIFEST) --release
$(CARGO) build $(RUST_CARGO_FLAGS)
$(RUST_STATICLIB_32): $(RUST_SOURCES)
$(CARGO) build $(RUST_CARGO_FLAGS) --target $(RUST_TARGET_32)
DEBUGFLAGS += -g -Wno-c++-compat
CPPFLAGS += -I$(LIB_SRCDIR) -I$(LIB_SRCDIR)/common -I$(LIB_SRCDIR)/compress -I$(LIB_SRCDIR)/legacy \
@@ -259,12 +302,15 @@ poolTests : $(PRGDIR)/util.c $(PRGDIR)/timefn.c poolTests.c $(LIB_SRCDIR)/common
# These static C test executables exercise Rust replacements. The normal
# prerequisite is also an archive input, placed after C sources by `$^`, and
# rebuilding Rust therefore relinks rather than leaving a stale implementation.
RUST_LINK_TARGETS := $(FULLBENCHS) fuzzer fuzzer32 zstreamtest zstreamtest32 \
RUST_LINK_TARGETS := fullbench fuzzer zstreamtest \
zstreamtest_asan zstreamtest_tsan zstreamtest_ubsan \
paramgrill roundTripCrash longmatch largeDictionary \
invalidDictionaries legacy decodecorpus poolTests
$(RUST_LINK_TARGETS): $(RUST_STATICLIB)
RUST_LINK_TARGETS_32 := fullbench32 fuzzer32 zstreamtest32
$(RUST_LINK_TARGETS_32): $(RUST_STATICLIB_32)
.PHONY: versionsTest
versionsTest: clean
$(PYTHON) test-zstd-versions.py