Skip to content

Commit c6534e6

Browse files
committed
mbedtls-sys: generate code with a recent version of bindgen
This patch lets us compile mbedtls-sys with recent clang versions. It still has a hack calling "sed" in it, which fixes some of the enum generated names, but it is a good starting point.
1 parent 2343470 commit c6534e6

File tree

2 files changed

+70
-34
lines changed

2 files changed

+70
-34
lines changed

mbedtls-sys/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ libc = { version = "0.2.0", optional = true }
2121
libz-sys = { version = "1.0.0", optional = true }
2222

2323
[build-dependencies]
24-
bindgen = "0.19.0"
24+
bindgen = "0.51.0"
2525
cmake = "0.1.17"
2626

2727
[features]

mbedtls-sys/build/bindgen.rs

Lines changed: 69 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -9,19 +9,46 @@
99
use bindgen;
1010

1111
use std::fs::File;
12-
use std::io::{stderr, Write};
12+
use std::io::Write;
1313

1414
use crate::headers;
1515

1616
#[derive(Debug)]
17-
struct StderrLogger;
17+
struct ParseCallback;
18+
use bindgen::callbacks::IntKind;
1819

19-
impl bindgen::Logger for StderrLogger {
20-
fn error(&self, msg: &str) {
21-
let _ = writeln!(stderr(), "Bindgen ERROR: {}", msg);
20+
impl bindgen::callbacks::ParseCallbacks for ParseCallback {
21+
fn int_macro(&self, name: &str, _value: i64) -> Option<IntKind> {
22+
if name.contains("MBEDTLS_") {
23+
Some(IntKind::I32)
24+
} else {
25+
None
26+
}
2227
}
23-
fn warn(&self, msg: &str) {
24-
let _ = writeln!(stderr(), "Bindgen WARNING: {}", msg);
28+
fn item_name(&self, original_item_name: &str) -> Option<String> {
29+
if original_item_name.starts_with("mbedtls_time_t") {
30+
Some(original_item_name.to_string())
31+
} else if original_item_name.starts_with("cipher_mode_t_MBEDTLS_") {
32+
Some(
33+
original_item_name
34+
.trim_start_matches("cipher_mode_t_MBEDTLS_")
35+
.to_string(),
36+
)
37+
} else if original_item_name.starts_with("mbedtls_") {
38+
Some(
39+
original_item_name
40+
.trim_start_matches("mbedtls_")
41+
.to_string(),
42+
)
43+
} else if original_item_name.starts_with("MBEDTLS_") {
44+
Some(
45+
original_item_name
46+
.trim_start_matches("MBEDTLS_")
47+
.to_string(),
48+
)
49+
} else {
50+
None
51+
}
2552
}
2653
}
2754

@@ -33,49 +60,58 @@ impl super::BuildConfig {
3360
Ok(for h in headers::enabled_ordered() {
3461
writeln!(f, "#include <mbedtls/{}>", h)?;
3562
})
36-
}).expect("bindgen-input.h I/O error");
63+
})
64+
.expect("bindgen-input.h I/O error");
3765

3866
let include = self.mbedtls_src.join("include");
3967

40-
let logger = StderrLogger;
41-
let mut bindgen = bindgen::Builder::new(header.into_os_string().into_string().unwrap());
42-
let bindings = bindgen
43-
.log(&logger)
68+
let bindings = bindgen::Builder::default()
69+
.header(header.into_os_string().into_string().unwrap())
4470
.clang_arg("-Dmbedtls_t_udbl=mbedtls_t_udbl;") // bindgen can't handle unused uint128
4571
.clang_arg(format!(
4672
"-DMBEDTLS_CONFIG_FILE=<{}>",
4773
self.config_h.to_str().expect("config.h UTF-8 error")
48-
)).clang_arg(format!(
74+
))
75+
.clang_arg(format!(
4976
"-I{}",
5077
include.to_str().expect("include/ UTF-8 error")
51-
)).match_pat(include.to_str().expect("include/ UTF-8 error"))
52-
.match_pat(self.config_h.to_str().expect("config.h UTF-8 error"))
53-
.use_core(true)
78+
))
79+
.use_core()
5480
.derive_debug(false) // buggy :(
55-
.ctypes_prefix(vec!["types".to_owned(), "raw_types".to_owned()])
56-
.remove_prefix("mbedtls_")
57-
.rust_enums(false)
58-
.convert_macros(true)
59-
.macro_int_types(
60-
vec![
61-
"sint",
62-
"sint",
63-
"sint",
64-
"slonglong",
65-
"sint",
66-
"sint",
67-
"sint",
68-
"slonglong",
69-
].into_iter(),
70-
).generate()
81+
.parse_callbacks(Box::new(ParseCallback))
82+
.ctypes_prefix("crate::types::raw_types")
83+
.blacklist_function("strtold")
84+
.blacklist_function("qecvt_r")
85+
.blacklist_function("qecvt")
86+
.blacklist_function("qfcvt_r")
87+
.blacklist_function("qgcvt")
88+
.blacklist_function("qfcvt")
89+
.opaque_type("std::*")
90+
.generate_comments(false)
91+
.generate()
7192
.expect("bindgen error");
7293

7394
let bindings_rs = self.out_dir.join("bindings.rs");
7495
File::create(&bindings_rs)
7596
.and_then(|mut f| {
97+
f.write_all(b"#![allow(nonstandard_style)]\n#![allow(unused_imports)]\n")?;
7698
bindings.write(Box::new(&mut f))?;
7799
f.write_all(b"use crate::types::*;\n") // for FILE, time_t, etc.
78-
}).expect("bindings.rs I/O error");
100+
})
101+
.expect("bindings.rs I/O error");
102+
103+
104+
// FIXME: at the time bindgen has a mechanism to rename enum consts
105+
use std::process::Command;
106+
Command::new("sed")
107+
.args(&[
108+
"-i",
109+
"-e",
110+
"s# [a-zA-Z_]*_MBEDTLS_# #g;",
111+
bindings_rs.as_os_str().to_string_lossy().as_ref(),
112+
])
113+
.status()
114+
.unwrap();
79115

80116
let mod_bindings = self.out_dir.join("mod-bindings.rs");
81117
File::create(&mod_bindings)

0 commit comments

Comments
 (0)