From 1fdb611a3e8e302666386e94b4e8fa877296d33f Mon Sep 17 00:00:00 2001 From: ginnyTheCat Date: Tue, 3 Jun 2025 18:14:59 +0200 Subject: [PATCH 1/4] Remove bindings to private or c std types --- mupdf-sys/build.rs | 78 ++++++++++++++++++++++++++++++++------------ mupdf-sys/make.rs | 5 +++ mupdf-sys/src/lib.rs | 1 + 3 files changed, 63 insertions(+), 21 deletions(-) diff --git a/mupdf-sys/build.rs b/mupdf-sys/build.rs index 6be99fc..656f0ab 100644 --- a/mupdf-sys/build.rs +++ b/mupdf-sys/build.rs @@ -44,26 +44,29 @@ fn run() -> Result<()> { let out_dir = PathBuf::from(env::var_os("OUT_DIR").ok_or("Missing OUT_DIR environment variable")?); - let build_dir = out_dir.join("build"); - let build_dir = build_dir.to_str().ok_or_else(|| { - format!("Build dir path is required to be valid UTF-8, got {build_dir:?}") - })?; + let sysroot = find_clang_sysroot(&target)?; - if let Err(e) = remove_dir_all(build_dir) { - if e.kind() != ErrorKind::NotFound { - println!("cargo:warning=Unable to clear {build_dir:?}. This may lead to flaky builds that might not incorporate configurations changes: {e}"); - } - } + let docs = env::var("DOCS_RS").is_ok(); + if !docs { + let build_dir = out_dir.join("build"); + let build_dir = build_dir.to_str().ok_or_else(|| { + format!("Build dir path is required to be valid UTF-8, got {build_dir:?}") + })?; - let sysroot = find_clang_sysroot(&target)?; + if let Err(e) = remove_dir_all(build_dir) { + if e.kind() != ErrorKind::NotFound { + println!("cargo:warning=Unable to clear {build_dir:?}. This may lead to flaky builds that might not incorporate configurations changes: {e}"); + } + } - copy_recursive(&src_dir, build_dir.as_ref(), &[".git".as_ref()])?; + copy_recursive(&src_dir, build_dir.as_ref(), &[".git".as_ref()])?; - println!("cargo:rerun-if-changed=wrapper.h"); - println!("cargo:rerun-if-changed=wrapper.c"); + println!("cargo:rerun-if-changed=wrapper.h"); + println!("cargo:rerun-if-changed=wrapper.c"); - Build::new(&target).run(&target, build_dir)?; - build_wrapper(&target).map_err(|e| format!("Unable to compile mupdf wrapper:\n {e}"))?; + Build::new(&target).run(&target, build_dir)?; + build_wrapper(&target).map_err(|e| format!("Unable to compile mupdf wrapper:\n {e}"))?; + } generate_bindings(&target, &out_dir.join("bindings.rs"), sysroot) .map_err(|e| format!("Unable to generate mupdf bindings using bindgen:\n {e}"))?; @@ -165,15 +168,51 @@ fn generate_bindings(target: &Target, path: &Path, sysroot: Option) -> R builder = builder .clang_arg("-Imupdf/include") .header("wrapper.h") - .header("wrapper.c") + .header("wrapper.c"); + + builder = builder + .allowlist_recursively(false) + .allowlist_type("__va_list_tag") + .allowlist_type("wchar_t") + .allowlist_type("FILE") + .opaque_type("FILE"); + + builder = builder .allowlist_item("fz_.*") .allowlist_item("FZ_.*") .allowlist_item("pdf_.*") .allowlist_item("PDF_.*") + .allowlist_type("cmap_splay") .allowlist_item("ucdn_.*") .allowlist_item("UCDN_.*") .allowlist_item("Memento_.*") - .allowlist_item("mupdf_.*") + .allowlist_item("mupdf_.*"); + + // build config + builder = builder + .blocklist_var("FZ_VERSION.*") + .blocklist_var("FZ_ENABLE_.*") + .blocklist_var("FZ_PLOTTERS_.*"); + + // internal implementation details, considered private + builder = builder + .blocklist_item("fz_jmp_buf") + .blocklist_function("fz_var_imp") + .blocklist_function("fz_push_try") + .blocklist_function("fz_do_.*") + .blocklist_var("FZ_JMPBUF_ALIGN") + .blocklist_type("fz_error_stack_slot") + .blocklist_type("fz_error_context") + .blocklist_type("fz_warn_context") + .blocklist_type("fz_aa_context") + .blocklist_type("fz_activity_.*") + .blocklist_function("fz_register_activity_logger") + .opaque_type("fz_context") + .blocklist_type("fz_new_context_imp") + .blocklist_type("fz_lock") + .blocklist_type("fz_unlock"); + + builder = builder .parse_callbacks(Box::new(bindgen::CargoCallbacks::new())) .parse_callbacks(Box::new(DocsCallbacks::default())); @@ -182,10 +221,7 @@ fn generate_bindings(target: &Target, path: &Path, sysroot: Option) -> R builder = builder.parse_callbacks(Box::new(ZerocopyDeriveCallbacks)); } - builder - .size_t_is_usize(true) - .generate()? - .write_to_file(path)?; + builder.use_core().generate()?.write_to_file(path)?; Ok(()) } diff --git a/mupdf-sys/make.rs b/mupdf-sys/make.rs index c5e3912..21ef738 100644 --- a/mupdf-sys/make.rs +++ b/mupdf-sys/make.rs @@ -201,6 +201,11 @@ impl Make { self.make_bool("verbose", true); + // harfbuzz sometimes requires this + if target.os == "windows" { + self.build.flag("-Wa,-mbig-obj"); + } + self.libs()?; self.cpus(target); diff --git a/mupdf-sys/src/lib.rs b/mupdf-sys/src/lib.rs index d64e578..9ebe3f6 100644 --- a/mupdf-sys/src/lib.rs +++ b/mupdf-sys/src/lib.rs @@ -1,3 +1,4 @@ +#![no_std] #![allow(non_upper_case_globals)] #![allow(non_camel_case_types)] #![allow(non_snake_case)] From a63541e7e24e550e6d6390155cb3d148be8efbcb Mon Sep 17 00:00:00 2001 From: ginnyTheCat Date: Tue, 3 Jun 2025 21:57:43 +0200 Subject: [PATCH 2/4] Add va_list to allowlist --- mupdf-sys/build.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/mupdf-sys/build.rs b/mupdf-sys/build.rs index 656f0ab..8133011 100644 --- a/mupdf-sys/build.rs +++ b/mupdf-sys/build.rs @@ -172,6 +172,7 @@ fn generate_bindings(target: &Target, path: &Path, sysroot: Option) -> R builder = builder .allowlist_recursively(false) + .allowlist_type("va_list") .allowlist_type("__va_list_tag") .allowlist_type("wchar_t") .allowlist_type("FILE") From e12f9147e85d89e4107e8a2fd8d50c817621f864 Mon Sep 17 00:00:00 2001 From: ginnyTheCat Date: Wed, 4 Jun 2025 01:12:24 +0200 Subject: [PATCH 3/4] Remove functions using va_list --- mupdf-sys/build.rs | 13 +++++++++++-- mupdf-sys/wrapper.c | 7 +++++++ 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/mupdf-sys/build.rs b/mupdf-sys/build.rs index 8133011..16f3f5c 100644 --- a/mupdf-sys/build.rs +++ b/mupdf-sys/build.rs @@ -172,8 +172,6 @@ fn generate_bindings(target: &Target, path: &Path, sysroot: Option) -> R builder = builder .allowlist_recursively(false) - .allowlist_type("va_list") - .allowlist_type("__va_list_tag") .allowlist_type("wchar_t") .allowlist_type("FILE") .opaque_type("FILE"); @@ -189,6 +187,17 @@ fn generate_bindings(target: &Target, path: &Path, sysroot: Option) -> R .allowlist_item("Memento_.*") .allowlist_item("mupdf_.*"); + // remove va_list functions as for all of these versions using ... exist + builder = builder + .blocklist_function("Memento_vasprintf") // Memento_asprintf + .blocklist_function("fz_vthrow") // fz_throw + .blocklist_function("fz_vwarn") // fz_warn + .blocklist_function("fz_vlog_error_printf") // fz_log_error_printf + .blocklist_function("fz_append_vprintf") // fz_append_printf + .blocklist_function("fz_write_vprintf") // fz_write_printf + .blocklist_function("fz_vsnprintf") // fz_snprintf + .blocklist_function("fz_format_string"); // mupdf_format_string + // build config builder = builder .blocklist_var("FZ_VERSION.*") diff --git a/mupdf-sys/wrapper.c b/mupdf-sys/wrapper.c index 8035090..997f2fa 100644 --- a/mupdf-sys/wrapper.c +++ b/mupdf-sys/wrapper.c @@ -3273,3 +3273,10 @@ int32_t mupdf_search_stext_page_cb(fz_context *ctx, fz_stext_page *page, const c } return count; } + +void mupdf_format_string(fz_context *ctx, void *user, void (*emit)(fz_context *ctx, void *user, int c), const char *fmt, ...) { + va_list ap; + va_start(ap, fmt); + fz_format_string(ctx, user, emit, fmt, ap); + va_end(ap); +} From fe700fb70d581d719831ef44909f9024ffc29eba Mon Sep 17 00:00:00 2001 From: ginnyTheCat Date: Wed, 4 Jun 2025 01:19:22 +0200 Subject: [PATCH 4/4] Use var_os in docs.rs check --- mupdf-sys/build.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mupdf-sys/build.rs b/mupdf-sys/build.rs index 16f3f5c..6e48017 100644 --- a/mupdf-sys/build.rs +++ b/mupdf-sys/build.rs @@ -46,7 +46,7 @@ fn run() -> Result<()> { let sysroot = find_clang_sysroot(&target)?; - let docs = env::var("DOCS_RS").is_ok(); + let docs = env::var_os("DOCS_RS").is_some(); if !docs { let build_dir = out_dir.join("build"); let build_dir = build_dir.to_str().ok_or_else(|| {