build(rust): rebuild the archive for C test and CLI links
Make Rust sources normal prerequisites of native C test executables and CLI builds. A changed Rust module now rebuilds libzstd_rs.a and relinks the target, instead of relying on a manually prepared archive that can silently be stale. The archive is linked after C objects, allowing migrated C shims to resolve their Rust ABI symbols while remaining compatible with the existing makefile flows. The migration guide now documents this behavior. Test Plan: - make -B -C tests fuzzer - ./tests/fuzzer -i1 --no-big-tests - make -B -C programs zstd - ./programs/zstd --version Refs: rust/README.md
This commit is contained in:
+19
-6
@@ -21,6 +21,19 @@ zstd-release:
|
||||
LIBZSTD_MK_DIR = ../lib
|
||||
include $(LIBZSTD_MK_DIR)/libzstd.mk
|
||||
|
||||
# Link the in-progress Rust implementation after C objects whenever a program
|
||||
# uses a migrated C shim. Source inputs are prerequisites so a changed Rust
|
||||
# module rebuilds the archive and relinks the executable automatically.
|
||||
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)
|
||||
|
||||
$(RUST_STATICLIB): $(RUST_SOURCES)
|
||||
$(CARGO) build --manifest-path $(RUST_MANIFEST) --release
|
||||
|
||||
ifeq ($(shell $(CC) -v 2>&1 | $(GREP) -c "gcc version "), 1)
|
||||
ALIGN_LOOP = -falign-loops=32
|
||||
else
|
||||
@@ -152,7 +165,7 @@ else
|
||||
# BUILD_DIR is defined
|
||||
|
||||
ZSTD_OBJ := $(addprefix $(BUILD_DIR)/, $(ZSTD_ALL_OBJ))
|
||||
$(BUILD_DIR)/zstd : $(ZSTD_OBJ)
|
||||
$(BUILD_DIR)/zstd : $(ZSTD_OBJ) $(RUST_STATICLIB)
|
||||
@echo "$(THREAD_MSG)"
|
||||
@echo "$(ZLIB_MSG)"
|
||||
@echo "$(LZMA_MSG)"
|
||||
@@ -199,7 +212,7 @@ zstd32 : $(ZSTDLIB_FULL_SRC) $(ZSTD_CLI_SRC)
|
||||
CLEAN += zstd-nolegacy
|
||||
zstd-nolegacy : LDFLAGS += $(THREAD_LD) $(ZLIBLD) $(LZMALD) $(LZ4LD) $(DEBUGFLAGS_LD)
|
||||
zstd-nolegacy : CPPFLAGS += -UZSTD_LEGACY_SUPPORT -DZSTD_LEGACY_SUPPORT=0
|
||||
zstd-nolegacy : $(ZSTDLIB_CORE_SRC) $(ZDICT_SRC) $(ZSTD_CLI_OBJ)
|
||||
zstd-nolegacy : $(ZSTDLIB_CORE_SRC) $(ZDICT_SRC) $(ZSTD_CLI_OBJ) $(RUST_STATICLIB)
|
||||
$(CC) $(FLAGS) $^ -o $@$(EXT) $(LDFLAGS)
|
||||
|
||||
.PHONY: zstd-nomt
|
||||
@@ -253,20 +266,20 @@ endif
|
||||
## zstd-small: minimal target, supporting only zstd compression and decompression. no bench. no legacy. no other format.
|
||||
CLEAN += zstd-small zstd-frugal
|
||||
zstd-small: CFLAGS = -Os -Wl,-s
|
||||
zstd-frugal zstd-small: $(ZSTDLIB_CORE_SRC) zstdcli.c util.c timefn.c fileio.c fileio_asyncio.c
|
||||
zstd-frugal zstd-small: $(ZSTDLIB_CORE_SRC) zstdcli.c util.c timefn.c fileio.c fileio_asyncio.c $(RUST_STATICLIB)
|
||||
$(CC) $(FLAGS) -DZSTD_NOBENCH -DZSTD_NODICT -DZSTD_NOTRACE -UZSTD_LEGACY_SUPPORT -DZSTD_LEGACY_SUPPORT=0 $^ -o $@$(EXT)
|
||||
|
||||
CLEAN += zstd-decompress
|
||||
zstd-decompress: $(ZSTDLIB_COMMON_SRC) $(ZSTDLIB_DECOMPRESS_SRC) zstdcli.c util.c timefn.c fileio.c fileio_asyncio.c
|
||||
zstd-decompress: $(ZSTDLIB_COMMON_SRC) $(ZSTDLIB_DECOMPRESS_SRC) zstdcli.c util.c timefn.c fileio.c fileio_asyncio.c $(RUST_STATICLIB)
|
||||
$(CC) $(FLAGS) -DZSTD_NOBENCH -DZSTD_NODICT -DZSTD_NOCOMPRESS -DZSTD_NOTRACE -UZSTD_LEGACY_SUPPORT -DZSTD_LEGACY_SUPPORT=0 $^ -o $@$(EXT)
|
||||
|
||||
CLEAN += zstd-compress
|
||||
zstd-compress: $(ZSTDLIB_COMMON_SRC) $(ZSTDLIB_COMPRESS_SRC) zstdcli.c util.c timefn.c fileio.c fileio_asyncio.c
|
||||
zstd-compress: $(ZSTDLIB_COMMON_SRC) $(ZSTDLIB_COMPRESS_SRC) zstdcli.c util.c timefn.c fileio.c fileio_asyncio.c $(RUST_STATICLIB)
|
||||
$(CC) $(FLAGS) -DZSTD_NOBENCH -DZSTD_NODICT -DZSTD_NODECOMPRESS -DZSTD_NOTRACE -UZSTD_LEGACY_SUPPORT -DZSTD_LEGACY_SUPPORT=0 $^ -o $@$(EXT)
|
||||
|
||||
## zstd-dictBuilder: executable supporting dictionary creation and compression (only)
|
||||
CLEAN += zstd-dictBuilder
|
||||
zstd-dictBuilder: $(ZSTDLIB_COMMON_SRC) $(ZSTDLIB_COMPRESS_SRC) $(ZDICT_SRC) zstdcli.c util.c timefn.c fileio.c fileio_asyncio.c dibio.c
|
||||
zstd-dictBuilder: $(ZSTDLIB_COMMON_SRC) $(ZSTDLIB_COMPRESS_SRC) $(ZDICT_SRC) zstdcli.c util.c timefn.c fileio.c fileio_asyncio.c dibio.c $(RUST_STATICLIB)
|
||||
$(CC) $(FLAGS) -DZSTD_NOBENCH -DZSTD_NODECOMPRESS -DZSTD_NOTRACE $^ -o $@$(EXT)
|
||||
|
||||
CLEAN += zstdmt
|
||||
|
||||
+4
-3
@@ -39,9 +39,10 @@ source file whose implementation has moved to Rust remains in the original
|
||||
makefile source list as a small shim so header configuration and platform
|
||||
preprocessor behavior stay available during the transition.
|
||||
|
||||
The original test makefile links `target/release/libzstd_rs.a` with whole-archive
|
||||
semantics. Rebuild the Rust archive before running C tests so the executable
|
||||
does not use a stale implementation.
|
||||
The test and program makefiles make `target/release/libzstd_rs.a` a normal
|
||||
link prerequisite. They rebuild the Rust archive and relink the executable
|
||||
when a Rust source changes, so original C tests do not accidentally use a stale
|
||||
implementation.
|
||||
|
||||
## Validation
|
||||
|
||||
|
||||
+21
-1
@@ -36,6 +36,18 @@ PRGDIR = ../programs
|
||||
PYTHON ?= python3
|
||||
TESTARTEFACT := versionsTest
|
||||
|
||||
# The Rust implementation is linked into C compatibility tests. Keep the
|
||||
# archive a real prerequisite so a changed Rust source always relinks a test.
|
||||
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)
|
||||
|
||||
$(RUST_STATICLIB): $(RUST_SOURCES)
|
||||
$(CARGO) build --manifest-path $(RUST_MANIFEST) --release
|
||||
|
||||
DEBUGFLAGS += -g -Wno-c++-compat
|
||||
CPPFLAGS += -I$(LIB_SRCDIR) -I$(LIB_SRCDIR)/common -I$(LIB_SRCDIR)/compress -I$(LIB_SRCDIR)/legacy \
|
||||
-I$(LIB_SRCDIR)/dictBuilder -I$(LIB_SRCDIR)/deprecated -I$(PRGDIR) \
|
||||
@@ -74,7 +86,6 @@ MULTITHREAD_CPP = -DZSTD_MULTITHREAD
|
||||
MULTITHREAD_LD = -pthread
|
||||
endif
|
||||
MULTITHREAD = $(MULTITHREAD_CPP) $(MULTITHREAD_LD)
|
||||
LDFLAGS += -Wl,--whole-archive ../rust/target/release/libzstd_rs.a -Wl,--no-whole-archive
|
||||
|
||||
VOID = /dev/null
|
||||
ZSTREAM_TESTTIME ?= -T90s
|
||||
@@ -245,6 +256,15 @@ CLEAN += poolTests
|
||||
poolTests : $(PRGDIR)/util.c $(PRGDIR)/timefn.c poolTests.c $(LIB_SRCDIR)/common/pool.c $(LIB_SRCDIR)/common/threading.c $(LIB_SRCDIR)/common/zstd_common.c $(LIB_SRCDIR)/common/error_private.c
|
||||
$(LINK.c) $(MULTITHREAD) $^ -o $@$(EXT)
|
||||
|
||||
# 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 \
|
||||
zstreamtest_asan zstreamtest_tsan zstreamtest_ubsan \
|
||||
paramgrill roundTripCrash longmatch largeDictionary \
|
||||
invalidDictionaries legacy decodecorpus poolTests
|
||||
$(RUST_LINK_TARGETS): $(RUST_STATICLIB)
|
||||
|
||||
.PHONY: versionsTest
|
||||
versionsTest: clean
|
||||
$(PYTHON) test-zstd-versions.py
|
||||
|
||||
Reference in New Issue
Block a user