This is a small update while I hammer out a much larger blog post (which has proven to be a little harder than normal to write).
Much of the start of this project was spent ensuring that that foundations required for doing a Rust conversion were available or worked. This involved many such things as;
- Using autotools and Makefiles to build Rust code, plus rebuild if files were changed
- Generation of bindings to C libraries (eg, GLib)
- Work on any of the tooling needed to generate the bindings (in my case, gtk-rs/gir)
- Manual writing of bindings in the case that use of generators wasn't possible
- Writing an safe API layer over any raw bindings
There's really a lot of work I hadn't anticipated. I ended up contributing to the
gir program which generates bindings for from G-IR files - at first adding the ability for it to generate good bindings for rust Unions (basically untagged rust enum) to match C style Unions, behind a feature gate as it relied on nightly Rust. Unions have since been stabilised and added in to the most recent stable (v1.19) Rust compiler release, and myself along with Sebastian Droege have further improved that side of things. I am now currently working on removing the feature-gating so that the Union code is generated with stable Rust (there are some small issues).
I discovered during some work with converting the JS->FFI code in GJS that the gir files for gobject-introspection lacked many important functions. To rectify this I decided that rather than work to export them as raw bindings, I rewrote those library functions in Rust. That was an interesting journey (and the topic of my next post in progress), I think I was able to write some good safe code this way - it uses the raw bindings for libffi and some GLib and girepository stuff, but these raw, unsafe calls are behind safe functions that basically mirror the original C functions in behaviour, and accept the same parameters though I've witten them to be used in pure Rust (i.e, not exported as C style). There is still a small amount of work to do on this part as I really need to propagate errors up and in one case decide what to do about using an
GError or not - that particular problem may solve itself later.
There are two main goals here now, and working towards both is fascinating;
- Converting C to Rust to aid safety
- Using what is learned in the process to help improve the current C/C++ code
Improving the existing C/C++ code is still a desired goal since the viability of a full-scale Rust conversion is a while off yet, and there are quite a few lessons to learn from Rust that can be applied to C++ (also a topic of my next post, but may split that out).
Oh, yeah, there is still one other thing that is still a bit of a blocker on full decent Rust to C interation, and that is bit-fields within structs; currently Rust does not have the ability to lay out a struct in the same way as a C-style struct that contains bit-fields or a mixture of those + other types. Theres is and RFC to add this, but there are some issues with it. I'm considering adopting it to try and get it over the finish line.
I also updated my jekyl powered blog with a new theme to make it much more readable. And also enabled comments. Enjoy!!