|
1 | 1 | //! |
2 | 2 | //! XmlSec Bindings Generation |
3 | 3 | //! |
4 | | -use bindgen::Builder as BindgenBuilder; |
| 4 | +use bindgen::Builder as BindgenBuilder; |
5 | 5 | use bindgen::Formatter as BindgenFormatter; |
6 | 6 |
|
7 | | -use pkg_config::Config as PkgConfig; |
8 | | - |
| 7 | +use std::collections::HashMap; |
9 | 8 | use std::env; |
10 | 9 | use std::path::PathBuf; |
11 | | -use std::process::Command; |
12 | | - |
13 | 10 |
|
14 | 11 | const BINDINGS: &str = "bindings.rs"; |
15 | 12 |
|
| 13 | +fn main() { |
| 14 | + let dependencies = locate_and_link_dependencies(); |
16 | 15 |
|
17 | | -fn main() |
18 | | -{ |
19 | | - println!("cargo:rustc-link-lib=xmlsec1-openssl"); // -lxmlsec1-openssl |
20 | | - println!("cargo:rustc-link-lib=xmlsec1"); // -lxmlsec1 |
21 | | - println!("cargo:rustc-link-lib=xml2"); // -lxml2 |
22 | | - println!("cargo:rustc-link-lib=ssl"); // -lssl |
23 | | - println!("cargo:rustc-link-lib=crypto"); // -lcrypto |
24 | | - |
25 | | - let path_out = PathBuf::from(env::var("OUT_DIR").unwrap()); |
| 16 | + let path_out = PathBuf::from(env::var("OUT_DIR").unwrap()); |
26 | 17 | let path_bindings = path_out.join(BINDINGS); |
27 | 18 |
|
28 | | - if !path_bindings.exists() |
29 | | - { |
30 | | - PkgConfig::new() |
31 | | - .probe("xmlsec1") |
32 | | - .expect("Could not find xmlsec1 using pkg-config"); |
33 | | - |
| 19 | + if !path_bindings.exists() { |
34 | 20 | let bindbuild = BindgenBuilder::default() |
35 | 21 | .header("bindings.h") |
36 | | - .clang_args(fetch_xmlsec_config_flags()) |
37 | | - .clang_args(fetch_xmlsec_config_libs()) |
| 22 | + .allowlist_type("xml.*") |
| 23 | + .allowlist_function("xml.*") |
| 24 | + .allowlist_var("xml.*") |
| 25 | + .clang_args(dependencies.clang_args()) |
38 | 26 | .layout_tests(true) |
39 | 27 | .formatter(BindgenFormatter::default()) |
40 | 28 | .generate_comments(true); |
41 | 29 |
|
42 | | - let bindings = bindbuild.generate() |
43 | | - .expect("Unable to generate bindings"); |
| 30 | + let bindings = bindbuild.generate().expect("Unable to generate bindings"); |
44 | 31 |
|
45 | | - bindings.write_to_file(path_bindings) |
| 32 | + bindings |
| 33 | + .write_to_file(path_bindings) |
46 | 34 | .expect("Couldn't write bindings!"); |
47 | 35 | } |
48 | 36 | } |
49 | 37 |
|
50 | | - |
51 | | -fn fetch_xmlsec_config_flags() -> Vec<String> |
52 | | -{ |
53 | | - let out = Command::new("xmlsec1-config") |
54 | | - .arg("--cflags") |
55 | | - .output() |
56 | | - .expect("Failed to get --cflags from xmlsec1-config. Is xmlsec1 installed?") |
57 | | - .stdout; |
58 | | - |
59 | | - args_from_output(out) |
| 38 | +struct LocatedDependencies { |
| 39 | + include_paths: Vec<PathBuf>, |
| 40 | + defines: HashMap<String, Option<String>>, |
60 | 41 | } |
61 | 42 |
|
62 | | - |
63 | | -fn fetch_xmlsec_config_libs() -> Vec<String> |
64 | | -{ |
65 | | - let out = Command::new("xmlsec1-config") |
66 | | - .arg("--libs") |
67 | | - .output() |
68 | | - .expect("Failed to get --libs from xmlsec1-config. Is xmlsec1 installed?") |
69 | | - .stdout; |
70 | | - |
71 | | - args_from_output(out) |
| 43 | +impl LocatedDependencies { |
| 44 | + fn clang_args(&self) -> Vec<String> { |
| 45 | + let mut result = Vec::new(); |
| 46 | + for include_path in &self.include_paths { |
| 47 | + result.push(format!("-I{}", include_path.display())); |
| 48 | + } |
| 49 | + for (define, value) in &self.defines { |
| 50 | + match value { |
| 51 | + Some(value) => result.push(format!("-D{}={}", define, value)), |
| 52 | + None => result.push(format!("-D{}", define)), |
| 53 | + } |
| 54 | + } |
| 55 | + result |
| 56 | + } |
72 | 57 | } |
73 | 58 |
|
| 59 | +#[cfg(not(windows))] |
| 60 | +fn locate_and_link_dependencies() -> LocatedDependencies { |
| 61 | + let library = |
| 62 | + pkg_config::probe_library("xmlsec1").expect("Could not find xmlsec1 using pkg-config"); |
74 | 63 |
|
75 | | -fn args_from_output(args: Vec<u8>) -> Vec<String> |
76 | | -{ |
77 | | - let decoded = String::from_utf8(args) |
78 | | - .expect("Got invalid UTF8 from xmlsec1-config"); |
79 | | - |
80 | | - let args = decoded.split_whitespace() |
81 | | - .map(|p| p.to_owned()) |
82 | | - .collect::<Vec<String>>(); |
| 64 | + LocatedDependencies { |
| 65 | + include_paths: library.include_paths, |
| 66 | + defines: library.defines, |
| 67 | + } |
| 68 | +} |
83 | 69 |
|
84 | | - args |
| 70 | +#[cfg(windows)] |
| 71 | +fn locate_and_link_dependencies() -> LocatedDependencies { |
| 72 | + let library = |
| 73 | + vcpkg::find_package("xmlsec").expect("Failed to find xmlsec using vcpkg. Is it installed?"); |
| 74 | + |
| 75 | + println!("cargo:rustc-link-lib=crypt32"); |
| 76 | + println!("cargo:rustc-link-lib=user32"); |
| 77 | + println!("cargo:rustc-link-lib=bcrypt"); |
| 78 | + |
| 79 | + // vcpkg does not provide the defines, so we have to provide them ourselves |
| 80 | + // -DXMLSEC_DL_LIBLTDL=1 -DXMLSEC_CRYPTO_OPENSSL=1 |
| 81 | + let mut defines = HashMap::new(); |
| 82 | + defines.insert("__XMLSEC_FUNCTION__".into(), Some("__func__".into())); |
| 83 | + defines.insert("XMLSEC_NO_SIZE_T".into(), None); |
| 84 | + defines.insert("XMLSEC_DL_LIBLTDL".into(), Some("1".into())); |
| 85 | + defines.insert("XMLSEC_CRYPTO_OPENSSL".into(), Some("1".into())); |
| 86 | + defines.insert("XMLSEC_NO_CRYPTO_DYNAMIC_LOADING".into(), Some("1".into())); |
| 87 | + defines.insert("XMLSEC_NO_GOST".into(), Some("1".into())); |
| 88 | + defines.insert("XMLSEC_NO_GOST2012".into(), Some("1".into())); |
| 89 | + |
| 90 | + LocatedDependencies { |
| 91 | + include_paths: library.include_paths, |
| 92 | + defines, |
| 93 | + } |
85 | 94 | } |
0 commit comments