-
Notifications
You must be signed in to change notification settings - Fork 45
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Automatic binding generation #264
Conversation
bc10d5a
to
c6ef627
Compare
I estimated the size of the code if we included all of Apple's frameworks (assuming Rust and C have similar line ratios); it would be around 13MB zipped, 50MB unzipped. For reference, the |
I probably won't put this under
|
075c18c
to
167ad93
Compare
Example of how I want at least some of AppKit to look like: https://github.com/rust-windowing/winit/tree/fafdedfb7d3a7370ca4b01108f7713b685633164/src/platform_impl/macos/appkit |
How can we model this nicely? |
Idea: Use (parts of) Swift's test suite (for example this one for errors: https://github.com/apple/swift/blob/7123d2614b5f222d03b3762cb110d27a9dd98e24/test/Inputs/clang-importer-sdk/usr/include/errors.h) |
dedf7d4
to
420f9a0
Compare
Clang has "module maps" for figuring out what to import from Objective-C headers - we should use those! |
Hey, I'm really excited about this enhancement and would find it super useful for some work I'm doing on binding the
|
e0ff895
to
a8d2ada
Compare
Currently I'm trying to push forwards on an initial version that actually compiles Primary missing items are:
Timeline on this is unknown, but I have quite a lot of free time this week, so I should be able to get pretty far. I can probably give you a better estimate at the end of the week, if I'm not done by then. Once I have this finished, there'll be lots of smaller things to work on, which I could probably use some help with, including:
I'll try to see if I can figure out a good way for you / somebody else to contribute with some of that, when I get there. |
I could use some guidance though: I'll admit I'm not the best at But what do you think? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I could use some guidance though: I'll admit I'm not the best at
git
, and I'm unsure if storing the generated result ingit
is the best solution? It does make audits (security and just general) easier, at the cost of blowing up the amount files we store. An alternative could also be to create a new repo just for it.But what do you think?
Putting it in a different repo isn't a bad idea but I think in general what I'd say is that the generated stuff in tracking should be either for some kind of sys-crate (or icrate
) or for integration tests. Bindgen keeps the input headers and the expectations in git and verifies that they match as expected in CI and the output does compile. Using the full frameworks to test is useful to know breadth of functionality but I believe it can change from macOS/SDK version to version.
After reviewing some stuff, it seems like the header-translator
crate is meant to run as a binary and then either store the output in the crate and tracking. I tend to like using a generator crate in a build script.
header-translator/src/main.rs
Outdated
}); | ||
} | ||
|
||
fn output_files( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should you want to use this crate as a build script, I think output_files
(and other stuff) will need to go in the lib.rs
a8d2ada
to
d6eefa8
Compare
Yeah, I'm aware of that approach, my desire with
I think my desire was to manually keep |
We can't parse it yet though, see #250
56827ff
to
d1ae521
Compare
Well, I was writing an automatic binding generator for AppKit, only to find out that you're doing it already; and from a glance it looks like your version is way ahead of mine! :-) My only complaint would be that, in my opinion, having the setup use // Have this trait.
pub trait IsA<T> {}
pub struct NSDate { /* .. */ }
impl IsA<NSDate> for NSDate {}
impl IsA<NSObject> for NSObject {}
// Extension trait.
pub trait NSDateExt : IsA<NSDate> { /* ... */ }
impl<T: IsA<NSDate>> NSDateExt for T {} That being said, I'm very excited to see this once it reaches readiness. Please let me know if there's anything I can do for this. |
See full history in 1c4c875. Add initial header translation Closer to usable Mostly works with NSCursor Mostly works with NSAlert.h Refactor a bit AppKit is now parse-able handle reserved keywords Handle protocols somewhat Handle the few remaining entity kinds Works with Foundation Cleanup Refactor Refactor Method to (almost) be PartialEq Parse more things Parse NSConsumed Verify memory management More work Fix reserved keywords Refactor statements Add initial availability Prepare RustType Split RustType up in parse and ToToken part Add icrate Add config files Temporarily disable protocol generation Generate files Add initial generated files for Foundation Skip "index" header Add basic imports Allow skipping methods Properly emit `unsafe` Make classes public Rename objc feature flag Improve imports somewhat Further import improvements Handle basic typedefs Improve generics handling Improve pointers to objects Refactor RustType::TypeDef Mostly support generics Refactor config setup Small fixes Support nested generics Comment out a bit of debug logging Emit all files Parse sized integer types Parse typedefs that map to other typedefs Appease clippy Add `const`-parsing for RustType::Id Parse Objective-C in/out/inout/bycopy/byref/oneway qualifiers Fix `id` being emitted when it actually specifies a protocol Make AppKit work again Parse all qualifiers, in particular lifetime qualifiers More consistent ObjCObjectPointer parsing Validate some lifetime attributes Fix out parameters (except for NSError) Assuming we find a good solution to #277 Refactor Stmt objc declaration parsing Clean up how return types work Refactor property parsing Fixes their order to be the same as in the source file Add support for functions taking NSError as an out parameter Assuming we do #276 Change icrate directory layout Refactor slightly Refactor file handling to allow for multiple frameworks simultaneously Put method output inside an extern_methods! call We'll want this no matter what, since it'll allow us to extend things with availability attributes in the future. Use extern_methods! functionality To cut down on the amount of code, which should make things easier to review and understand. This uses features which are not actually yet done, see #244. Not happy with the formatting either, but not sure how to fix that? Manually fix the formatting of attribute macros in extern_methods! Add AppKit bindings Speed things up by optionally formatting at the end instead Prepare for parsing more than one SDK Specify a minimum deployment target Document SDK situation Parse headers on iOS as well Refactor stmt parsing a bit Remove Stmt::FileImport and Stmt::ItemImport These are not nearly enough to make imports work well anyhow, so I'll rip it out and find a better solution Do preprocessing step explicitly as the first thing Refactor so that file writing is done using plain Display Allows us to vastly improve the speed, as well as allowing us to make the output much prettier wrt. newlines and such in the future (proc_macro2 / quote output is not really meant to be consumed by human eyes) Improve whitespace in generated files and add warning header Don't crash on unions Add initial enum parsing Add initial enum expr parsing Add very simple enum output Fix duplicate enum check Improve enum expr parsing This should make it easier for things to work on 32-bit platforms Add static variable parsing Add a bit of WIP code Add function parsing Fix generic struct generation Make &Class as return type static Trim unnecessary parentheses Fix generics default parameter Remove methods that are both instance and class methods For now, until we can solve this more generally Skip protocols that are also classes Improve imports setups Bump recursion limit Add MacTypes.h type translation Fix int64_t type translation Make statics public Fix init methods Make __inner_extern_class allowing trailing comma in generics Attempt to improve Rust's parsing speed of icrate Custom NSObject TMP import Remove NSProxy Temporarily remove out parameter setup Add struct support Add partial support for "related result types" Refactor typedef parsing a bit Output remaining typedefs Fix Option<Sel> and *mut bool Fix almost all remaining type errors in Foundation Skip statics whoose value we cannot find Fix anonymous enum types Fix AppKit duplicate methods Add CoreData Properly fix imports Add `abstract` keyword Put enum and static declarations behind a macro Add proper IncompleteArray parsing Refactor type parsing Make NSError** handling happen in all the places that it does with Swift Refactor Ty a bit more Make Display for RustType always sound Add support for function pointers Add support for block pointers Add extern functions Emit protocol information We can't parse it yet though, see #250 Make CoreData compile Make AppKit compile Add support for the AuthenticationServices framework Do clang < v13 workarounds without modifying sources Refactor Foundation fixes
Yeah, still very much experimenting with what's the best approach! I'm not sure what you mean by "isn't hygenic", would you care to elaborate?
Sure, there will be fairly soon. I'm done with the rebase and do actually have something workable over in #308 now, once that is merged it should become easier to collaborate. |
See full history in 1c4c875. Add initial header translation Closer to usable Mostly works with NSCursor Mostly works with NSAlert.h Refactor a bit AppKit is now parse-able handle reserved keywords Handle protocols somewhat Handle the few remaining entity kinds Works with Foundation Cleanup Refactor Refactor Method to (almost) be PartialEq Parse more things Parse NSConsumed Verify memory management More work Fix reserved keywords Refactor statements Add initial availability Prepare RustType Split RustType up in parse and ToToken part Add icrate Add config files Temporarily disable protocol generation Generate files Add initial generated files for Foundation Skip "index" header Add basic imports Allow skipping methods Properly emit `unsafe` Make classes public Rename objc feature flag Improve imports somewhat Further import improvements Handle basic typedefs Improve generics handling Improve pointers to objects Refactor RustType::TypeDef Mostly support generics Refactor config setup Small fixes Support nested generics Comment out a bit of debug logging Emit all files Parse sized integer types Parse typedefs that map to other typedefs Appease clippy Add `const`-parsing for RustType::Id Parse Objective-C in/out/inout/bycopy/byref/oneway qualifiers Fix `id` being emitted when it actually specifies a protocol Make AppKit work again Parse all qualifiers, in particular lifetime qualifiers More consistent ObjCObjectPointer parsing Validate some lifetime attributes Fix out parameters (except for NSError) Assuming we find a good solution to #277 Refactor Stmt objc declaration parsing Clean up how return types work Refactor property parsing Fixes their order to be the same as in the source file Add support for functions taking NSError as an out parameter Assuming we do #276 Change icrate directory layout Refactor slightly Refactor file handling to allow for multiple frameworks simultaneously Put method output inside an extern_methods! call We'll want this no matter what, since it'll allow us to extend things with availability attributes in the future. Use extern_methods! functionality To cut down on the amount of code, which should make things easier to review and understand. This uses features which are not actually yet done, see #244. Not happy with the formatting either, but not sure how to fix that? Manually fix the formatting of attribute macros in extern_methods! Add AppKit bindings Speed things up by optionally formatting at the end instead Prepare for parsing more than one SDK Specify a minimum deployment target Document SDK situation Parse headers on iOS as well Refactor stmt parsing a bit Remove Stmt::FileImport and Stmt::ItemImport These are not nearly enough to make imports work well anyhow, so I'll rip it out and find a better solution Do preprocessing step explicitly as the first thing Refactor so that file writing is done using plain Display Allows us to vastly improve the speed, as well as allowing us to make the output much prettier wrt. newlines and such in the future (proc_macro2 / quote output is not really meant to be consumed by human eyes) Improve whitespace in generated files and add warning header Don't crash on unions Add initial enum parsing Add initial enum expr parsing Add very simple enum output Fix duplicate enum check Improve enum expr parsing This should make it easier for things to work on 32-bit platforms Add static variable parsing Add a bit of WIP code Add function parsing Fix generic struct generation Make &Class as return type static Trim unnecessary parentheses Fix generics default parameter Remove methods that are both instance and class methods For now, until we can solve this more generally Skip protocols that are also classes Improve imports setups Bump recursion limit Add MacTypes.h type translation Fix int64_t type translation Make statics public Fix init methods Make __inner_extern_class allowing trailing comma in generics Attempt to improve Rust's parsing speed of icrate Custom NSObject TMP import Remove NSProxy Temporarily remove out parameter setup Add struct support Add partial support for "related result types" Refactor typedef parsing a bit Output remaining typedefs Fix Option<Sel> and *mut bool Fix almost all remaining type errors in Foundation Skip statics whoose value we cannot find Fix anonymous enum types Fix AppKit duplicate methods Add CoreData Properly fix imports Add `abstract` keyword Put enum and static declarations behind a macro Add proper IncompleteArray parsing Refactor type parsing Make NSError** handling happen in all the places that it does with Swift Refactor Ty a bit more Make Display for RustType always sound Add support for function pointers Add support for block pointers Add extern functions Emit protocol information We can't parse it yet though, see #250 Make CoreData compile Make AppKit compile Add support for the AuthenticationServices framework Do clang < v13 workarounds without modifying sources Refactor Foundation fixes
A possible source of at least a bit of docs is also https://github.com/xamarin/apple-api-docs. In general, Xamarin has done a lot of work in this space, I should try to take a look at their stuff at some point |
#308 is done 🎉 Will try to release a new version of |
This is very similar to using
bindgen
, but I went with creating things from scratch because:bindgen
is kinda intimidating, knowing so little aboutlibclang
, so I started here first; I'd still like to upstream some of this, but I'll start here for now.bindgen
has to handle all C code under the sun. A few manual fixes and such are acceptable.#[cfg]
so that we can ship one, ready-to-use library..apinotes
or similar), and such a thing will probably never belong inbindgen
That said, I have taken inspiration from the existing Objective-C implementation in
bindgen
, credits to @simlay.In the end, I'm envisioning something like this (so
objc2
would be the Apple equivalent to thewindows
crate):See #85 (comment) for a bit of details on what Swift does.