From 1408f38807a0a38655c1920ec5beb0c69b8a5a6d Mon Sep 17 00:00:00 2001 From: Michael Wu Date: Mon, 3 Sep 2018 15:44:08 -0700 Subject: [PATCH] Add cfg switches for frameworks and add more frameworks --- Cargo.toml | 25 +++++++++++++++ build.rs | 3 +- rustkit_bindgen/src/lib.rs | 63 ++++++++++++++++++++++++++++++++++++-- 3 files changed, 88 insertions(+), 3 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index b079f34..31c45e5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,3 +13,28 @@ rustkit_bindgen = { path = "rustkit_bindgen", version = "0.0.1" } [dependencies] bitflags = "1.0" + +[features] +default = ["RK_Foundation"] + +RK_AVFoundation = [] +RK_AVKit = [] +RK_AppKit = [] +RK_AudioToolbox = [] +RK_CoreAudio = [] +RK_CoreData = [] +RK_CoreFoundation = [] +RK_CoreGraphics = [] +RK_CoreImage = [] +RK_CoreMedia = [] +RK_CoreServices = [] +RK_CoreVideo = [] +RK_DiskArbitration = [] +RK_Foundation = [] +RK_IOSurface = [] +RK_ImageIO = [] +RK_MediaToolbox = [] +RK_Metal = [] +RK_OpenGL = [] +RK_QuartzCore = [] +RK_Security = [] diff --git a/build.rs b/build.rs index 3605c57..d75b5ea 100644 --- a/build.rs +++ b/build.rs @@ -24,7 +24,7 @@ fn main () { let out_dir = env::var("OUT_DIR").unwrap(); let out_dir = Path::new(&out_dir); let sdk_root = Path::new("/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk"); - let frameworks = vec!["Foundation"]; + let frameworks = vec!["AVKit", "AppKit", "Foundation"]; let top_path = out_dir.join("top.rs"); let mut top = File::create(&top_path).unwrap(); bind_system_header(&sdk_root, "objc/NSObject.h", &out_dir, &mut top); @@ -32,6 +32,7 @@ fn main () { bind_system_header(&sdk_root, "sys/acl.h", &out_dir, &mut top); bind_system_header(&sdk_root, "hfs/hfs_unistr.h", &out_dir, &mut top); bind_system_header(&sdk_root, "mach/message.h", &out_dir, &mut top); + bind_system_header(&sdk_root, "simd/types.h", &out_dir, &mut top); let mut done: HashSet = HashSet::new(); let mut deps: Vec = frameworks.iter().map(|s| s.to_string()).collect(); while let Some(f) = deps.pop() { diff --git a/rustkit_bindgen/src/lib.rs b/rustkit_bindgen/src/lib.rs index f56d175..732740e 100644 --- a/rustkit_bindgen/src/lib.rs +++ b/rustkit_bindgen/src/lib.rs @@ -1120,7 +1120,7 @@ pub fn bind_framework( let idx = walker::Index::new().unwrap(); let framework_include = format!("-F{}/System/Library/Frameworks", sdk_path_str); let system_include_path = format!("-I{}/usr/include", sdk_path_str); - let args = vec![ + let mut args = vec![ "-ObjC", "-fobjc-arc", "-fno-objc-exceptions", @@ -1129,6 +1129,10 @@ pub fn bind_framework( &system_include_path, include_path.to_str().unwrap(), ]; + if framework_name == "IOSurface" { + args.push("-include"); + args.push("IOSurface/IOSurfaceObjC.h"); + } let tu = idx.parse_tu(&args).unwrap(); let mut out_path = out_dir.to_owned(); out_path.push(&format!("{}.rs", framework_name)); @@ -1447,6 +1451,35 @@ fn gen_file( } } + fn gen_framework_sel_attr(decls: &HashMap, framework_name: Option<&str>, refs: &[String]) -> Option { + let mut frameworks = HashSet::new(); + for r in refs { + let target_framework = if let Some(itemdecl) = decls.get(r) { + let name = itemdecl.framework_name(); + if let Some(name) = name.last() { + name.to_owned() + } else { + continue; + } + } else { + continue; + }; + if let Some(framework) = framework_name { + if framework == target_framework { + continue; + } + } + if target_framework == "Foundation" { + continue; + } + frameworks.insert(format!("RK_{}", target_framework)); + } + if frameworks.is_empty() { + None + } else { + Some(parse_quote!(#[cfg(all(#(feature = #frameworks),*))])) + } + } let mut uses = HashSet::new(); for d in decls.values() { if !d.src().starts_with(base_path) { @@ -1517,6 +1550,11 @@ fn gen_file( }); } + let mut framework_feature_check: Vec = Vec::new(); + if let Some(framework_name) = framework_name { + let feature_name = format!("RK_{}", framework_name); + framework_feature_check.push(parse_quote!(#[cfg(feature = #feature_name)])); + } for s in selectors { let mut sel = s.as_bytes().to_owned(); sel.push(0); @@ -1680,6 +1718,9 @@ fn gen_file( let mut func = syn::parse2(tokens).unwrap(); if let syn::ImplItem::Method(ref mut method) = func { method.vis = parse_quote!{pub}; + if let Some(cfg) = gen_framework_sel_attr(decls, framework_name, &m.refs()) { + method.attrs.push(cfg); + } } methods.push(func); } @@ -1689,6 +1730,9 @@ fn gen_file( let mut func = syn::parse2(tokens).unwrap(); if let syn::ImplItem::Method(ref mut method) = func { method.vis = parse_quote!{pub}; + if let Some(cfg) = gen_framework_sel_attr(decls, framework_name, &m.refs()) { + method.attrs.push(cfg); + } } methods.push(func); } @@ -1699,6 +1743,9 @@ fn gen_file( let mut func = syn::parse2(tokens).unwrap(); if let syn::ImplItem::Method(ref mut method) = func { method.vis = parse_quote!{pub}; + if let Some(cfg) = gen_framework_sel_attr(decls, framework_name, &m.refs()) { + method.attrs.push(cfg); + } } methods.push(func); } @@ -1711,12 +1758,17 @@ fn gen_file( let mut func = syn::parse2(tokens).unwrap(); if let syn::ImplItem::Method(ref mut method) = func { method.vis = parse_quote!{pub}; + if let Some(cfg) = gen_framework_sel_attr(decls, framework_name, &m.refs()) { + method.attrs.push(cfg); + } } methods.push(func); } } + let framework_feature_check = framework_feature_check.clone(); ast.items.push(parse_quote!{ + #(#framework_feature_check)* impl #name { #(#methods)* } @@ -1732,7 +1784,13 @@ fn gen_file( let mut methods: Vec = Vec::new(); for (s, m) in &c.imethods { if let Some(tokens) = m.gen_call(&decls, s, false) { - let func = syn::parse2(tokens).unwrap(); + let mut func = syn::parse2(tokens).unwrap(); + if let syn::TraitItem::Method(ref mut method) = func { + if let Some(cfg) = gen_framework_sel_attr(decls, framework_name, &m.refs()) { + method.attrs.push(cfg); + } + method.attrs.extend(framework_feature_check.iter().cloned()); + } methods.push(func); } } @@ -1785,6 +1843,7 @@ fn gen_file( if let Some(framework_name) = framework_name { ast.items.push(parse_quote!{ + #(#framework_feature_check)* #[link(name=#framework_name, kind="framework")] extern "C" { #(#funcs)*