gtk-rs/gtk

Building gtk-rs runs out of memory on 2GB device, which I think means compiling any basic graphical app won't work there

ell1e opened this issue · 18 comments

ell1e commented

So I am using a PinePhone, a 2GB linux phone, where I occasionally also do some dev stuff on the run which saves me a laptop. I usually don't really touch rust, or much of phone-specific libraries, which is why when I wanted to build the phone's graphical on-screen keyboard it seemed natural to do it on-device: the detailed reasons were that with that approach I don't need to figure out cross-compilers to ARM64, and I won't otherwise really touch much of this on-screen keyboard anyway so kinda keeping the super device specific on-device seemed cleaner to me.

However, building it I ran into a roadblock: https://source.puri.sm/Librem5/squeekboard/-/issues/243 it appears that building gtk-rs runs out of memory on 2GB device, which I think means compiling any basic GTK+ graphical app won't work there at all. That seems like a bit of a potential issue:

oom

If this is ultimately a rustc optimization issue, I'd be happy to forward the ticket there. Also I hope I found the right bugtracker here for the rust gtk module, if not let me know and I'd be happy to reopen this ticket in the right place.

The solution there is cross-compilation. The rust compiler uses a lot of memory when running, which is an issue (my raspberry 3 cannot use rustc directly, I cross-compile to it for example). I show an example on how to cross-compile to raspberry here, I guess it's not very different for the pinephone.

As for the rust compiler using too much memory, well, it's not a known issue but luckily, the cross-compilation is pretty easy to use there.

ell1e commented

Yes but cross compilation means I can't e.g. compile on the phone itself when I'm on the train. I often don't bring my laptop anymore since it's not that required, and most trains have power outlets here so I don't really mind the power consumption of compilation either. Of course this isn't that useful as a full time dev where this compiling is way too slow, but for some hobby stuff on the side this is very convenient. And some people just starting out in some poorer neighborhoods might only have a raspberry pi to work on, should they never use rust for graphical applications then? So to me this seems a little unfortunate.

Is there an upstream ticket to track this yet? I think it's unfortunate that any GTK+ app dev in rust will be impossible on lower spec devices due to this. (Rather than just inconvenient with expected long compilation times, I understand those cannot be magically avoided in any case.)

Cross compilation is pretty common for any embedded development, even in C/C++. So not sure...

ell1e commented

Raspberry pi 2 and newer really doesn't usually count as an embedded platform I don't think. Pretty sure it's a somewhat common entry level device for teenagers and other new tinkerers especially from poorer backgrounds since it is so cheap, often used for python programming on device (I think "pi" even refers to python? I forgot) with a real desktop environment. And at least until recently, 4GB memory was also pretty common for an entry level laptop. Not everyone has a powerful rig, and requiring >2GB for compilation for a regular graphical app seems surprising to me even on a 4GB machine.

Is it really just me who finds it bewildering that with 2GB memory it's not possible to compile a simple GTK hello world app in rust? I'm not from the rust world, to be fair, so I find it even more bewildering that you seem to have just accepted that as the "new normal". I guess if that is what everyone using rust agrees on, who am I to judge. But from the outside looking in this seems really like something that should be addressed to me.

You might get lower memory usage by using fewer codegen units.

ell1e commented

Would this be something to be addressed in the downstream application I reported this from, that is the squeekboard on-screen keyboard I tried to compile?

Also I feel like it wouldn't hurt to poke rustc people about this as well, unless this is an inherent issue somehow caused by and fixable in gtk-rs itself. But from the reactions in chat and here it appears to be common that rustc needs a lot of memory, and not that project-related. So I feel like maybe I should make a rustc issue ticket...?

I think this will have to be reported to rustc itself as a first step. gtk-rs could improve the memory usage by providing a less convenient API. To some degree it could probably also be improved without sacrificing usability, but in the end it's something that has to be improved in the compiler.

ell1e commented

Okay, thanks for the info! I forwarded the ticket to here: rust-lang/rust#78308

Hi. I'm the maintainer of Squeekboard, and gtk-rs has been the number one crate giving us trouble in terms of compile-time resource usage. The other problem is taking several minutes compiling for arm64.

While I agree that the problem is partially with rustc and its unreasonable resource usage, in practice this creates a pressure on the downstream maintainer (in this case me) to justify choosing rust/gtk-rs, when the cost is that CI pipelines time out, fellow developers have extended edit/compile/run cycles, or can't even build it on the target device.

Since gtk-rs is a big part of it, I must consider going back to C for GTK, or splitting gtk-rs up into parts, which contain only what I'm using. Of course, that is not beneficial to gtk-rs in any way.

From a practical perspective, I would like to ask about what we can do in the other parts of the stack while we wait for rustc to catch up with the world:

Where does this extra load come from on the gtk-rs side? Is it because of a lot of templating? What are the smallest changes to the API that yield the biggest advantage? Would splitting into more crates achieve anything?

It's the huge number of types in gtk and the number of traits that come together with those. I think a practical approach that would make things not too bad for users would be to add cargo features to explicitly enable specific parts of the API (and have all enabled by default).

Thanks. I can to allocate some time for a features attempt towards the end of the year.

I'm not a GTK expert… is there a preferred way to slice the features, or should I just try whatever gives good results?

I have no idea really, someone would have to look at this and try to group things in a useful way. I don't really use GTK myself :)

Neither do I (what kind of people are we for maintaining GUI stuff if we don't do GUIs?! 🤣 ). Do you have any ideas how we could split things @ebassi?

Not really. GTK is a complete API, and we have historically resisted any call to slice and dice it (and GLib) up for constrained environments—especially if it's just a side effect of a build-time issues on certain languages.

I honestly don't even know how would you go about it, to be fair; leaf widgets are probably something that can be ignored, unless they are containers? Maybe the file/color/application selection widgets? Or the printing API?

ell1e commented

Maybe it would make sense to poke and find out how quickly this could possibly be addressed in rustc? (Edit: I mean also from a practical side, like whether there is manpower for this in the near future at all for this sort of problem) Fwiw I just hoped it would get addressed in the medium to longer term personally, although from @dcz-purism 's remarks it sounds like it's a somewhat acute problem for some people right now. I don't want to stop anyone from any intermediate solutions of course if you want to do them, just my two cents

I don't really know what would be needed on the rustc side. I never tried to hack on it yet, but considering how often I see people complaining about build times, I suspect that low hanging fruits have been picked there.

ell1e commented

Hm but I do wonder if that is also the case for the memory usage? Although if the CI timeouts impact you more, I understand that is possibly not your main concern. For on device builds however I feel like memory really is the main issue.

Limiting compilation unit size is the starting point both for memory and CPU usage. This needs to be tried and then we'll see.