Skip to content

Commit

Permalink
Replace imgui-sys-bindgen with a newly-added xtask setup
Browse files Browse the repository at this point in the history
  • Loading branch information
thomcc committed Dec 8, 2020
1 parent 6084763 commit 4f5eba7
Show file tree
Hide file tree
Showing 11 changed files with 263 additions and 178 deletions.
2 changes: 2 additions & 0 deletions .cargo/config
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[alias]
xtask = "run --package xtask --"
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,5 @@ members = [
"imgui-winit-support",
"imgui-examples",
"imgui-gfx-examples",
"imgui-sys-bindgen",
"xtask",
]
16 changes: 0 additions & 16 deletions imgui-sys-bindgen/Cargo.toml

This file was deleted.

123 changes: 0 additions & 123 deletions imgui-sys-bindgen/src/lib.rs

This file was deleted.

28 changes: 0 additions & 28 deletions imgui-sys-bindgen/src/main.rs

This file was deleted.

7 changes: 2 additions & 5 deletions imgui-sys/src/bindings.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
/* automatically generated by rust-bindgen 0.55.1 */
/* automatically generated by rust-bindgen 0.56.0 */

#![allow(non_upper_case_globals)]
#![allow(non_camel_case_types)]
#![allow(non_snake_case)]
#![allow(clippy::all)]
#![allow(nonstandard_style, clippy::all)]

#[repr(C)]
#[derive(Copy, Clone, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)]
Expand Down
7 changes: 2 additions & 5 deletions imgui-sys/src/wasm_bindings.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
/* automatically generated by rust-bindgen 0.55.1 */
/* automatically generated by rust-bindgen 0.56.0 */

#![allow(non_upper_case_globals)]
#![allow(non_camel_case_types)]
#![allow(non_snake_case)]
#![allow(clippy::all)]
#![allow(nonstandard_style, clippy::all)]

#[repr(C)]
#[derive(Copy, Clone, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)]
Expand Down
12 changes: 12 additions & 0 deletions xtask/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# See https://github.com/matklad/cargo-xtask for more on this pattern.
[package]
name = "xtask"
version = "0.1.0"
authors = ["Thom Chiovoloni <[email protected]>"]
edition = "2018"
publish = false

[dependencies]
anyhow = "1"
pico-args = "0.3"
smoljson = "0.1"
155 changes: 155 additions & 0 deletions xtask/src/bindgen.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
use anyhow::{anyhow, Context, Result};
use std::path::{Path, PathBuf};

pub struct GenBindings {
pub bindings_path: Option<String>,
pub output_path: Option<String>,
pub wasm_import_name: Option<String>,
}

impl GenBindings {
pub fn run(self) -> Result<()> {
let root = crate::project_root();
let bindings = self
.bindings_path
.map(PathBuf::from)
.unwrap_or_else(|| root.join("imgui-sys/third-party"));

let output = self
.output_path
.map(PathBuf::from)
.unwrap_or_else(|| root.join("imgui-sys/src"));

let wasm_name = self
.wasm_import_name
.or_else(|| std::env::var("IMGUI_RS_WASM_IMPORT_NAME").ok())
.unwrap_or_else(|| "imgui-sys-v0".to_string());
let types = get_types(&bindings.join("structs_and_enums.json"))?;
let funcs = get_definitions(&bindings.join("definitions.json"))?;
let header = bindings.join("cimgui.h");

generate_binding_file(&header, &output.join("bindings.rs"), &types, &funcs, None)?;
generate_binding_file(
&header,
&output.join("wasm_bindings.rs"),
&types,
&funcs,
Some(&wasm_name),
)?;

Ok(())
}
}

fn get_types(structs_and_enums: &Path) -> Result<Vec<String>> {
let types_txt = std::fs::read_to_string(structs_and_enums)?;
let types_val = types_txt
.parse::<smoljson::ValOwn>()
.map_err(|e| anyhow!("Failed to parse {}: {:?}", structs_and_enums.display(), e))?;
let mut types: Vec<String> = types_val["enums"]
.as_object()
.ok_or_else(|| anyhow!("No `enums` in bindings file"))?
.keys()
.map(|k| format!("^{}", k))
.collect();
types.extend(
types_val["structs"]
.as_object()
.ok_or_else(|| anyhow!("No `structs` in bindings file"))?
.keys()
.map(|k| format!("^{}", k)),
);
Ok(types)
}

fn get_definitions(definitions: &Path) -> Result<Vec<String>> {
fn bad_arg_type(s: &str) -> bool {
s == "va_list" || s.starts_with("__")
}
let defs_txt = std::fs::read_to_string(definitions)?;
let defs_val = defs_txt
.parse::<smoljson::ValOwn>()
.map_err(|e| anyhow!("Failed to parse {}: {:?}", definitions.display(), e))?;
let definitions = defs_val
.into_object()
.ok_or_else(|| anyhow!("bad json data in defs file"))?;
let mut keep_defs = vec![];
for (name, def) in definitions {
let defs = def
.into_array()
.ok_or_else(|| anyhow!("def {} not an array", &name))?;
keep_defs.reserve(defs.len());
for func in defs {
let args = func["argsT"].as_array().unwrap();
if !args
.iter()
.any(|a| a["type"].as_str().map_or(false, bad_arg_type))
{
let name = func["ov_cimguiname"]
.as_str()
.ok_or_else(|| anyhow!("ov_cimguiname wasnt string..."))?;
keep_defs.push(format!("^{}", name));
}
}
}
Ok(keep_defs)
}

fn generate_binding_file(
header: &Path,
output: &Path,
types: &[String],
funcs: &[String],
wasm_import_mod: Option<&str>,
) -> Result<()> {
let mut cmd = std::process::Command::new("bindgen");
let a = &[
"--size_t-is-usize",
"--no-prepend-enum-name",
"--no-doc-comments",
"--with-derive-default",
"--with-derive-partialeq",
"--with-derive-eq",
"--with-derive-hash",
"--impl-debug",
];
cmd.args(a);
cmd.args(&["--blacklist-type", "__darwin_size_t"]);
cmd.args(&["--raw-line", "#![allow(nonstandard_style, clippy::all)]"]);
cmd.arg("--output").arg(output);

if let Some(name) = wasm_import_mod {
cmd.args(&["--wasm-import-module-name", &name]);
}
for t in types {
cmd.args(&["--whitelist-type", t]);
}
for f in funcs {
cmd.args(&["--whitelist-function", f]);
}
cmd.arg(header);
cmd.args(&["--", "-DCIMGUI_DEFINE_ENUMS_AND_STRUCTS=1"]);
eprintln!("Executing bindgen [output = {}]", output.display());
let status = cmd.status().context("Failed to exacute bindgen")?;
if !status.success() {
anyhow!(
"Failed to execute bindgen: {}, see output for details",
status
);
}
eprintln!("Success [output = {}]", output.display());

Ok(())
}

// impl Deref for CountingCommand {
// type Target = std::process::Command;
// fn deref(&self) -> &Self::Target {
// &self.c
// }
// }
// impl std::ops::DerefMut for CountingCommand {
// fn deref_mut(&mut self) -> &mut Self::Target {
// &mut self.c
// }
// }
Loading

0 comments on commit 4f5eba7

Please sign in to comment.