From 59fc33ed2b681282aa4843a00dfcdb3dbfc074e9 Mon Sep 17 00:00:00 2001 From: Stefan Sommerfeld Date: Mon, 1 Sep 2025 10:44:09 +0200 Subject: [PATCH 1/3] check if libxml2 includes are in a libxml2 subdirectory --- build.rs | 61 ++++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 39 insertions(+), 22 deletions(-) diff --git a/build.rs b/build.rs index d8d2fef82..ea7f6a365 100644 --- a/build.rs +++ b/build.rs @@ -1,4 +1,7 @@ -use std::{env, fs, path::{Path, PathBuf}}; +use std::{ + env, fs, + path::{Path, PathBuf}, +}; struct ProbedLib { version: String, @@ -40,7 +43,11 @@ fn find_libxml2() -> Option { ); None } else { - #[cfg(any(target_family = "unix", target_os = "macos", all(target_family="windows", target_env="gnu")))] + #[cfg(any( + target_family = "unix", + target_os = "macos", + all(target_family = "windows", target_env = "gnu") + ))] { let lib = pkg_config::Config::new() .probe("libxml-2.0") @@ -48,12 +55,12 @@ fn find_libxml2() -> Option { return Some(ProbedLib { include_paths: lib.include_paths, version: lib.version, - }) + }); } #[cfg(all(target_family = "windows", target_env = "msvc"))] { - if let Some(meta) = vcpkg_dep::vcpkg_find_libxml2() { + if let Some(meta) = vcpkg_dep::vcpkg_find_libxml2() { return Some(meta); } else { eprintln!("vcpkg did not succeed in finding libxml2."); @@ -71,11 +78,12 @@ fn generate_bindings(header_dirs: Vec, output_path: &Path) { // invalidate build as soon as the wrapper changes .parse_callbacks(Box::new(bindgen::CargoCallbacks::new())) .layout_tests(true) - .clang_args(&["-DPKG-CONFIG", "-DLIBXML_C14N_ENABLED", "-DLIBXML_OUTPUT_ENABLED"]) - .clang_args( - header_dirs.iter() - .map(|dir| format!("-I{}", dir.display())) - ); + .clang_args(&[ + "-DPKG-CONFIG", + "-DLIBXML_C14N_ENABLED", + "-DLIBXML_OUTPUT_ENABLED", + ]) + .clang_args(header_dirs.iter().map(|dir| format!("-I{}", dir.display()))); bindings .generate() .expect("failed to generate bindings with bindgen") @@ -92,10 +100,13 @@ fn main() { // if we could find header files, generate fresh bindings from them generate_bindings(probed_lib.include_paths, &bindings_path); // and expose the libxml2 version to the code - let version_parts: Vec = probed_lib.version.split('.') - .map(|part| part.parse::().unwrap_or(-1)).collect(); - let older_than_2_12 = version_parts.len() > 1 && (version_parts[0] < 2 || - version_parts[0] == 2 && version_parts[1] < 12); + let version_parts: Vec = probed_lib + .version + .split('.') + .map(|part| part.parse::().unwrap_or(-1)) + .collect(); + let older_than_2_12 = version_parts.len() > 1 + && (version_parts[0] < 2 || version_parts[0] == 2 && version_parts[1] < 12); println!("cargo::rustc-check-cfg=cfg(libxml_older_than_2_12)"); if older_than_2_12 { println!("cargo::rustc-cfg=libxml_older_than_2_12"); @@ -113,12 +124,19 @@ fn main() { mod vcpkg_dep { use crate::ProbedLib; pub fn vcpkg_find_libxml2() -> Option { - if let Ok(metadata) = vcpkg::Config::new() - .find_package("libxml2") { - Some(ProbedLib { version: vcpkg_version(), include_paths: metadata.include_paths }) - } else { - None + if let Ok(mut metadata) = vcpkg::Config::new().find_package("libxml2") { + if let Some(mut include_path) = metadata.include_paths.pop() { + if include_path.join("libxml2").exists() { + // libxml2 >= 2.14.5 is in a 'libxml2' subdirectory + include_path = include_path.join("libxml2"); + } + return Some(ProbedLib { + version: vcpkg_version(), + include_paths: vec![include_path], + }); + } } + None } fn vcpkg_version() -> String { @@ -127,7 +145,7 @@ mod vcpkg_dep { let mut vcpkg_exe = vcpkg::find_vcpkg_root(&vcpkg::Config::new()).unwrap(); vcpkg_exe.push("vcpkg.exe"); let vcpkg_list_libxml2 = std::process::Command::new(vcpkg_exe) - .args(["list","libxml2"]) + .args(["list", "libxml2"]) .output() .expect("vcpkg.exe failed to execute in vcpkg_dep build step"); if vcpkg_list_libxml2.status.success() { @@ -137,9 +155,8 @@ mod vcpkg_dep { let mut version_piece = line.split("2."); version_piece.next(); if let Some(version_tail) = version_piece.next() { - if let Some(version) = version_tail.split(' ').next() - .unwrap().split('#').next() { - return format!("2.{version}"); + if let Some(version) = version_tail.split(' ').next().unwrap().split('#').next() { + return format!("2.{version}"); } } } From 47b8f0e7fb7c126f8ca75273afcb5b935c736557 Mon Sep 17 00:00:00 2001 From: Stefan Sommerfeld Date: Mon, 1 Sep 2025 10:50:04 +0200 Subject: [PATCH 2/3] bump revision --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 50a9f4fc4..f3f3ed9bd 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "libxml" -version = "0.3.7" +version = "0.3.8" edition = "2024" authors = ["Andreas Franzén ", "Deyan Ginev ","Jan Frederik Schaefer "] description = "A Rust wrapper for libxml2 - the XML C parser and toolkit developed for the Gnome project" From 01442241fa7542b7f964167855e2de3756b29700 Mon Sep 17 00:00:00 2001 From: Stefan Sommerfeld Date: Tue, 2 Sep 2025 15:36:32 +0200 Subject: [PATCH 3/3] always add libxml2 subdirectory to the include path, because this seems to be standard --- build.rs | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/build.rs b/build.rs index ea7f6a365..852047ad4 100644 --- a/build.rs +++ b/build.rs @@ -124,17 +124,19 @@ fn main() { mod vcpkg_dep { use crate::ProbedLib; pub fn vcpkg_find_libxml2() -> Option { - if let Ok(mut metadata) = vcpkg::Config::new().find_package("libxml2") { - if let Some(mut include_path) = metadata.include_paths.pop() { - if include_path.join("libxml2").exists() { - // libxml2 >= 2.14.5 is in a 'libxml2' subdirectory - include_path = include_path.join("libxml2"); - } - return Some(ProbedLib { - version: vcpkg_version(), - include_paths: vec![include_path], + if let Ok(metadata) = vcpkg::Config::new().find_package("libxml2") { + let include_paths = metadata + .include_paths + .into_iter() + .fold(Vec::new(), |mut acc, p| { + acc.push(p.join("libxml2")); + acc.push(p); + acc }); - } + return Some(ProbedLib { + version: vcpkg_version(), + include_paths, + }); } None }