ports@,

since we have security/blake3 in the tree it looks ligical to switch b3sum
to use that library as well.

It requires some cargo hacking and some patch work, but it is not that
dirty.

What do you think?

Index: Makefile
===================================================================
RCS file: /cvs/ports/security/b3sum/Makefile,v
diff -u -p -r1.1.1.1 Makefile
--- Makefile    6 May 2026 18:12:55 -0000       1.1.1.1
+++ Makefile    27 Jun 2026 21:58:56 -0000
@@ -1,6 +1,7 @@
 COMMENT =              command line BLAKE3 checksum utility
 
 V =                    1.8.5
+REVISION =             0
 PKGNAME =              b3sum-${V}
 
 DIST_TUPLE =           github BLAKE3-team BLAKE3 ${V} .
@@ -13,11 +14,13 @@ HOMEPAGE =          https://github.com/BLAKE3-te
 # CC0-1.0 or Apache-2.0
 PERMIT_PACKAGE =       Yes
 
-WANTLIB +=             ${MODCARGO_WANTLIB}
+WANTLIB +=             ${MODCARGO_WANTLIB} blake3
 
 MODULES =              devel/cargo
 
 CONFIGURE_STYLE =      cargo
+
+LIB_DEPENDS +=         security/blake3
 
 SEPARATE_BUILD =       Yes
 
