*: use libz-sys instead of bundled one (#419)

* *: use libz-sys instead of bundled one

When using the built-in cmake to build zlib, it changes the source tree
as madler/zlib#162 describes. This leads to the failure during
[generating the docs][1]. So let's switch to libz-sys instead, which
uses its own custom script to build zlib, and leave source tree as it
is. Switching to libz-sys can also reduce the package size as we can
ignore more sub modules. It should improve compile time if libz-sys is
also a dependency of other crates.

The only shortcoming is that libz-sys may not be compatible with
grpcio, but I believe the chance is quite small given it's such a small
library. And giving it's such a small library, the benifits like compile
time or package size described above may be too small to be observed.

[1]: https://docs.rs/crate/grpcio/0.5.0-alpha.5/builds/196235.

Signed-off-by: Jay Lee <busyjaylee@gmail.com>
diff --git a/grpc-sys/Cargo.toml b/grpc-sys/Cargo.toml
index 6d8551e..86f5949 100644
--- a/grpc-sys/Cargo.toml
+++ b/grpc-sys/Cargo.toml
@@ -26,6 +26,7 @@
     "grpc/src/ruby/*",
     "grpc/vsprojects/*",
     "grpc/test/core/end2end/*",
+    "grpc/third_party/zlib/*",
     "grpc/third_party/abseil-cpp/*",
     "grpc/third_party/benchmark/*",
     "grpc/third_party/bloaty/*",
@@ -48,6 +49,7 @@
 [dependencies]
 libc = "0.2"
 openssl-sys = { version = "0.9", optional = true, features = ["vendored"] }
+libz-sys = { version = "1.0.25", features = ["static"] }
 
 [features]
 default = []
diff --git a/grpc-sys/build.rs b/grpc-sys/build.rs
index d651e46..c0e1ab4 100644
--- a/grpc-sys/build.rs
+++ b/grpc-sys/build.rs
@@ -41,7 +41,6 @@
 fn prepare_grpc() {
     let mut modules = vec![
         "grpc",
-        "grpc/third_party/zlib",
         "grpc/third_party/cares/cares",
         "grpc/third_party/address_sorting",
     ];
@@ -77,7 +76,7 @@
 fn build_grpc(cc: &mut Build, library: &str) {
     prepare_grpc();
 
-    let mut third_party = vec!["cares/cares/lib", "zlib"];
+    let mut third_party = vec!["cares/cares/lib"];
 
     let dst = {
         let mut config = Config::new("grpc");
@@ -151,21 +150,16 @@
         } else if cfg!(feature = "secure") {
             third_party.extend_from_slice(&["boringssl/ssl", "boringssl/crypto"]);
         }
+        // Uses zlib from libz-sys.
+        setup_libz(&mut config);
         config.build_target(library).uses_cxx11().build()
     };
 
-    let mut zlib = "z";
     let build_dir = format!("{}/build", dst.display());
     if get_env("CARGO_CFG_TARGET_OS").map_or(false, |s| s == "windows") {
         let profile = match &*env::var("PROFILE").unwrap_or("debug".to_owned()) {
-            "bench" | "release" => {
-                zlib = "zlibstatic";
-                "Release"
-            }
-            _ => {
-                zlib = "zlibstaticd";
-                "Debug"
-            }
+            "bench" | "release" => "Release",
+            _ => "Debug",
         };
         println!("cargo:rustc-link-search=native={}/{}", build_dir, profile);
         for path in third_party {
@@ -184,7 +178,7 @@
         }
     }
 
-    println!("cargo:rustc-link-lib=static={}", zlib);
+    println!("cargo:rustc-link-lib=static=z");
     println!("cargo:rustc-link-lib=static=cares");
     println!("cargo:rustc-link-lib=static=gpr");
     println!("cargo:rustc-link-lib=static=address_sorting");
@@ -231,6 +225,23 @@
     println!("cargo:rustc-link-lib=crypto");
 }
 
+fn setup_libz(config: &mut Config) {
+    config.define("gRPC_ZLIB_PROVIDER", "package");
+    config.register_dep("Z");
+    // cmake script expect libz.a being under ${DEP_Z_ROOT}/lib, but libz-sys crate put it
+    // under ${DEP_Z_ROOT}/build. Append the path to CMAKE_PREFIX_PATH to get around it.
+    let zlib_root = env::var("DEP_Z_ROOT").unwrap();
+    let prefix_path = if let Ok(prefix_path) = env::var("CMAKE_PREFIX_PATH") {
+        format!("{};{}/build", prefix_path, zlib_root)
+    } else {
+        format!("{}/build", zlib_root)
+    };
+    // To avoid linking system library, set lib path explicitly.
+    println!("cargo:rustc-link-search=native={}/build", zlib_root);
+    println!("cargo:rustc-link-search=native={}/lib", zlib_root);
+    env::set_var("CMAKE_PREFIX_PATH", prefix_path);
+}
+
 #[cfg(feature = "openssl-vendored")]
 fn setup_openssl(config: &mut Config) {
     // openssl-sys uses openssl-src to build the library. openssl-src uses
diff --git a/scripts/reset-submodule b/scripts/reset-submodule
index 0f778a1..0fa7738 100755
--- a/scripts/reset-submodule
+++ b/scripts/reset-submodule
@@ -3,7 +3,6 @@
 cd grpc-sys/grpc
 git submodule update --init third_party/boringssl
 git submodule update --init third_party/cares/cares
-git submodule update --init third_party/zlib
 cd third_party/zlib
 git clean -f
 git reset --hard
diff --git a/src/async/executor.rs b/src/async/executor.rs
index b1ae5e8..8f4ea2e 100644
--- a/src/async/executor.rs
+++ b/src/async/executor.rs
@@ -117,7 +117,7 @@
     pub fn resolve(self, success: bool) {
         // it should always be canceled for now.
         assert!(success);
-        poll(&Arc::new(self.clone()), true);
+        poll(&Arc::new(self), true);
     }
 }