aboutsummaryrefslogtreecommitdiff
path: root/steamworks-sys/build.rs
diff options
context:
space:
mode:
authorMatthew Collins <[email protected]>2020-02-22 20:50:46 +0000
committerMatthew Collins <[email protected]>2020-02-22 20:50:46 +0000
commit0b4f68b1f4fac5c7e608861274eadeb5186688b3 (patch)
tree9d69e5fd94e4d6cd8c7a535f4a0236e2d55c7d35 /steamworks-sys/build.rs
parentBump version to 0.6.1 (diff)
downloadsteamworks-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-xsteamworks-sys/build.rs241
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(())
}