diff --git a/programs/Makefile b/programs/Makefile index 7df1d0467..f7f171d4f 100644 --- a/programs/Makefile +++ b/programs/Makefile @@ -125,7 +125,7 @@ RUST_CLI_STATICLIB := $(RUST_CLI_TARGET_DIR)/release/libzstd_cli_rs.a RUST_CLI_STATICLIB_32 := $(RUST_CLI_TARGET_DIR)/$(RUST_TARGET_32)/release/libzstd_cli_rs.a RUST_CLI_CARGO_FLAGS := --manifest-path $(RUST_CLI_MANIFEST) --release \ --target-dir $(RUST_CLI_TARGET_DIR) \ - --no-default-features --features cli,compression,decompression,benchmark + --no-default-features --features cli,compression,decompression,benchmark,dict-builder $(RUST_CLI_STATICLIB): $(RUST_CLI_SOURCES) $(CARGO) build $(RUST_CLI_CARGO_FLAGS) @@ -206,6 +206,16 @@ RUST_COMPRESS_CLI_CARGO_FLAGS := --manifest-path $(RUST_CLI_MANIFEST) --release $(RUST_COMPRESS_CLI_STATICLIB): $(RUST_CLI_SOURCES) $(CARGO) build $(RUST_COMPRESS_CLI_CARGO_FLAGS) +RUST_DICTBUILDER_CLI_BUILD_CONFIG := cli-c1-d0-dictbuilder-$(RUST_HUF_MODE) +RUST_DICTBUILDER_CLI_TARGET_DIR := $(RUST_DIR)/target/$(RUST_DICTBUILDER_CLI_BUILD_CONFIG) +RUST_DICTBUILDER_CLI_STATICLIB := $(RUST_DICTBUILDER_CLI_TARGET_DIR)/release/libzstd_cli_rs.a +RUST_DICTBUILDER_CLI_CARGO_FLAGS := --manifest-path $(RUST_CLI_MANIFEST) --release \ + --target-dir $(RUST_DICTBUILDER_CLI_TARGET_DIR) \ + --no-default-features --features cli,compression,dict-builder + +$(RUST_DICTBUILDER_CLI_STATICLIB): $(RUST_CLI_SOURCES) + $(CARGO) build $(RUST_DICTBUILDER_CLI_CARGO_FLAGS) + # Most program objects use a configuration-hashed directory, but the compact # direct-source variants below do not. Give their C outputs an independent # mode stamp so they cannot outlive a different Rust HUF archive selection. @@ -479,7 +489,7 @@ zstd-compress: $(ZSTDLIB_COMMON_SRC) $(ZSTDLIB_COMPRESS_SRC) zstdcli.c util.c ti ## 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 $(RUST_DICTBUILDER_STATICLIB) $(RUST_COMPRESS_CLI_STATICLIB) +zstd-dictBuilder: $(ZSTDLIB_COMMON_SRC) $(ZSTDLIB_COMPRESS_SRC) $(ZDICT_SRC) zstdcli.c util.c timefn.c fileio.c fileio_asyncio.c dibio.c $(RUST_DICTBUILDER_STATICLIB) $(RUST_DICTBUILDER_CLI_STATICLIB) $(CC) $(FLAGS) -DZSTD_NOBENCH -DZSTD_NODECOMPRESS -DZSTD_NOTRACE $^ -o $@$(EXT) RUST_DIRECT_LINK_TARGETS := zstd32 zstd-nolegacy zstd-small zstd-frugal \ diff --git a/rust/cli/Cargo.toml b/rust/cli/Cargo.toml index 63035c22f..344091b43 100644 --- a/rust/cli/Cargo.toml +++ b/rust/cli/Cargo.toml @@ -14,6 +14,7 @@ default = ["cli", "compression", "decompression", "benchmark"] cli = [] compression = [] decompression = [] +dict-builder = ["compression"] helpers = [] # The integrated benchmark archive is optional so zstd-small and zstd-frugal # can omit every benchmark implementation and its timing/data-generator diff --git a/rust/cli/src/lib.rs b/rust/cli/src/lib.rs index 1600f404e..229dc673c 100644 --- a/rust/cli/src/lib.rs +++ b/rust/cli/src/lib.rs @@ -7,7 +7,7 @@ mod benchzstd; #[cfg(any(feature = "benchmark", feature = "helpers"))] #[path = "../../src/datagen.rs"] mod datagen; -#[cfg(feature = "cli")] +#[cfg(all(feature = "cli", feature = "dict-builder"))] #[path = "../../src/dibio.rs"] mod dibio; #[cfg(feature = "cli")] diff --git a/rust/src/zstd_cli.rs b/rust/src/zstd_cli.rs index c9fd09b86..047203683 100644 --- a/rust/src/zstd_cli.rs +++ b/rust/src/zstd_cli.rs @@ -152,6 +152,7 @@ struct ZDICT_fastCover_params_t { #[repr(C)] #[derive(Clone, Copy, Debug, Default, PartialEq)] +#[cfg(all(feature = "compression", feature = "dict-builder"))] struct ZDICT_legacy_params_t { selectivityLevel: c_uint, zParams: ZDICT_params_t, @@ -297,7 +298,7 @@ unsafe extern "C" { /// Narrow bridge to `programs/dibio.c`. The file loader and dictionary /// algorithms remain on the C/Rust library side of this boundary. - #[cfg(feature = "compression")] + #[cfg(all(feature = "compression", feature = "dict-builder"))] fn DiB_trainFromFiles( dict_file_name: *const c_char, max_dict_size: usize, @@ -688,7 +689,7 @@ const fn max_c_level_for_help() -> i32 { } fn write_basic_usage(out: &mut W, program_name: &str) { - let max_level = DEFAULT_MAX_CLEVEL; + let max_level = max_c_level_for_help(); let _ = writeln!( out, "Compress or decompress the INPUT file(s); reads from STDIN if INPUT is `-` or not provided." @@ -2538,13 +2539,13 @@ fn run_bench(cli: &Cli) -> Result { /// file loading and output path stay in that bridge for now; the selected /// dictionary builder symbols are supplied by the Rust library archive. fn run_train(cli: &Cli) -> Result { - #[cfg(not(feature = "compression"))] + #[cfg(not(all(feature = "compression", feature = "dict-builder")))] { let _ = cli; - return Err("training mode not available".to_owned()); + Err("training mode not available".to_owned()) } - #[cfg(feature = "compression")] + #[cfg(all(feature = "compression", feature = "dict-builder"))] { let default_output = cstring(DEFAULT_DICT_NAME).expect("static dictionary name"); let output = cli.output.as_ref().unwrap_or(&default_output);