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
|
LIBZSTD_MK_DIR = ../lib
|
||||||
include $(LIBZSTD_MK_DIR)/libzstd.mk
|
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)
|
ifeq ($(shell $(CC) -v 2>&1 | $(GREP) -c "gcc version "), 1)
|
||||||
ALIGN_LOOP = -falign-loops=32
|
ALIGN_LOOP = -falign-loops=32
|
||||||
else
|
else
|
||||||
@@ -152,7 +165,7 @@ else
|
|||||||
# BUILD_DIR is defined
|
# BUILD_DIR is defined
|
||||||
|
|
||||||
ZSTD_OBJ := $(addprefix $(BUILD_DIR)/, $(ZSTD_ALL_OBJ))
|
ZSTD_OBJ := $(addprefix $(BUILD_DIR)/, $(ZSTD_ALL_OBJ))
|
||||||
$(BUILD_DIR)/zstd : $(ZSTD_OBJ)
|
$(BUILD_DIR)/zstd : $(ZSTD_OBJ) $(RUST_STATICLIB)
|
||||||
@echo "$(THREAD_MSG)"
|
@echo "$(THREAD_MSG)"
|
||||||
@echo "$(ZLIB_MSG)"
|
@echo "$(ZLIB_MSG)"
|
||||||
@echo "$(LZMA_MSG)"
|
@echo "$(LZMA_MSG)"
|
||||||
@@ -199,7 +212,7 @@ zstd32 : $(ZSTDLIB_FULL_SRC) $(ZSTD_CLI_SRC)
|
|||||||
CLEAN += zstd-nolegacy
|
CLEAN += zstd-nolegacy
|
||||||
zstd-nolegacy : LDFLAGS += $(THREAD_LD) $(ZLIBLD) $(LZMALD) $(LZ4LD) $(DEBUGFLAGS_LD)
|
zstd-nolegacy : LDFLAGS += $(THREAD_LD) $(ZLIBLD) $(LZMALD) $(LZ4LD) $(DEBUGFLAGS_LD)
|
||||||
zstd-nolegacy : CPPFLAGS += -UZSTD_LEGACY_SUPPORT -DZSTD_LEGACY_SUPPORT=0
|
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)
|
$(CC) $(FLAGS) $^ -o $@$(EXT) $(LDFLAGS)
|
||||||
|
|
||||||
.PHONY: zstd-nomt
|
.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.
|
## zstd-small: minimal target, supporting only zstd compression and decompression. no bench. no legacy. no other format.
|
||||||
CLEAN += zstd-small zstd-frugal
|
CLEAN += zstd-small zstd-frugal
|
||||||
zstd-small: CFLAGS = -Os -Wl,-s
|
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)
|
$(CC) $(FLAGS) -DZSTD_NOBENCH -DZSTD_NODICT -DZSTD_NOTRACE -UZSTD_LEGACY_SUPPORT -DZSTD_LEGACY_SUPPORT=0 $^ -o $@$(EXT)
|
||||||
|
|
||||||
CLEAN += zstd-decompress
|
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)
|
$(CC) $(FLAGS) -DZSTD_NOBENCH -DZSTD_NODICT -DZSTD_NOCOMPRESS -DZSTD_NOTRACE -UZSTD_LEGACY_SUPPORT -DZSTD_LEGACY_SUPPORT=0 $^ -o $@$(EXT)
|
||||||
|
|
||||||
CLEAN += zstd-compress
|
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)
|
$(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)
|
## zstd-dictBuilder: executable supporting dictionary creation and compression (only)
|
||||||
CLEAN += zstd-dictBuilder
|
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)
|
$(CC) $(FLAGS) -DZSTD_NOBENCH -DZSTD_NODECOMPRESS -DZSTD_NOTRACE $^ -o $@$(EXT)
|
||||||
|
|
||||||
CLEAN += zstdmt
|
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
|
makefile source list as a small shim so header configuration and platform
|
||||||
preprocessor behavior stay available during the transition.
|
preprocessor behavior stay available during the transition.
|
||||||
|
|
||||||
The original test makefile links `target/release/libzstd_rs.a` with whole-archive
|
The test and program makefiles make `target/release/libzstd_rs.a` a normal
|
||||||
semantics. Rebuild the Rust archive before running C tests so the executable
|
link prerequisite. They rebuild the Rust archive and relink the executable
|
||||||
does not use a stale implementation.
|
when a Rust source changes, so original C tests do not accidentally use a stale
|
||||||
|
implementation.
|
||||||
|
|
||||||
## Validation
|
## Validation
|
||||||
|
|
||||||
|
|||||||
+21
-1
@@ -36,6 +36,18 @@ PRGDIR = ../programs
|
|||||||
PYTHON ?= python3
|
PYTHON ?= python3
|
||||||
TESTARTEFACT := versionsTest
|
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
|
DEBUGFLAGS += -g -Wno-c++-compat
|
||||||
CPPFLAGS += -I$(LIB_SRCDIR) -I$(LIB_SRCDIR)/common -I$(LIB_SRCDIR)/compress -I$(LIB_SRCDIR)/legacy \
|
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) \
|
-I$(LIB_SRCDIR)/dictBuilder -I$(LIB_SRCDIR)/deprecated -I$(PRGDIR) \
|
||||||
@@ -74,7 +86,6 @@ MULTITHREAD_CPP = -DZSTD_MULTITHREAD
|
|||||||
MULTITHREAD_LD = -pthread
|
MULTITHREAD_LD = -pthread
|
||||||
endif
|
endif
|
||||||
MULTITHREAD = $(MULTITHREAD_CPP) $(MULTITHREAD_LD)
|
MULTITHREAD = $(MULTITHREAD_CPP) $(MULTITHREAD_LD)
|
||||||
LDFLAGS += -Wl,--whole-archive ../rust/target/release/libzstd_rs.a -Wl,--no-whole-archive
|
|
||||||
|
|
||||||
VOID = /dev/null
|
VOID = /dev/null
|
||||||
ZSTREAM_TESTTIME ?= -T90s
|
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
|
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)
|
$(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
|
.PHONY: versionsTest
|
||||||
versionsTest: clean
|
versionsTest: clean
|
||||||
$(PYTHON) test-zstd-versions.py
|
$(PYTHON) test-zstd-versions.py
|
||||||
|
|||||||
Reference in New Issue
Block a user