Skip to content

Commit

Permalink
Add cfg switches for frameworks and add more frameworks
Browse files Browse the repository at this point in the history
  • Loading branch information
michaelwu committed Sep 3, 2018
1 parent 32bfccd commit 1408f38
Show file tree
Hide file tree
Showing 3 changed files with 88 additions and 3 deletions.
25 changes: 25 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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 = []
3 changes: 2 additions & 1 deletion build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,15 @@ 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);
bind_system_header(&sdk_root, "MacTypes.h", &out_dir, &mut top);
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<String> = HashSet::new();
let mut deps: Vec<String> = frameworks.iter().map(|s| s.to_string()).collect();
while let Some(f) = deps.pop() {
Expand Down
63 changes: 61 additions & 2 deletions rustkit_bindgen/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand All @@ -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));
Expand Down Expand Up @@ -1447,6 +1451,35 @@ fn gen_file(
}
}

fn gen_framework_sel_attr(decls: &HashMap<String, ItemDecl>, framework_name: Option<&str>, refs: &[String]) -> Option<syn::Attribute> {
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) {
Expand Down Expand Up @@ -1517,6 +1550,11 @@ fn gen_file(
});
}

let mut framework_feature_check: Vec<syn::Attribute> = 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);
Expand Down Expand Up @@ -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);
}
Expand All @@ -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);
}
Expand All @@ -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);
}
Expand All @@ -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)*
}
Expand All @@ -1732,7 +1784,13 @@ fn gen_file(
let mut methods: Vec<syn::TraitItem> = 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);
}
}
Expand Down Expand Up @@ -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)*
Expand Down

0 comments on commit 1408f38

Please sign in to comment.