Skip to content

implement Clone on Builder #2132

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

Closed
jrandall opened this issue Dec 9, 2021 · 1 comment · Fixed by #2302
Closed

implement Clone on Builder #2132

jrandall opened this issue Dec 9, 2021 · 1 comment · Fixed by #2302

Comments

@jrandall
Copy link

jrandall commented Dec 9, 2021

I have a use case in which I would like to invoke rust-bindgen multiple times. Once with generate_comments(false) and once with generate_comments(true) -- the use case here is that the C header file has comments annotating the run-time version required for a particular struct field to have been added. This is for a sqlite extension that we want to build against a new version of sqlite headers (e.g. sqlite3ext.h but then have runtime detection of version in order to make it safe to load the loadable extension into an older version of sqlite.

I have this working (using some syn parsing of the AST that rust-bindgen generates to process the fields and their comments). However, I would very much like to be able to write code like this:

let mut bindings = bindgen::builder()
           .trust_clang_mangling(false)                                                                                |
            .header(header.clone())                                                                                     |
            .parse_callbacks(Box::new(SqliteTypeChooser))                                                               |
            .rustfmt_bindings(true);
            
 // lots of conditional code that updates `bindings` with different clang args, etc in different situtaions
 
 let bindings_with_comments = bindings.clone().generate_comments(true);

// actual invocations of `bindings.generate()` and `bindings_with_comments.generate()`

However, I find that the bindgen Builder does not implement Clone (it appears that it used to as of 0.19.1 but has not for some trime: https://docs.rs/bindgen/0.19.1/src/bindgen/.cargo/registry/src/jiasu.xzqcsaa.nyc.mn-1ecc6299db9ec823/bindgen-0.19.1/src/lib.rs.html#42).

As a result of not being able to .clone(), I find that I am having to write something like this:

let mut bindings = bindgen::builder()
           .trust_clang_mangling(false)                                                                                |
            .header(header.clone())                                                                                     |
            .parse_callbacks(Box::new(SqliteTypeChooser))                                                               |
            .rustfmt_bindings(true);
let mut bindings_with_comments = bindgen::builder()
           .trust_clang_mangling(false)                                                                                |
            .header(header.clone())                                                                                     |
            .parse_callbacks(Box::new(SqliteTypeChooser))                                                               |
            .rustfmt_bindings(true);
            
 // lots of conditional code that follows every update to `bindings` with an identical update to `bindings_with_comments`
 
// actual invocations of `bindings.generate()` and `bindings_with_comments.generate()`

I've explored a bit if there are alternatives to this but struggle to find anything that doesn't involve essentially duplicating hundreds of lines of code.

It feels like the right solution is to implement Clone on bindgen Builder -- is there a good reason not to do this, or is it simply that no one has presented a use-case for it to date?

@pvdrz
Copy link
Contributor

pvdrz commented Oct 7, 2022

We are very close to fix this. Maybe I'll split #2292 into two so this gets fixed quicker.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
2 participants