Index: patches/patch-b3sum_Cargo_lock
===================================================================
RCS file: patches/patch-b3sum_Cargo_lock
diff -N patches/patch-b3sum_Cargo_lock
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ patches/patch-b3sum_Cargo_lock      27 Jun 2026 21:58:56 -0000
@@ -0,0 +1,25 @@
+Index: b3sum/Cargo.lock
+--- b3sum/Cargo.lock.orig
++++ b3sum/Cargo.lock
+@@ -76,6 +76,7 @@ version = "1.8.5"
+ dependencies = [
+  "anyhow",
+  "blake3",
++ "blake3_c_rust_bindings",
+  "clap",
+  "duct",
+  "hex",
+@@ -102,6 +103,13 @@ dependencies = [
+  "cpufeatures",
+  "memmap2",
+  "rayon-core",
++]
++
++[[package]]
++name = "blake3_c_rust_bindings"
++version = "0.0.0"
++dependencies = [
++ "cc",
+ ]
+ 
+ [[package]]
Index: patches/patch-b3sum_Cargo_toml
===================================================================
RCS file: patches/patch-b3sum_Cargo_toml
diff -N patches/patch-b3sum_Cargo_toml
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ patches/patch-b3sum_Cargo_toml      27 Jun 2026 21:58:56 -0000
@@ -0,0 +1,18 @@
+Index: b3sum/Cargo.toml
+--- b3sum/Cargo.toml.orig
++++ b3sum/Cargo.toml
+@@ -15,12 +15,13 @@ pure = ["blake3/pure"]
+ 
+ [dependencies]
+ anyhow = "1.0.25"
+-blake3 = { version = "1.8", path = "..", features = ["mmap", "rayon"] }
++blake3 = { package = "blake3_c_rust_bindings", path = 
"../c/blake3_c_rust_bindings", default-features = false, features = ["system"] }
+ clap = { version = "4.0.8", features = ["derive", "wrap_help"] }
+ hex = "0.4.0"
+ rayon-core = "1.12.1"
+ wild = "2.0.3"
+ 
+ [dev-dependencies]
++blake3_rust = { package = "blake3", path = "..", features = ["mmap", "rayon"] 
}
+ duct = "1.0.0"
+ tempfile = "3.1.0"
Index: patches/patch-b3sum_src_main_rs
===================================================================
RCS file: patches/patch-b3sum_src_main_rs
diff -N patches/patch-b3sum_src_main_rs
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ patches/patch-b3sum_src_main_rs     27 Jun 2026 21:58:56 -0000
@@ -0,0 +1,104 @@
+Index: b3sum/src/main.rs
+--- b3sum/src/main.rs.orig
++++ b3sum/src/main.rs
+@@ -19,6 +19,30 @@ const RAW_ARG: &str = "raw";
+ const TAG_ARG: &str = "tag";
+ const CHECK_ARG: &str = "check";
+ 
++#[derive(Clone)]
++struct OutputReader {
++    hasher: blake3::Hasher,
++    position: u64,
++}
++
++impl OutputReader {
++    fn new(hasher: blake3::Hasher, position: u64) -> Self {
++        Self { hasher, position }
++    }
++
++    fn fill(&mut self, buf: &mut [u8]) {
++        self.hasher.finalize_seek(self.position, buf);
++        self.position = self.position.wrapping_add(buf.len() as u64);
++    }
++}
++
++impl Read for OutputReader {
++    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
++        self.fill(buf);
++        Ok(buf.len())
++    }
++}
++
+ #[derive(Parser)]
+ #[command(version, max_term_width(100))]
+ struct Inner {
+@@ -121,7 +145,7 @@ impl Args {
+             // `-` arguments. Input::open handles that case below.
+             blake3::Hasher::new_keyed(&read_key_from_stdin()?)
+         } else if let Some(ref context) = inner.derive_key {
+-            blake3::Hasher::new_derive_key(context)
++            blake3::Hasher::new_derive_key_raw(context.as_bytes())
+         } else {
+             blake3::Hasher::new()
+         };
+@@ -173,25 +197,42 @@ impl Args {
+     }
+ }
+ 
+-fn hash_path(args: &Args, path: &Path) -> 
anyhow::Result<blake3::OutputReader> {
++fn update_reader(
++    hasher: &mut blake3::Hasher,
++    mut reader: impl Read,
++) -> io::Result<u64> {
++    // Match the buffer size used by the root crate's update_reader helper.
++    let mut buffer = [0; 65536];
++    let mut total = 0;
++    loop {
++        match reader.read(&mut buffer) {
++            Ok(0) => return Ok(total),
++            Ok(n) => {
++                hasher.update(&buffer[..n]);
++                total += n as u64;
++            }
++            Err(e) if e.kind() == io::ErrorKind::Interrupted => continue,
++            Err(e) => return Err(e),
++        }
++    }
++}
++
++fn hash_path(args: &Args, path: &Path) -> anyhow::Result<OutputReader> {
+     let mut hasher = args.base_hasher.clone();
+     if path == Path::new("-") {
+         if args.keyed() {
+             bail!("Cannot open `-` in keyed mode");
+         }
+-        hasher.update_reader(io::stdin().lock())?;
++        update_reader(&mut hasher, io::stdin().lock())?;
+     } else if args.no_mmap() {
+-        hasher.update_reader(File::open(path)?)?;
++        update_reader(&mut hasher, File::open(path)?)?;
+     } else {
+-        // The fast path: Try to mmap the file and hash it with multiple 
threads.
+-        hasher.update_mmap_rayon(path)?;
++        update_reader(&mut hasher, File::open(path)?)?;
+     }
+-    let mut output_reader = hasher.finalize_xof();
+-    output_reader.set_position(args.seek());
+-    Ok(output_reader)
++    Ok(OutputReader::new(hasher, args.seek()))
+ }
+ 
+-fn write_hex_output(mut output: blake3::OutputReader, args: &Args) -> 
anyhow::Result<()> {
++fn write_hex_output(mut output: OutputReader, args: &Args) -> 
anyhow::Result<()> {
+     // Encoding multiples of the 64 bytes is most efficient.
+     // TODO: This computes each output block twice when the --seek argument 
isn't a multiple of 64.
+     // We'll refactor all of this soon anyway, once SIMD optimizations are 
available for the XOF.
+@@ -207,7 +248,7 @@ fn write_hex_output(mut output: blake3::OutputReader, 
+     Ok(())
+ }
+ 
+-fn write_raw_output(output: blake3::OutputReader, args: &Args) -> 
anyhow::Result<()> {
++fn write_raw_output(output: OutputReader, args: &Args) -> anyhow::Result<()> {
+     let mut output = output.take(args.len());
+     let stdout = std::io::stdout();
+     let mut handler = stdout.lock();
Index: patches/patch-c_blake3_c_rust_bindings_Cargo_toml
===================================================================
RCS file: patches/patch-c_blake3_c_rust_bindings_Cargo_toml
diff -N patches/patch-c_blake3_c_rust_bindings_Cargo_toml
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ patches/patch-c_blake3_c_rust_bindings_Cargo_toml   27 Jun 2026 21:58:56 
-0000
@@ -0,0 +1,19 @@
+Index: c/blake3_c_rust_bindings/Cargo.toml
+--- c/blake3_c_rust_bindings/Cargo.toml.orig
++++ c/blake3_c_rust_bindings/Cargo.toml
+@@ -10,6 +10,9 @@ description = "TESTING ONLY Rust bindings for the BLAK
+ edition = "2024"
+ 
+ [features]
++default = ["ignore"]
++system = []
++pure = []
+ # By default the x86-64 build uses assembly implementations. This feature 
makes
+ # the build use the C intrinsics implementations instead.
+ prefer_intrinsics = []
+@@ -29,4 +32,4 @@ reference_impl = { path = "../../reference_impl" }
+ 
+ [build-dependencies]
+ cc = "1.0.48"
+-ignore = "0.4.23"
++ignore = { version = "0.4.23", optional = true }
Index: patches/patch-c_blake3_c_rust_bindings_build_rs
===================================================================
RCS file: patches/patch-c_blake3_c_rust_bindings_build_rs
diff -N patches/patch-c_blake3_c_rust_bindings_build_rs
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ patches/patch-c_blake3_c_rust_bindings_build_rs     27 Jun 2026 21:58:56 
-0000
@@ -0,0 +1,51 @@
+Index: c/blake3_c_rust_bindings/build.rs
+--- c/blake3_c_rust_bindings/build.rs.orig
++++ c/blake3_c_rust_bindings/build.rs
+@@ -1,4 +1,5 @@
+ use std::env;
++use std::process::Command;
+ 
+ fn defined(var: &str) -> bool {
+     env::var_os(var).is_some()
+@@ -102,7 +103,33 @@ fn c_dir_path(filename: &str) -> String {
+     }
+ }
+ 
++fn pkg_config(args: &[&str]) -> Option<String> {
++    let pkg_config = env::var_os("PKG_CONFIG").unwrap_or_else(|| 
"pkg-config".into());
++    let output = Command::new(pkg_config).args(args).output().ok()?;
++    if output.status.success() {
++        Some(String::from_utf8_lossy(&output.stdout).trim().to_string())
++    } else {
++        None
++    }
++}
++
+ fn main() -> Result<(), Box<dyn std::error::Error>> {
++    if defined("CARGO_FEATURE_SYSTEM") {
++        println!("cargo::rerun-if-env-changed=PKG_CONFIG");
++        println!("cargo::rerun-if-env-changed=PKG_CONFIG_PATH");
++        println!("cargo::rerun-if-env-changed=PKG_CONFIG_LIBDIR");
++        println!("cargo::rerun-if-env-changed=PKG_CONFIG_SYSROOT_DIR");
++
++        if let Some(libdir) = pkg_config(&["--variable=libdir", "libblake3"]) 
{
++            if !libdir.is_empty() {
++                println!("cargo::rustc-link-search=native={libdir}");
++                println!("cargo::rustc-link-lib=blake3");
++                return Ok(());
++            }
++        }
++        return Err("pkg-config libblake3 lookup failed".into());
++    }
++
+     let mut base_build = new_build();
+     base_build.file(c_dir_path("blake3.c"));
+     base_build.file(c_dir_path("blake3_dispatch.c"));
+@@ -232,6 +259,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
+ 
+     // Ditto for source files, though these shouldn't change as often. 
`ignore::Walk` respects
+     // .gitignore, so this doesn't traverse target/.
++    #[cfg(feature = "ignore")]
+     for result in ignore::Walk::new("..") {
+         let result = result?;
+         let path = result.path();
Index: patches/patch-c_blake3_c_rust_bindings_src_lib_rs
===================================================================
RCS file: patches/patch-c_blake3_c_rust_bindings_src_lib_rs
diff -N patches/patch-c_blake3_c_rust_bindings_src_lib_rs
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ patches/patch-c_blake3_c_rust_bindings_src_lib_rs   27 Jun 2026 21:58:56 
-0000
@@ -0,0 +1,14 @@
+Index: c/blake3_c_rust_bindings/src/lib.rs
+--- c/blake3_c_rust_bindings/src/lib.rs.orig
++++ c/blake3_c_rust_bindings/src/lib.rs
+@@ -11,7 +11,10 @@ mod test;
+ 
+ pub const BLOCK_LEN: usize = 64;
+ pub const CHUNK_LEN: usize = 1024;
++// The C header exposes the keyed API as a 32-byte key, but not a named 
constant.
++pub const KEY_LEN: usize = 32;
+ pub const OUT_LEN: usize = 32;
++pub type Hash = [u8; OUT_LEN];
+ 
+ // Feature detection functions for tests and benchmarks. Note that the C code
+ // does its own feature detection in blake3_dispatch.c.


-- 
wbr, Kirill

Reply via email to