diff --git a/build.rs b/build.rs index d6eb499..2dcfe45 100644 --- a/build.rs +++ b/build.rs @@ -2,6 +2,64 @@ use std::env; use std::fs; use std::path::{Path, PathBuf}; +const SOURCES: &[&str] = &[ + "nghttp2/lib/sfparse.c", + "nghttp2/lib/nghttp2_alpn.c", + "nghttp2/lib/nghttp2_buf.c", + "nghttp2/lib/nghttp2_callbacks.c", + "nghttp2/lib/nghttp2_debug.c", + "nghttp2/lib/nghttp2_extpri.c", + "nghttp2/lib/nghttp2_frame.c", + "nghttp2/lib/nghttp2_hd.c", + "nghttp2/lib/nghttp2_hd_huffman.c", + "nghttp2/lib/nghttp2_hd_huffman_data.c", + "nghttp2/lib/nghttp2_helper.c", + "nghttp2/lib/nghttp2_http.c", + "nghttp2/lib/nghttp2_map.c", + "nghttp2/lib/nghttp2_mem.c", + "nghttp2/lib/nghttp2_option.c", + "nghttp2/lib/nghttp2_outbound_item.c", + "nghttp2/lib/nghttp2_pq.c", + "nghttp2/lib/nghttp2_priority_spec.c", + "nghttp2/lib/nghttp2_queue.c", + "nghttp2/lib/nghttp2_rcbuf.c", + "nghttp2/lib/nghttp2_session.c", + "nghttp2/lib/nghttp2_stream.c", + "nghttp2/lib/nghttp2_submit.c", + "nghttp2/lib/nghttp2_version.c", + "nghttp2/lib/nghttp2_ratelim.c", + "nghttp2/lib/nghttp2_time.c", +]; + +const HEADERS: &[&str] = &[ + "nghttp2/lib/sfparse.h", + "nghttp2/lib/nghttp2_alpn.h", + "nghttp2/lib/nghttp2_buf.h", + "nghttp2/lib/nghttp2_callbacks.h", + "nghttp2/lib/nghttp2_debug.h", + "nghttp2/lib/nghttp2_extpri.h", + "nghttp2/lib/nghttp2_frame.h", + "nghttp2/lib/nghttp2_hd.h", + "nghttp2/lib/nghttp2_hd_huffman.h", + "nghttp2/lib/nghttp2_helper.h", + "nghttp2/lib/nghttp2_http.h", + "nghttp2/lib/nghttp2_int.h", + "nghttp2/lib/nghttp2_map.h", + "nghttp2/lib/nghttp2_mem.h", + "nghttp2/lib/nghttp2_net.h", + "nghttp2/lib/nghttp2_option.h", + "nghttp2/lib/nghttp2_outbound_item.h", + "nghttp2/lib/nghttp2_pq.h", + "nghttp2/lib/nghttp2_priority_spec.h", + "nghttp2/lib/nghttp2_queue.h", + "nghttp2/lib/nghttp2_ratelim.h", + "nghttp2/lib/nghttp2_rcbuf.h", + "nghttp2/lib/nghttp2_session.h", + "nghttp2/lib/nghttp2_stream.h", + "nghttp2/lib/nghttp2_submit.h", + "nghttp2/lib/nghttp2_time.h", +]; + fn main() { let out_dir = PathBuf::from(env::var_os("OUT_DIR").expect("OUT_DIR not set")); let target = env::var("TARGET").expect("TARGET not set"); @@ -22,6 +80,33 @@ fn main() { generate_bindings(&out_dir, &include_dir); println!("cargo:root={}", install_dir.display()); + + // Emit rerun-if-changed directives to avoid unnecessary rebuilds + emit_rerun_if_changed(); +} + +fn emit_rerun_if_changed() { + // Build script itself + println!("cargo:rerun-if-changed=build.rs"); + + // Template files + println!( + "cargo:rerun-if-changed=nghttp2/lib/includes/nghttp2/nghttp2ver.h.in" + ); + println!("cargo:rerun-if-changed=nghttp2/lib/libnghttp2.pc.in"); + + // Header files (public) + println!("cargo:rerun-if-changed=nghttp2/lib/includes/nghttp2/nghttp2.h"); + + // Source files + for source in SOURCES { + println!("cargo:rerun-if-changed={}", source); + } + + // Header dependencies (internal) + for header in HEADERS { + println!("cargo:rerun-if-changed={}", header); + } } struct NgHttp2Version { @@ -106,35 +191,6 @@ fn build_nghttp2(target: &str, include_dir: &Path, lib_dir: &Path) { } fn add_source_files(build: &mut cc::Build) { - const SOURCES: &[&str] = &[ - "nghttp2/lib/sfparse.c", - "nghttp2/lib/nghttp2_alpn.c", - "nghttp2/lib/nghttp2_buf.c", - "nghttp2/lib/nghttp2_callbacks.c", - "nghttp2/lib/nghttp2_debug.c", - "nghttp2/lib/nghttp2_extpri.c", - "nghttp2/lib/nghttp2_frame.c", - "nghttp2/lib/nghttp2_hd.c", - "nghttp2/lib/nghttp2_hd_huffman.c", - "nghttp2/lib/nghttp2_hd_huffman_data.c", - "nghttp2/lib/nghttp2_helper.c", - "nghttp2/lib/nghttp2_http.c", - "nghttp2/lib/nghttp2_map.c", - "nghttp2/lib/nghttp2_mem.c", - "nghttp2/lib/nghttp2_option.c", - "nghttp2/lib/nghttp2_outbound_item.c", - "nghttp2/lib/nghttp2_pq.c", - "nghttp2/lib/nghttp2_priority_spec.c", - "nghttp2/lib/nghttp2_queue.c", - "nghttp2/lib/nghttp2_rcbuf.c", - "nghttp2/lib/nghttp2_session.c", - "nghttp2/lib/nghttp2_stream.c", - "nghttp2/lib/nghttp2_submit.c", - "nghttp2/lib/nghttp2_version.c", - "nghttp2/lib/nghttp2_ratelim.c", - "nghttp2/lib/nghttp2_time.c", - ]; - for source in SOURCES { build.file(source); } @@ -201,6 +257,10 @@ fn generate_bindings(out_dir: &Path, include_dir: &Path) { builder = builder.clang_arg(format!("-D{}", ssize_t_def)); } + // Note: We don't use CargoCallbacks here because it would emit + // rerun-if-changed for generated headers in OUT_DIR (whose path changes + // between builds) and system headers. We manually emit rerun-if-changed + // for the source files in emit_rerun_if_changed() instead. let bindings = builder // Only include nghttp2 symbols .allowlist_function("nghttp2_.*") @@ -220,7 +280,6 @@ fn generate_bindings(out_dir: &Path, include_dir: &Path) { .blocklist_function(".*vprintf.*") .blocklist_type(".*va_list.*") .blocklist_type("nghttp2_debug_vprintf_callback") - .parse_callbacks(Box::new(bindgen::CargoCallbacks::new())) .generate() .expect("Failed to generate bindings");