diff options
| author | Matthew Collins <[email protected]> | 2020-02-22 20:50:46 +0000 |
|---|---|---|
| committer | Matthew Collins <[email protected]> | 2020-02-22 20:50:46 +0000 |
| commit | 0b4f68b1f4fac5c7e608861274eadeb5186688b3 (patch) | |
| tree | 9d69e5fd94e4d6cd8c7a535f4a0236e2d55c7d35 /steamworks-sys/build.rs | |
| parent | Bump version to 0.6.1 (diff) | |
| download | steamworks-rs-0b4f68b1f4fac5c7e608861274eadeb5186688b3.tar.xz steamworks-rs-0b4f68b1f4fac5c7e608861274eadeb5186688b3.zip | |
Rework to use the new flat steam api
Diffstat (limited to 'steamworks-sys/build.rs')
| -rwxr-xr-x | steamworks-sys/build.rs | 241 |
1 files changed, 23 insertions, 218 deletions
diff --git a/steamworks-sys/build.rs b/steamworks-sys/build.rs index 207ad50..41e1f84 100755 --- a/steamworks-sys/build.rs +++ b/steamworks-sys/build.rs @@ -1,46 +1,4 @@ -extern crate cc; -extern crate serde_json; -#[macro_use] -extern crate serde_derive; - -#[derive(Deserialize)] -struct SteamApi { - typedefs: Vec<SteamTypedef>, - structs: Vec<SteamStruct>, - enums: Vec<SteamEnum>, -} - -#[derive(Deserialize)] -struct SteamTypedef { - typedef: String, - #[serde(rename = "type")] - ty: String, -} - -#[derive(Deserialize)] -struct SteamEnum { - enumname: String, - values: Vec<SteamEnumValue>, -} - -#[derive(Deserialize)] -struct SteamEnumValue { - name: String, - value: String, -} - -#[derive(Deserialize)] -struct SteamStruct { - #[serde(rename = "struct")] - struct_: String, - fields: Vec<SteamField>, -} - -#[derive(Deserialize)] -struct SteamField { - fieldname: String, - fieldtype: String, -} +extern crate bindgen; #[cfg(feature = "docs-only")] fn main() {} @@ -49,9 +7,7 @@ fn main() {} fn main() -> Result<(), Box<dyn std::error::Error>> { use std::env; use std::path::{Path, PathBuf}; - use std::fmt::Write as _; - use std::fs::{self, File}; - use std::borrow::Cow; + use std::fs::{self}; let out_path = PathBuf::from(env::var("OUT_DIR").unwrap()); let sdk_loc = env::var("STEAM_SDK_LOCATION") @@ -60,7 +16,6 @@ fn main() -> Result<(), Box<dyn std::error::Error>> { let triple = env::var("TARGET").unwrap(); let mut lib = "steam_api"; - let mut packing = 8; let mut link_path = sdk_loc.join("redistributable_bin"); if triple.contains("windows") { if !triple.contains("i686") { @@ -68,14 +23,12 @@ fn main() -> Result<(), Box<dyn std::error::Error>> { link_path.push("win64"); } } else if triple.contains("linux") { - packing = 4; if triple.contains("i686") { link_path.push("linux32"); } else { link_path.push("linux64"); } } else if triple.contains("darwin") { - packing = 4; link_path.push("osx"); } else { panic!("Unsupported OS"); @@ -83,167 +36,29 @@ fn main() -> Result<(), Box<dyn std::error::Error>> { println!("cargo:rustc-link-search={}", link_path.display()); println!("cargo:rustc-link-lib=dylib={}", lib); - if env::var("STEAM_SDK_MAKE_BINDINGS").is_ok() { - - // Steamworks uses packed structs making them hard to work - // with normally - let steam_api_json_loc = sdk_loc.join("public/steam/steam_api.json"); - let file = File::open(&steam_api_json_loc).expect(&format!("open {:?}", steam_api_json_loc)); - let steam_api: SteamApi = serde_json::from_reader(file)?; - - let mut bindings = r##" - use libc::*; - "##.to_owned(); - - fn c_to_rust<'a>(fty: &'a str) -> Option<(&'a str, Cow<'a, str>)> { - // Generics - if fty == "T *" { - return None; - } - let fty = { - if fty.contains("enum") { - if fty.contains("::") { - return None; - } - fty.trim_start_matches("enum ") - } else if fty.contains("struct") { - fty.trim_start_matches("struct ") - } else if fty == "_Bool" { - "bool" - } else { - fty - } - }; - let fty_rust = if fty == "const char*" || fty == "*const char" || fty == "const char *" { - "*const c_char".into() - } else if fty == "char*" { - "*mut c_char".into() - } else if fty == "const char **" { - "*mut *const c_char".into() - } else if fty.ends_with("*") { - if fty.starts_with("const") { - let trimmed = fty.trim_start_matches("const ").trim_end_matches("*").trim(); - format!("*const {}", c_to_rust(trimmed)?.1).into() - } else { - let trimmed = fty.trim_end_matches("*").trim(); - format!("*mut {}", c_to_rust(trimmed)?.1).into() - } - } else if fty.contains("[") { - let open_square = fty.char_indices().find(|ic| ic.1 == '[').unwrap().0; - let close_square = fty.char_indices().find(|ic| ic.1 == ']').unwrap().0; - format!( - "[{}; {}]", - c_to_rust(&fty[..open_square].trim())?.1, - &fty[open_square + 1..close_square], - ).into() - } else if fty.contains("(") { - eprintln!("Unsupported field type function pointer: {:?}", fty); - return None; - } else { - match fty { - "int" => "c_int".into(), - "float" => "c_float".into(), - "double" => "c_double".into(), - "void" => "c_void".into(), - "uint8" => "u8".into(), - "int8" => "i8".into(), - "uint16" => "u16".into(), - "int16" => "i16".into(), - "uint32" => "u32".into(), - "int32" => "i32".into(), - "uint64" => "u64".into(), - "int64" => "i64".into(), - "lint64" => "i64".into(), - "ulint64" => "u64".into(), - "intp" => "isize".into(), - "uintp" => "usize".into(), - "class CSteamID" => "CSteamID".into(), - "class CGameID" => "CGameID".into(), - "char" => "c_char".into(), - val if val.contains("class") => return None, - val => val.into(), - } - }; - - Some((fty, fty_rust)) - } - - for def in steam_api.typedefs { - if def.typedef.chars().next().map_or(true, |v| v.is_lowercase()) { - continue; - } - - if let Some(rty) = c_to_rust(&def.ty) { - if def.typedef == rty.1 || def.typedef.contains("::") { - continue; - } - writeln!(bindings, r#" - #[repr(transparent)] - #[derive(PartialEq, Eq, Hash, Clone, Copy)] - pub struct {}(pub {});"#, def.typedef, rty.1)?; + let bindings = bindgen::Builder::default() + .header("src/fixes.hpp") + .header(sdk_loc.join("public/steam/steam_api_flat.h").to_string_lossy()) + .header(sdk_loc.join("public/steam/steam_gameserver.h").to_string_lossy()) + .clang_arg("-xc++") + .opaque_type("SteamTVRegion_t") + .clang_arg(format!("-I{}", sdk_loc.join("public").display())) + .rustfmt_bindings(true) + .default_enum_style(bindgen::EnumVariation::Rust { + non_exhaustive: true + }) + .generate() + .expect("Unable to generate bindings"); + + bindings + .write_to_file( + if env::var("STEAM_SDK_MAKE_BINDINGS").is_ok() { + Path::new("src/bindings.rs").to_owned() } else { - eprintln!("Could not typedef {:?}", def.typedef); - } - } - - for e in steam_api.enums { - if e.enumname.contains("::") { - continue; - } - writeln!(bindings, r#" - #[repr(C)] - #[derive(PartialEq, Eq, Hash, Clone, Copy)] - pub enum {} {{"#, e.enumname)?; - - for v in e.values { - // Known duplicate - if v.name == "k_EWorkshopFileTypeFirst" { - continue; - } - writeln!(bindings, r#" {} = {},"#, v.name.trim_start_matches("k_"), v.value)?; + out_path.join("bindings.rs") } - - writeln!(bindings, r#"}}"#)?; - - } - - 'structs: - for s in steam_api.structs { - if s.struct_ == "CSteamID" || s.struct_ == "CGameID" || s.struct_.contains("::") { - continue; - } - // TODO: Remove special case for SteamUGCDetails_t - let derive = if !s.fields.iter().any(|v| - v.fieldtype == "float" - || v.fieldtype == "double" - || v.fieldtype == "struct SteamUGCDetails_t" - || v.fieldtype.contains('[')) - { - "#[derive(Clone, Copy, PartialEq, Eq, Hash)]" - } else { - "#[derive(Clone, Copy)]" - }; - let mut s_builder = String::new(); - writeln!(s_builder, r#" - #[repr(C, packed({}))] - {} - pub struct {} {{"#, packing, derive, s.struct_)?; - - for f in s.fields { - if let Some(rty) = c_to_rust(&f.fieldtype) { - writeln!(s_builder, " pub {}: {},", f.fieldname, rty.1)?; - } else { - continue 'structs; - } - } - - writeln!(s_builder, r#"}}"#)?; - - bindings.push_str(&s_builder); - } - - fs::write("src/bindings.rs", bindings)?; - } + ) + .expect("Couldn't write bindings!"); if triple.contains("windows") { let file_name = format!("{}.dll", lib); @@ -254,15 +69,5 @@ fn main() -> Result<(), Box<dyn std::error::Error>> { fs::copy(link_path.join("libsteam_api.so"), out_path.join("libsteam_api.so"))?; } - let mut compiler = cc::Build::new(); - compiler - .cpp(true) - .include(sdk_loc.join("public/steam")) - .file("src/lib.cpp"); - if triple.contains("darwin") || triple.contains("linux") { - compiler.flag("-std=c++11"); - } - compiler.compile("steamrust"); - Ok(()) } |