GNOME Bugzilla – Bug 727798
reduce size of sparsely-used libgio under static linking
Last modified: 2018-05-24 16:24:39 UTC
Hi, attached patch adds a configure parameter to allow disabling GApplication, GMenu and related API. These are all useless on Android and iOS, and only marginally useful on OS X and Windows, and even on Unixes that don't run GNOME. If this patch is accepted I'm also going to prepare more patches that allow disabling GSettings, GDBus, xdgmime, GResource and GRegex. Reasoning for this is that all of these are not useful and use quite a bit of space. By removing all this I was able to get the size of an Android app down by about 1MB compressed size per architecture. If you worry about maintainability of many little parameters to disable subsystems I would also be fine with grouping them into a --disable-gnome (for all but GRegex, I'm also open for better suggestions for the name) or making them be removed automatically for non-Linux targets. If you worry that nobody is ever going to test these things, we run buildbots for GStreamer on all supported platforms (Linux, Windows, OS X, Android and iOS).
Created attachment 273764 [details] [review] 0001-Allow-disabling-GApplication-GMenu-and-related-API.patch
I'm not interested in this. Even less so if you call it --disable-gnome
It would be extremely useful for GStreamer, where we (and the application writers) only need limited functionality from gio for many platforms, and binary size is an important consideration for deployments on these platforms. Could you suggest a way forward, how we can make this more acceptable?
I sort of expected something like this to be necessary at some point given: 1) The extremely widespread use of GLib 2) The growth of its APIs 3) The fact that on Android and iOS we can't actually be shared And point #3 sucks, there's nothing we can do about it. I think ultimately what we should be providing here is not one or 5 configure arguments necessarily, but an easy framework for people to tweak it, since ultimately it will be per app. Hmm. You know the systemd people use -ffunction-sections and -fgc-sections to effectively have the linker traverse the callgraph and do this for you, automatically per app. That way if you do happen to use GRegex, it'd be available. Now when you say GRegex is useless, do you mean if for example you're using the framework-native regex API? Oh I just reread comment #3, you basically want only the APIs used by GStreamer? If that's all we want, then I would call it --enable-embedded-mode=gstreamer or something?
The problem with -fgc-sections is that it's not doing much here because e.g. giomodule.c is calling the _get_type() functions of GApplication and other stuff... effectively pulling it all into the final shared object. Or gboxed.c doing the same for GRegex by referencing its copy/free functions. (In reply to comment #4) > Now when you say GRegex is useless, do you mean if for example you're using the > framework-native regex API? Well, ignore the "useless" bit for GRegex, that was more about GApplication, GMenu, GDBus, GSettings :) For GRegex that's really a per-application thing, some might need it some don't... and we even have some GStreamer plugins using GRegex. But there are still enough applications that don't use GRegex at all but link it (and pcre) in.
(In reply to comment #5) > The problem with -fgc-sections is that it's not doing much here because e.g. > giomodule.c is calling the _get_type() functions of GApplication and other > stuff... effectively pulling it all into the final shared object. > Or gboxed.c doing the same for GRegex by referencing its copy/free functions. Note that -fgc-sections only removes complete .o files, so once you use one symbol from a .o file the complete .o file is included.
I'm quite happy to entertain suggestions for things that will improve the usefulness of gc-sections under static linking. The idea of something like libgapplication also interests me a bit, but it's very unclear where we should draw the line. GDBus as well? How about some of the more esoteric stream types (compress, convert, etc)? Desktop file handling? Network monitor? TLS and proxies? If we can find a way to make section-gc effective for static-linked applications then we should seriously explore that. It will allow automatic pruning in a much more-useful way than setting arbitrary boundaries between what we think are related classes of functionality for one usecase, only to have someone else come along and complain because they need one item from "group B" but none of the others.
So let's take a look at how we can change GLib to make more efficient use of -gc-sections in combination with -ffunction-sections and -fdata-sections instead.
(In reply to comment #5) > The problem with -fgc-sections is that it's not doing much here because e.g. > giomodule.c is calling the _get_type() functions of GApplication and other > stuff... OK... so to fix that, we'd have to get rid of _g_io_modules_ensure_extension_points_registered() and _g_io_modules_ensure_loaded() and make extension-point initialization be lazy/distributed, with each extension point being registered from its _get_default() function or equivalent. giomodule.c already seems to be able to handle this without needing to change the way that we actually load the modules; if it loads a module and finds that the module implements an extension point that hasn't been registered, it just waits to initialize the module until that extension point does get registered. (If we are reorganizing giomodule handling, we should also make sure to address the static giomodule case, which would imply that actually you don't want the _get_default() function to do the lazy registering directly. Rather, you'd have, eg, g_tls_backend_register_extension_point(), and g_tls_backend_get_default() would call that, but you could also call it manually, and then register your own static GTlsBackend implementation, and then call g_tls_backend_get_default()). > Or gboxed.c doing the same for GRegex by referencing its copy/free functions. I think that could be fixed by having the G_DEFINE_BOXED_TYPE() invocations in gboxed.c for the large/"optional" types each be in their own section? Then if you never use G_TYPE_REGEX, then the section of libgobject containing g_regex_get_type() won't get pulled in, and so the section of libglib containing GRegex won't get pulled in.
See also, bug #793256. As I said there, the availability of CI for platforms which would use this (like Android/iOS) would make supporting it in GLib a lot more feasible.
-- GitLab Migration Automatic Message -- This bug has been migrated to GNOME's GitLab instance and has been closed from further activity. You can subscribe and participate further through the new bug through this link to our GitLab instance: https://gitlab.gnome.org/GNOME/glib/issues/854.