bindgen header, link, etc functions take String instead of Path(Buf)
Probably pretty self-explanatory.
header() and link() (and other functions) on bindgen take Into<String>, even though the examples show them being used with paths (although not Path with a capital P).
I'd think this would be backwards compatible, since PathBuf is supposed to contain a superset of the characters as String.
As an anecdote, I tried to build and generate bindings for a library using cc and bindgen. I've saved the shared root folder of the library as a PathBuf. cc uses AsRef<Path> for it's methods, such as cc::Build::file so a PathBuf works fine, but bindgen uses Into<String>, which means I need to call path.into_os_string().into_string().unwrap() or similar.
As a question for the package maintainers: does using AsRef<Path> make sense for bindgen?
Yes, I think it does, and I think I'd take a PR to update this for the arguments that take a path.
I'm happy to take a shot at this.
Do you think the methods should just take a impl AsRef<Path> and immediately convert them to String (and fail if not convertable) or if the backing data structures should store PathBufs and then convert later, as needed? It seems like at some point we need them in some string-ified form to pass to clang.
Edit: Here is a very non-invasive and naive implementation possibility: https://github.com/tangmi/rust-bindgen/commit/c835325b6ac83bdcad8524800e141d5374460e42
Hmm, yeah, that's a good point... So ideally we'd turn the clang arguments into a bunch of Box<[u8]> or Vec<u8> (so we don't need to turn it into a string) and then pass it to clang, which really wants just C strings (see TranslationUnti::parse in src/clang.rs). Though that may need clang-sys changes as well.
I'll take a peek at it later. Some notes I've made:
Pathcan be converted tostd::ffi::OsStrlosslessly- There's the
std::ffi::CStrtype, which we could use instead ofVec<u8>to represent C strings, though I'm not sure yet how that relates toOsStror toTranslationUnite::parse
@emilio I'm struggling to find a solution that doesn't do a lossy conversion between string types and am looking for advice.
The main issue(s) I am running into are:
PathandPathBufare represented in a platform-specific way (UTF-8 on Unix and WTF-8 on Windows).- These can be converted losslessly to
OsStrandOsString, respectively. - It seems all
strs areOsStrs, but not allOsStrs arestrs
- These can be converted losslessly to
Command::arg[s]takesAsRef<OsStr>, which poses no problem, as we can convertBuilder::command_line_flags,Builder::dump_preprocessed_input, andBuilder::rustfmt_generated_stringto build aVec<OsString>instead of aVec<String>.- I looked at
cc::Build, which basically wraps aCommandthat calls a compiler and builds arguments lists withAsRef<OsStr>.
- I looked at
bindgenusesclang-sys, which takes a*const c_char(orCString).CStr/CStringwork withStr/Stringon all platforms, but not nessecarily withOsStr/OsString(there exists std::os::unix::ffi::OsStrExt::as_bytes on Unix only).
We need data as:
&[u8]for writing to filesAsRef<Path>for use inCommand::arg*const c_char/CStrfor use inclang_sys
From this, it seems that on Unix, we can use AsRef<Path> from user input and convert to the proper string types. On Windows, however, there has to be some lossy conversion (or error propagation) at some point, as we can't guarantee that conversions for 1. and 3. can be done safely.
I'd like to represent Builder and BindgenOptions with PathBuf for the relevant fields, as it seems more semantic than String (or alternatives), but before I go too far down that path, I'd like to know your thoughts on this.
Thanks!
I see three paths here:
- Handle windows via the lossy path:
OsString->String->CStringand return an error when trying to set a clang_arg with anOsStringthat cannot be converted in this way. - Change the unix methods only so they take
AsRef<OsStr>instead and let windows keep usingAsRef<str>andInto<String>. - Leave things as they are right now.
As I'm not a windows developer I wonder what happens if you pass a windows wide string as an argument to clang.