From 45b0a1921f0b0749cd470382e7ddceb1f9cdc6fc Mon Sep 17 00:00:00 2001 From: Amy Kwan Date: Wed, 22 Apr 2026 11:07:24 -0400 Subject: [PATCH 1/2] [AIX] Use zlibNX if available. This change prevents libz-sys from building its own zlib by using zlibNX if available, which is an version of the zlib library that supports hardware accelerated data compression and decompression. --- build.rs | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/build.rs b/build.rs index 981b43ca..602ef90e 100644 --- a/build.rs +++ b/build.rs @@ -30,6 +30,19 @@ fn main() { return; } + // On AIX, use zlibNX if available. + if target.contains("aix") { + let zlibNX_lib = "/usr/opt/zlibNX/lib"; + let zlibNX_include = "/usr/opt/zlibNX/include"; + if std::path::Path::new(zlibNX_lib).join("libz.a").exists() && + std::path::Path::new(zlibNX_include).join("zlib.h").exists() { + println!("cargo:rustc-link-search=native={}", zlibNX_lib); + println!("cargo:rustc-link-lib=z"); + println!("cargo:include={}", zlibNX_include); + return; + } + } + let want_static = should_link_static(); // Don't run pkg-config if we're linking statically (we'll build below) and // also don't run pkg-config on FreeBSD/DragonFly. That'll end up printing From 8db860915f579b57dcd6db5dee5a4ee61196fb9f Mon Sep 17 00:00:00 2001 From: Amy Kwan Date: Fri, 24 Apr 2026 12:38:54 -0400 Subject: [PATCH 2/2] Fix zlibNX handling to honor static mode and validate linkability This change addresses two issues with respect to AIX zlibNX support: 1. The zlibNX check is moved after should_link_static() to allow users to force static builds even when zlibNX is present. 2. zlibNX linkability is validated prior to using it. The zlibnx_installed() function is added and compiles/links a test program (similar to zlib_installed() validation). --- build.rs | 56 +++++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 43 insertions(+), 13 deletions(-) diff --git a/build.rs b/build.rs index 602ef90e..bca0b192 100644 --- a/build.rs +++ b/build.rs @@ -30,19 +30,6 @@ fn main() { return; } - // On AIX, use zlibNX if available. - if target.contains("aix") { - let zlibNX_lib = "/usr/opt/zlibNX/lib"; - let zlibNX_include = "/usr/opt/zlibNX/include"; - if std::path::Path::new(zlibNX_lib).join("libz.a").exists() && - std::path::Path::new(zlibNX_include).join("zlib.h").exists() { - println!("cargo:rustc-link-search=native={}", zlibNX_lib); - println!("cargo:rustc-link-lib=z"); - println!("cargo:include={}", zlibNX_include); - return; - } - } - let want_static = should_link_static(); // Don't run pkg-config if we're linking statically (we'll build below) and // also don't run pkg-config on FreeBSD/DragonFly. That'll end up printing @@ -96,6 +83,24 @@ fn main() { return build_zlib(&mut cfg, &target); } + // On AIX, prefer zlibNX if available and linkable. + if target.contains("aix") { + let zlibnx_lib = "/usr/opt/zlibNX/lib"; + let zlibnx_include = "/usr/opt/zlibNX/include"; + if std::path::Path::new(zlibnx_lib).join("libz.a").exists() + && std::path::Path::new(zlibnx_include).join("zlib.h").exists() + { + if zlibnx_installed(&mut cfg, zlibnx_lib, zlibnx_include) { + println!("cargo:rustc-link-search=native={}", zlibnx_lib); + println!("cargo:rustc-link-lib=z"); + println!("cargo:include={}", zlibnx_include); + return; + } else { + println!("cargo:warning=zlibNX found at {} but not linkable, falling back to bundled zlib", zlibnx_lib); + } + } + } + // If we've gotten this far we're probably a pretty standard platform. // Almost all platforms here ship libz by default, but some don't have // pkg-config files that we would find above. @@ -249,6 +254,31 @@ fn zlib_installed(cfg: &mut cc::Build) -> bool { false } +fn zlibnx_installed(cfg: &mut cc::Build, lib_dir: &str, include_dir: &str) -> bool { + let out_dir = PathBuf::from(env::var_os("OUT_DIR").unwrap()); + let test_file = out_dir.join("smoke_test_zlibnx"); + let mut cmd = cfg.get_compiler().to_command(); + cmd.arg("src/smoke.c") + .arg("-g0") + .arg("-o") + .arg(&test_file) + .arg(format!("-L{}", lib_dir)) + .arg(format!("-I{}", include_dir)) + .arg("-lz"); + + println!("running {:?}", cmd); + let result = if let Ok(status) = cmd.status() { + status.success() + } else { + false + }; + + // Clean up test file. + let _ = fs::remove_file(&test_file); + + result +} + /// The environment variable `LIBZ_SYS_STATIC` is first checked for a value of `0` (false) or `1` (true), /// before considering the `static` feature when no explicit ENV value was detected. /// When `libz-sys` is a transitive dependency from a crate that forces static linking via the `static` feature,