From 7d6c389b4f3330696e737110bbb9f7c38101da55 Mon Sep 17 00:00:00 2001 From: Fabio Valentini Date: Wed, 10 Jan 2024 17:12:19 +0100 Subject: [PATCH] unconditionally use pkg-config to link with system zlib --- build.rs | 197 ++------------------------------------------------- build_zng.rs | 60 ---------------- 2 files changed, 4 insertions(+), 253 deletions(-) delete mode 100644 build_zng.rs diff --git a/build.rs b/build.rs index 1368a12..8d1acf7 100644 --- a/build.rs +++ b/build.rs @@ -1,198 +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"); - 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!(feature = "zlib-ng") && !cfg!(feature = "stock-zlib"); - - if want_ng && target != "wasm32-unknown-unknown" { - return build_zlib_ng(&target, true); - } - - // 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(_) => return, - Err(e) => { - println!("cargo-warning={}", e.to_string()) - } - } - } - - if target.contains("windows") { - if try_vcpkg() { - return; - } - } - - // 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; - } - - 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; - let apple_to_apple = host.contains("-apple-") && target.contains("-apple-"); - if target.contains("msvc") - || target.contains("pc-windows-gnu") - || want_static - || (cross_compiling && !apple_to_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(not(feature = "zlib-ng"))] -fn build_zlib_ng(_target: &str, _compat: bool) {} - -#[cfg(feature = "zlib-ng")] -mod build_zng; -#[cfg(feature = "zlib-ng")] -use build_zng::build_zlib_ng; - -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(_) => 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("-o").arg("/dev/null").arg("-lz"); - - println!("running {:?}", cmd); - if let Ok(status) = cmd.status() { - if status.success() { - return true; - } - } - - false } diff --git a/build_zng.rs b/build_zng.rs deleted file mode 100644 index 2557625..0000000 --- a/build_zng.rs +++ /dev/null @@ -1,60 +0,0 @@ -use std::env; - -pub fn build_zlib_ng(target: &str, compat: bool) { - let mut cmake = cmake::Config::new("src/zlib-ng"); - cmake - .define("BUILD_SHARED_LIBS", "OFF") - .define("ZLIB_COMPAT", if compat { "ON" } else { "OFF" }) - .define("ZLIB_ENABLE_TESTS", "OFF") - .define("WITH_GZFILEOP", "ON"); - if target.contains("s390x") { - // Enable hardware compression on s390x. - cmake - .define("WITH_DFLTCC_DEFLATE", "1") - .define("WITH_DFLTCC_INFLATE", "1") - .cflag("-DDFLTCC_LEVEL_MASK=0x7e"); - } - if target == "i686-pc-windows-msvc" { - cmake.define("CMAKE_GENERATOR_PLATFORM", "Win32"); - } - - let install_dir = cmake.build(); - - let includedir = install_dir.join("include"); - let libdir = install_dir.join("lib"); - let libdir64 = install_dir.join("lib64"); - println!( - "cargo:rustc-link-search=native={}", - libdir.to_str().unwrap() - ); - println!( - "cargo:rustc-link-search=native={}", - libdir64.to_str().unwrap() - ); - let mut debug_suffix = ""; - let libname = if target.contains("windows") && target.contains("msvc") { - if env::var("OPT_LEVEL").unwrap() == "0" { - debug_suffix = "d"; - } - "zlibstatic" - } else { - "z" - }; - println!( - "cargo:rustc-link-lib=static={}{}{}", - libname, - if compat { "" } else { "-ng" }, - debug_suffix, - ); - println!("cargo:root={}", install_dir.to_str().unwrap()); - println!("cargo:include={}", includedir.to_str().unwrap()); - if !compat { - println!("cargo:rustc-cfg=zng"); - } -} - -#[allow(dead_code)] -fn main() { - let target = env::var("TARGET").unwrap(); - build_zlib_ng(&target, false); -} -- 2.43.0