Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Rust bindings #49

Merged
merged 1 commit into from
Oct 14, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions .github/workflows/rust.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
name: Rust/Cargo CI

on:
push:
branches: [ gcc.amd64 ]
pull_request:
branches: [ gcc.amd64 ]

jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@master
with:
toolchain: stable
run: cargo test --all
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -29,3 +29,6 @@
/build
/Makefile
/configure.log

/target
Cargo.lock
27 changes: 27 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
[package]
name = "cloudflare-zlib-sys"
version = "0.3.2"
edition = "2021"
authors = ["Vlad Krasnov <[email protected]>", "Kornel Lesiński <[email protected]>", "Mark Adler <[email protected]>"]
categories = ["external-ffi-bindings", "compression"]
description = "Cloudflare fork of zlib with performance improvements"
documentation = "https://www.zlib.net/manual.html"
homepage = "https://lib.rs/crates/cloudflare-zlib-sys"
repository = "https://github.com/cloudflare/zlib"
include = ["rust/README.md", "LICENSE", "Cargo.toml", "rust/*.rs", "/*.[ch]"]
keywords = ["cloudflare", "libz", "gzip"]
license = "Zlib"
readme = "rust/README.md"
build = "rust/build.rs"
links = "cfzlib"

[lib]
crate-type = ["lib", "staticlib"]
path = "rust/lib.rs"

[build-dependencies]
cc = "1.0.67"

[features]
# Obsolete
asm = []
52 changes: 52 additions & 0 deletions benches/bench.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
#![feature(test)]

extern crate test;
use cloudflare_zlib_sys::*;

#[bench]
fn compress_9(b: &mut test::Bencher) {
let source: Vec<_> = (0..50000).map(|n| {
(((n * 11111111) >> 13) ^ (n * 1321)) as u8
}).collect();
let mut gzbuf = vec![0u8; 50000];
b.iter(|| unsafe {
let mut len = gzbuf.len() as uLong;
assert_eq!(0, compress2(gzbuf.as_mut_ptr(), &mut len,
source.as_ptr(), source.len() as uLong,
Z_BEST_COMPRESSION));
assert!(len > 10000 && len <= 32556);
len
})
}

#[bench]
fn compress_def(b: &mut test::Bencher) {
let source: Vec<_> = (0..50000).map(|n| {
(((n * 11111117) >> 9) ^ (n * 1311)) as u8
}).collect();
let mut gzbuf = vec![0u8; 50000];
b.iter(|| unsafe {
let mut len = gzbuf.len() as uLong;
assert_eq!(0, compress2(gzbuf.as_mut_ptr(), &mut len,
source.as_ptr(), source.len() as uLong,
Z_DEFAULT_COMPRESSION));
assert!(len > 10000 && len <= 31486);
len
})
}

#[bench]
fn compress_1(b: &mut test::Bencher) {
let source: Vec<_> = (0..50000).map(|n| {
(((n * 11110031) >> 12) ^ (n * 1327)) as u8
}).collect();
let mut gzbuf = vec![0u8; 50000];
b.iter(|| unsafe {
let mut len = gzbuf.len() as uLong;
assert_eq!(0, compress2(gzbuf.as_mut_ptr(), &mut len,
source.as_ptr(), source.len() as uLong,
Z_BEST_SPEED));
assert!(len > 10000 && len <= 43967);
len
})
}
6 changes: 6 additions & 0 deletions rust/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# Rust bindings for Zlib with Cloudflare's performance improvements

This crate builds zlib C implementation for 64-bit ARM and Intel CPUs. It requires x86-64 CPU with SSE 4.2 or ARM64 with NEON & CRC. 32-bit architectures are not supported at all.

The API/ABI of the library is the same as original Zlib's.

87 changes: 87 additions & 0 deletions rust/build.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
use std::env;
use std::path::PathBuf;

fn main() {
let mut cc = cc::Build::new();
let comp = cc.get_compiler();
let msvc_bugs = comp.is_like_msvc();
cc.warnings(false);
cc.pic(true);

let target_pointer_width = env::var("CARGO_CFG_TARGET_POINTER_WIDTH").expect("CARGO_CFG_TARGET_POINTER_WIDTH var");
let target_arch = env::var("CARGO_CFG_TARGET_ARCH").expect("CARGO_CFG_TARGET_ARCH var");

if target_pointer_width != "64" {
println!("cargo:warning=cloudflare-zlib does not support 32-bit architectures");
}

if let Ok(target_cpu) = env::var("TARGET_CPU") {
cc.flag_if_supported(&format!("-march={}", target_cpu));
}

let vendor = PathBuf::from(env::var_os("CARGO_MANIFEST_DIR").unwrap());
println!("cargo:include={}", vendor.display());
cc.include(&vendor);

if target_arch == "aarch64" {
cc.define("INFLATE_CHUNK_SIMD_NEON", Some("1"));
cc.define("ADLER32_SIMD_NEON", Some("1"));
} else if target_arch == "x86_64" {
cc.define("INFLATE_CHUNK_SIMD_SSE2", Some("1"));
if msvc_bugs {
cc.define("__x86_64__", Some("1"));
}
}

cc.define("INFLATE_CHUNK_READ_64LE", Some("1"));

if msvc_bugs {
cc.define("_CRT_SECURE_NO_DEPRECATE", Some("1"));
cc.define("_CRT_NONSTDC_NO_DEPRECATE", Some("1"));
cc.flag_if_supported("/arch:AVX");
} else {
cc.define("HAVE_UNISTD_H", Some("1"));
cc.define("HAVE_HIDDEN", Some("1"));

if "32" != target_pointer_width {
cc.define("HAVE_OFF64_T", Some("1"));
cc.define("_LARGEFILE64_SOURCE", Some("1"));
}
if target_arch == "aarch64" {
cc.flag_if_supported("-march=armv8-a+crc");
} else {
if cc.is_flag_supported("-mssse3").is_ok() {
cc.flag("-mssse3");
cc.define("ADLER32_SIMD_SSSE3", Some("1"));
}
if cc.is_flag_supported("-mpclmul").is_ok() {
cc.flag("-mpclmul");
cc.define("HAS_PCLMUL", None);
cc.file(vendor.join("crc32_simd.c"));
cc.flag_if_supported("-msse4.2");
}
}
}

cc.file(vendor.join("adler32.c"));
cc.file(vendor.join("adler32_simd.c"));
cc.file(vendor.join("crc32.c"));
cc.file(vendor.join("deflate.c"));
cc.file(vendor.join("infback.c"));
cc.file(vendor.join("inffast.c"));
cc.file(vendor.join("inflate.c"));
cc.file(vendor.join("inftrees.c"));
cc.file(vendor.join("trees.c"));
cc.file(vendor.join("zutil.c"));

cc.file(vendor.join("compress.c"));
cc.file(vendor.join("uncompr.c"));
cc.file(vendor.join("gzclose.c"));
cc.file(vendor.join("gzlib.c"));
cc.file(vendor.join("gzread.c"));
cc.file(vendor.join("gzwrite.c"));

cc.file(vendor.join("inffast_chunk.c"));

cc.compile("cloudflare_zlib");
}
Loading