From 3660391791ccadf584bcbfd0b9238fca13e52522 Mon Sep 17 00:00:00 2001 From: Fabio Valentini Date: Wed, 25 Sep 2024 17:10:14 +0200 Subject: [PATCH] unconditionally use pkg-config to link with system zlib --- build.rs | 243 +------------------------------------------------------ 1 file changed, 4 insertions(+), 239 deletions(-) diff --git a/build.rs b/build.rs index cab160a..8d1acf7 100644 --- a/build.rs +++ b/build.rs @@ -1,244 +1,9 @@ -use std::env; -use std::fs; -use std::path::PathBuf; - fn main() { - println!("cargo:rerun-if-env-changed=LIBZ_SYS_STATIC"); println!("cargo:rerun-if-changed=build.rs"); - println!("cargo:rerun-if-changed=zng/cmake.rs"); - println!("cargo:rerun-if-changed=zng/cc.rs"); - - let host = env::var("HOST").unwrap(); - let target = env::var("TARGET").unwrap(); - - let host_and_target_contain = |s| host.contains(s) && target.contains(s); - - let want_ng = cfg!(any( - feature = "zlib-ng", - feature = "zlib-ng-no-cmake-experimental-community-maintained" - )) && !cfg!(feature = "stock-zlib"); - - if want_ng && target != "wasm32-unknown-unknown" { - return build_zlib_ng(&target, true); - } - - // All android compilers should come with libz by default, so let's just use - // the one already there. Likewise, Haiku always ships with libz, so we can - // link to it even when cross-compiling. - if target.contains("android") || target.contains("haiku") { - println!("cargo:rustc-link-lib=z"); - return; - } - - // 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 - // `-L /usr/lib` which wreaks havoc with linking to an OpenSSL in /usr/local/lib - // (Ports, etc.) - let want_static = - cfg!(feature = "static") || env::var("LIBZ_SYS_STATIC").unwrap_or(String::new()) == "1"; - if !want_static && - !target.contains("msvc") && // pkg-config just never works here - !(host_and_target_contain("freebsd") || - host_and_target_contain("dragonfly")) - { - // Don't print system lib dirs to cargo since this interferes with other - // packages adding non-system search paths to link against libraries - // that are also found in a system-wide lib dir. - let zlib = pkg_config::Config::new() - .cargo_metadata(true) - .print_system_libs(false) - .probe("zlib"); - match zlib { - Ok(zlib) => { - if !zlib.include_paths.is_empty() { - let paths = zlib - .include_paths - .iter() - .map(|s| s.display().to_string()) - .collect::>(); - println!("cargo:include={}", paths.join(",")); - } - } - Err(e) => { - println!("cargo-warning={}", e.to_string()) - } - } - } - - if target.contains("windows") { - if try_vcpkg() { - return; - } - } - - let mut cfg = cc::Build::new(); - - // Situations where we build unconditionally. - // - // MSVC basically never has it preinstalled, MinGW picks up a bunch of weird - // paths we don't like, `want_static` may force us, and cross compiling almost - // never has a prebuilt version. - // - // Apple platforms have libz.1.dylib, and it's usually available even when - // cross compiling (via fat binary or in the target's Xcode SDK) - let cross_compiling = target != host; - if target.contains("msvc") - || target.contains("pc-windows-gnu") - || want_static - || (cross_compiling && !target.contains("-apple-")) - { - return build_zlib(&mut cfg, &target); - } - - // 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. - // - // In any case test if zlib is actually installed and if so we link to it, - // otherwise continue below to build things. - if zlib_installed(&mut cfg) { - println!("cargo:rustc-link-lib=z"); - return; - } - - build_zlib(&mut cfg, &target) -} - -fn build_zlib(cfg: &mut cc::Build, target: &str) { - let dst = PathBuf::from(env::var_os("OUT_DIR").unwrap()); - let lib = dst.join("lib"); - - cfg.warnings(false).out_dir(&lib).include("src/zlib"); - - cfg.file("src/zlib/adler32.c") - .file("src/zlib/compress.c") - .file("src/zlib/crc32.c") - .file("src/zlib/deflate.c") - .file("src/zlib/infback.c") - .file("src/zlib/inffast.c") - .file("src/zlib/inflate.c") - .file("src/zlib/inftrees.c") - .file("src/zlib/trees.c") - .file("src/zlib/uncompr.c") - .file("src/zlib/zutil.c"); - if !cfg!(feature = "libc") || target.starts_with("wasm32") { - cfg.define("Z_SOLO", None); - } else { - cfg.file("src/zlib/gzclose.c") - .file("src/zlib/gzlib.c") - .file("src/zlib/gzread.c") - .file("src/zlib/gzwrite.c"); - } - - if !target.contains("windows") { - cfg.define("STDC", None); - cfg.define("_LARGEFILE64_SOURCE", None); - cfg.define("_POSIX_SOURCE", None); - cfg.flag("-fvisibility=hidden"); - } - if target.contains("apple") { - cfg.define("_C99_SOURCE", None); - } - if target.contains("solaris") { - cfg.define("_XOPEN_SOURCE", "700"); - } - - cfg.compile("z"); - - fs::create_dir_all(dst.join("include")).unwrap(); - fs::copy("src/zlib/zlib.h", dst.join("include/zlib.h")).unwrap(); - fs::copy("src/zlib/zconf.h", dst.join("include/zconf.h")).unwrap(); - - fs::create_dir_all(lib.join("pkgconfig")).unwrap(); - let zlib_h = fs::read_to_string(dst.join("include/zlib.h")).unwrap(); - let version = zlib_h - .lines() - .find(|l| l.contains("ZLIB_VERSION")) - .unwrap() - .split("\"") - .nth(1) + pkg_config::Config::new() + .cargo_metadata(true) + .print_system_libs(false) + .probe("zlib") .unwrap(); - fs::write( - lib.join("pkgconfig/zlib.pc"), - fs::read_to_string("src/zlib/zlib.pc.in") - .unwrap() - .replace("@prefix@", dst.to_str().unwrap()) - .replace("@includedir@", "${prefix}/include") - .replace("@libdir@", "${prefix}/lib") - .replace("@VERSION@", version), - ) - .unwrap(); - - println!("cargo:root={}", dst.to_str().unwrap()); - println!("cargo:rustc-link-search=native={}", lib.to_str().unwrap()); - println!("cargo:include={}/include", dst.to_str().unwrap()); -} - -#[cfg(any( - feature = "zlib-ng", - feature = "zlib-ng-no-cmake-experimental-community-maintained" -))] -mod zng { - #[cfg_attr(feature = "zlib-ng", path = "cmake.rs")] - #[cfg_attr( - all( - feature = "zlib-ng-no-cmake-experimental-community-maintained", - not(feature = "zlib-ng") - ), - path = "cc.rs" - )] - mod build_zng; - - pub(super) use build_zng::build_zlib_ng; -} - -fn build_zlib_ng(_target: &str, _compat: bool) { - #[cfg(any( - feature = "zlib-ng", - feature = "zlib-ng-no-cmake-experimental-community-maintained" - ))] - zng::build_zlib_ng(_target, _compat); -} - -fn try_vcpkg() -> bool { - // see if there is a vcpkg tree with zlib installed - match vcpkg::Config::new() - .emit_includes(true) - .find_package("zlib") - { - Ok(zlib) => { - if !zlib.include_paths.is_empty() { - let paths = zlib - .include_paths - .iter() - .map(|s| s.display().to_string()) - .collect::>(); - println!("cargo:include={}", paths.join(",")); - } - true - } - Err(e) => { - println!("note, vcpkg did not find zlib: {}", e); - false - } - } -} - -fn zlib_installed(cfg: &mut cc::Build) -> bool { - let mut cmd = cfg.get_compiler().to_command(); - cmd.arg("src/smoke.c") - .arg("-g0") - .arg("-o") - .arg("/dev/null") - .arg("-lz"); - - println!("running {:?}", cmd); - if let Ok(status) = cmd.status() { - if status.success() { - return true; - } - } - - false } -- 2.46.2