From 2c15028ee9300f5082ee35020fe9c879b1fdbedf Mon Sep 17 00:00:00 2001 From: Steven Sloboda Date: Mon, 28 Dec 2020 12:51:59 -0500 Subject: [PATCH] grpc-sys: Use grpc headers found by pkgconfig. Previously the bundled grpc headers were always used to generate bindings even in the case where pkgconfig was used to locate gRPC to link against. This caused errors at runtime, e.g., SEGFAULT, rather than a compile-time error. To fix this, use the headers found by pkgconfig to generate bindings rather than than the bundled headers if pkgconfig is already being used. Signed-off-by: Steven Sloboda --- grpc-sys/build.rs | 31 ++++++++++++++++++++++--------- 1 file changed, 22 insertions(+), 9 deletions(-) diff --git a/grpc-sys/build.rs b/grpc-sys/build.rs index 5561e5e9a..eeca24797 100644 --- a/grpc-sys/build.rs +++ b/grpc-sys/build.rs @@ -268,7 +268,7 @@ fn get_env(name: &str) -> Option { // Generate the bindings to grpc C-core. // Try to disable the generation of platform-related bindings. #[cfg(feature = "use-bindgen")] -fn bindgen_grpc(file_path: &PathBuf) { +fn bindgen_grpc(file_path: &PathBuf, grpc_include_dir: &PathBuf) { // create a config to generate binding file let mut config = bindgen::Builder::default(); if cfg!(feature = "secure") { @@ -281,7 +281,7 @@ fn bindgen_grpc(file_path: &PathBuf) { // Search header files with API interface let mut headers = Vec::new(); - for result in WalkDir::new(Path::new("./grpc/include")) { + for result in WalkDir::new(grpc_include_dir) { let dent = result.expect("Error happened when search headers"); if !dent.file_type().is_file() { continue; @@ -307,7 +307,7 @@ fn bindgen_grpc(file_path: &PathBuf) { let cfg = config .header("grpc_wrap.cc") .clang_arg("-xc++") - .clang_arg("-I./grpc/include") + .clang_arg(format!("-I{}", grpc_include_dir.display())) .clang_arg("-std=c++11") .rustfmt_bindings(true) .impl_debug(true) @@ -344,7 +344,7 @@ fn bindgen_grpc(file_path: &PathBuf) { // Determine if need to update bindings. Supported platforms do not // need to be updated by default unless the UPDATE_BIND is specified. // Other platforms use bindgen to generate the bindings every time. -fn config_binding_path() { +fn config_binding_path(#[allow(unused_variables)] grpc_include_dir: &PathBuf) { let target = env::var("TARGET").unwrap(); let file_path: PathBuf = match target.as_str() { "x86_64-unknown-linux-gnu" | "aarch64-unknown-linux-gnu" => { @@ -359,7 +359,7 @@ fn config_binding_path() { #[cfg(feature = "use-bindgen")] if env::var("UPDATE_BIND").is_ok() { - bindgen_grpc(&file_path); + bindgen_grpc(&file_path, grpc_include_dir); } file_path @@ -368,7 +368,7 @@ fn config_binding_path() { let file_path = PathBuf::from(env::var("OUT_DIR").unwrap()).join("grpc-bindings.rs"); #[cfg(feature = "use-bindgen")] - bindgen_grpc(&file_path); + bindgen_grpc(&file_path, grpc_include_dir); file_path } @@ -400,15 +400,28 @@ fn main() { cc.define("_WIN32_WINNT", Some("0x600")); } - if get_env("GRPCIO_SYS_USE_PKG_CONFIG").map_or(false, |s| s == "1") { + let grpc_include_dir = if get_env("GRPCIO_SYS_USE_PKG_CONFIG").map_or(false, |s| s == "1") { // Print cargo metadata. let lib_core = probe_library(library, true); + let grpc_include_dir = lib_core + .include_paths + .iter() + .map(|inc_path| inc_path.join("grpc")) + .find(|grpc_inc_path| grpc_inc_path.is_dir()) + .unwrap_or_else(|| { + panic!( + "Could not find grpc include dir in {:#?}", + lib_core.include_paths + ) + }); for inc_path in lib_core.include_paths { cc.include(inc_path); } + grpc_include_dir } else { build_grpc(&mut cc, library); - } + "./grpc/include".into() + }; cc.cpp(true); if !cfg!(target_env = "msvc") { @@ -418,5 +431,5 @@ fn main() { cc.warnings_into_errors(true); cc.compile("libgrpc_wrap.a"); - config_binding_path(); + config_binding_path(&grpc_include_dir); }