Skip to content
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

Add a bindgen pass #2124

Closed
brson opened this issue Apr 4, 2012 · 13 comments
Closed

Add a bindgen pass #2124

brson opened this issue Apr 4, 2012 · 13 comments
Labels
A-frontend Area: frontend (errors, parsing and HIR) C-enhancement Category: An issue proposing an enhancement or a PR with one. P-low Low priority

Comments

@brson
Copy link
Contributor

brson commented Apr 4, 2012

Make a pass that executes bindgen during the build.

This would build the jsapi module automatically based on the header files:

#[bindgen(files("jsapi.h", "jswhatever.h"), name = "jsapi")];

It would never generate any .rs files, just insert it directly into the AST.

@catamorphism
Copy link
Contributor

Rather than baking this in as a syntax extension, I think this could be a good test for rustpkg's custom build logic. As such, it's blocked on #5677.

@emberian
Copy link
Member

emberian commented Jul 7, 2013

Still relevant

@catamorphism
Copy link
Contributor

The major sub-bugs of #5677 are done, so this is ready to work on.

@huonw
Copy link
Member

huonw commented Dec 8, 2013

cc #10530 (the converse operation; generating a C header from a Rust file), and some keywords (since I couldn't find this issue when opening that one): C header, C library, libclang, clang.

@thestinger
Copy link
Contributor

I'm nominating this because I think hard-wiring the ABI of C libraries is a huge problem. Rust libraries are going to silently fail across library versions with breaking changes to the ABI. If we had this, using C from Rust would be as easy as from C++. It would be a killer feature of the language in my opinion.

I don't think it would be incredibly difficult to move bindgen into the Rust compiler proper and start hooking it up to resolve.

@emberian
Copy link
Member

I agree.

@metajack
Copy link
Contributor

In theory this sounds great. How do you deal with unions? Will the bindgen do the right thing with * vs. *mut? Servo basically uses bindgen as an initial thing just so we don't have to type everything, but it doesn't seem capable of generating the final bindings in all cases.

Not to mention that you can't handle C macros, which must be shimmed.

@huonw
Copy link
Member

huonw commented Jan 25, 2014

How do you deal with unions?

rust-bindgen currently converts

union Foo {
  int x;
  char y;
  double z;
};

into

use std::libc::*;
pub struct Union_Foo {
    data: [u64, ..1u],
}
impl Union_Foo {
    pub fn x(&mut self) -> *mut c_int {
        unsafe { ::std::cast::transmute(::std::ptr::to_mut_unsafe_ptr(self)) }
    }
    pub fn y(&mut self) -> *mut c_schar {
        unsafe { ::std::cast::transmute(::std::ptr::to_mut_unsafe_ptr(self)) }
    }
    pub fn z(&mut self) -> *mut c_double {
        unsafe { ::std::cast::transmute(::std::ptr::to_mut_unsafe_ptr(self)) }
    }
}

Of course, if it were built into the compiler we could have first class FFI unions.

Will the bindgen do the right thing with * vs. *mut?

If the C headers are const-correct, I believe it does approximately the right thing.

Not to mention that you can't handle C macros, which must be shimmed.

We can do a best effort thing, aiui libclang offers sensible handling of macros (I don't know the details).

@thestinger
Copy link
Contributor

@metajack: A basic implementation will remove 100% of the ABI hard-wiring for libraries designed with FFI in mind like sqlite3 and libgit2. It's true that it will never be perfect for many libraries, but it will certainly vastly reduce the redundancy on the Rust side and therefore the risk of silent breakage with different versions or even configurations of the library.

@pnkfelix
Copy link
Member

Not as high a priority as it seemed 2 years ago. P-low.

@huonw
Copy link
Member

huonw commented Apr 15, 2014

This could probably be done as an loadable syntax extension now that we have them, e.g.

#[phase(syntax)] extern crate bindgen;

#[bindgen("foo.h")] // fills the module with the appropriate `extern` block
mod foo {}

@ghost
Copy link

ghost commented Apr 25, 2014

Vala does this correctly. Of course they cheat by compiling to C, but the interface is nice.

@brson
Copy link
Contributor Author

brson commented Jan 13, 2015

I don't feel as passionately abut integrating a C compiler into our Rust compiler any more. It doesn't feel very pressing, can probably done out-of-tree through Cargo eventually. Closing but feel free to reopen if you disagree.

@brson brson closed this as completed Jan 13, 2015
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-frontend Area: frontend (errors, parsing and HIR) C-enhancement Category: An issue proposing an enhancement or a PR with one. P-low Low priority
Projects
None yet
Development

No branches or pull requests

7 participants