Skip to content

Commit cb93ad6

Browse files
authored
Merge pull request #4 from leftger/feat/fix-bindings-gen-target
fix: struct matches target architecture
2 parents c7e7fe7 + 399dfcd commit cb93ad6

File tree

2 files changed

+111
-10
lines changed

2 files changed

+111
-10
lines changed

stm32-bindings-gen/src/lib.rs

Lines changed: 54 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,25 @@
1+
use bindgen::callbacks::{ItemInfo, ItemKind, ParseCallbacks};
12
use std::io::Write;
23
use std::{fs, path::PathBuf};
34
use tempfile::NamedTempFile;
45

6+
#[derive(Debug)]
7+
struct UppercaseCallbacks;
8+
9+
impl ParseCallbacks for UppercaseCallbacks {
10+
fn item_name(&self, item: ItemInfo<'_>) -> Option<String> {
11+
if matches!(item.kind, ItemKind::Var) {
12+
Some(item.name.to_ascii_uppercase())
13+
} else {
14+
None
15+
}
16+
}
17+
}
18+
519
pub struct Options {
620
pub out_dir: PathBuf,
721
pub sources_dir: PathBuf,
22+
pub target_triple: String,
823
}
924

1025
pub struct Gen {
@@ -34,11 +49,25 @@ impl Gen {
3449
// The bindgen::Builder is the main entry point
3550
// to bindgen, and lets you build up options for
3651
// the resulting bindings.
37-
let bindings = bindgen::Builder::default()
38-
.clang_arg(format!(
39-
"-I{}/Middlewares/ST/STM32_WPAN/mac_802_15_4/core/inc",
40-
self.opts.sources_dir.to_str().unwrap()
41-
))
52+
let target_flag = format!("--target={}", self.opts.target_triple);
53+
let include_arg = format!(
54+
"-I{}/Middlewares/ST/STM32_WPAN/mac_802_15_4/core/inc",
55+
self.opts.sources_dir.to_str().unwrap()
56+
);
57+
let mut builder = bindgen::Builder::default()
58+
.parse_callbacks(Box::new(UppercaseCallbacks))
59+
// Force Clang to use the same layout as the selected target.
60+
.clang_arg(&target_flag)
61+
.clang_arg(&include_arg);
62+
if self
63+
.opts
64+
.target_triple
65+
.to_ascii_lowercase()
66+
.starts_with("thumb")
67+
{
68+
builder = builder.clang_arg("-mthumb");
69+
}
70+
let bindings = builder
4271
// The input header we would like to generate
4372
// bindings for.
4473
.header("stm32-bindings-gen/inc/wpan-wba.h")
@@ -53,12 +82,30 @@ impl Gen {
5382
.write_to_file(&out_path)
5483
.expect("Couldn't write bindings!");
5584

56-
let file_contents = fs::read_to_string(&out_path).unwrap();
57-
let file_contents = file_contents
85+
let mut file_contents = fs::read_to_string(&out_path).unwrap();
86+
file_contents = file_contents
5887
.replace("::std::mem::", "::core::mem::")
5988
.replace("::std::os::raw::", "::core::ffi::")
6089
.replace("::std::option::", "::core::option::");
6190

91+
file_contents = file_contents
92+
.lines()
93+
.map(|line| {
94+
if let Some(rest) = line.strip_prefix("pub const ") {
95+
if let Some((name, tail)) = rest.split_once(':') {
96+
let upper = name.trim().to_ascii_uppercase();
97+
return format!("pub const {}:{}", upper, tail);
98+
}
99+
}
100+
line.to_owned()
101+
})
102+
.collect::<Vec<_>>()
103+
.join("\n");
104+
105+
if !file_contents.ends_with('\n') {
106+
file_contents.push('\n');
107+
}
108+
62109
fs::write(&out_path, file_contents).unwrap();
63110

64111
// copy misc files

stm32-bindings-gen/src/main.rs

Lines changed: 57 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,70 @@
1-
use std::path::PathBuf;
1+
use std::{env, path::PathBuf, process};
22

33
use stm32_bindings_gen::{Gen, Options};
44

55
fn main() {
66
let out_dir = PathBuf::from("build/stm32-bindings");
77
let sources_dir = PathBuf::from("sources");
8-
9-
// let args: Vec<String> = args().collect();
8+
let target_triple = resolve_target_triple();
109

1110
let opts = Options {
1211
out_dir,
1312
sources_dir,
13+
target_triple,
1414
};
1515
Gen::new(opts).run_gen();
1616
}
17+
18+
fn resolve_target_triple() -> String {
19+
let mut args = env::args().skip(1);
20+
let mut positional: Option<String> = None;
21+
22+
while let Some(arg) = args.next() {
23+
match arg.as_str() {
24+
"--help" | "-h" => {
25+
eprintln!("Usage: stm32-bindings-gen [--target <triple>] [triple]");
26+
process::exit(0);
27+
}
28+
"--target" => {
29+
let value = args.next().unwrap_or_else(|| {
30+
eprintln!("Expected a value after --target");
31+
process::exit(1);
32+
});
33+
let trimmed = value.trim();
34+
if trimmed.is_empty() {
35+
eprintln!("Target triple cannot be empty.");
36+
process::exit(1);
37+
}
38+
return trimmed.to_string();
39+
}
40+
_ => {
41+
if let Some(value) = arg.strip_prefix("--target=") {
42+
let trimmed = value.trim();
43+
if trimmed.is_empty() {
44+
eprintln!("Target triple cannot be empty.");
45+
process::exit(1);
46+
}
47+
return trimmed.to_string();
48+
}
49+
if positional.is_none() {
50+
let trimmed = arg.trim();
51+
if !trimmed.is_empty() {
52+
positional = Some(trimmed.to_string());
53+
}
54+
}
55+
}
56+
}
57+
}
58+
59+
positional
60+
.or_else(|| env::var("BINDGEN_TARGET").ok())
61+
.and_then(|s| {
62+
let trimmed = s.trim();
63+
if trimmed.is_empty() {
64+
None
65+
} else {
66+
Some(trimmed.to_string())
67+
}
68+
})
69+
.unwrap_or_else(|| "thumbv8m.main-none-eabihf".to_string())
70+
}

0 commit comments

Comments
 (0)