Improve footprint by allowing element selection during static link stage
This MR intends to alleviate
gst-full library by splitting the plugin into elements and add these elements to a static plugin removing all the unnecessary code from non selected elements.
By reorganizing the code after declaring all the individual element (GST_ELEMENT_REGISTER_DEFINE) from a plugin, the dead code path (elements not selected and their code dependencies) will be removed. It will result in a smaller gst-full library containing with only the set of libs and the set of plugins/elements selected.
This MR depends on other MRs to demonstrate the mechanism:
gstreamer!661 (merged): Where new defines have been introduced to declare a single element and a demonstration of the split in coreelements.
gst-plugins-base!900 (merged): With an advanced use of this mechanism (put common method in a separate file) and use of
With ELF format compilers, linkers are able to drop dead code which are not used. We could use -gc-sections linker flag but the result might be unpredictable (see below).
Two concepts have been introduced:
- Declare all elements to be registered by another plugin
- Separate the code to avoid full object inclusion when only one method from an object is necessary
That's why I introduced first in
gst/gstelement.h the macros to declare the elements.:
GST_ELEMENT_REGISTER_DEFINE(element,name,rank,type): Declare a method containing gst_element_register with a element decalration as before(name,rank etc.). This method will be called with a given plugin, ie
gst_init_static_plugins()generated by gst-build in
GST_ELEMENT_REGISTER_DEFINE_WITH_CODE(element, name,rank,type, code): Declare a method which call
another piece ofinit_method`. This method usually calls a common init (once) and gst_element_register (see alsa or playback in gst-plugins-base!900 (merged))
GST_ELEMENT_REGISTER_DEFINE_CUSTOM(element, method): This method allows to create the gst_element_register method and call directly a method instead of defining the method with rank, type etc. See playbin3 in gst-plugins-base!900 (merged)
Then in gst-plugins-base!900 (merged) I put the common element_init method in a separate file from plugin.c to gstpluginnameelement.c to avoid dragging all the code from the other plugin's element and use the rule for the linker by separating the code in individual objects:
=> If there is one method from an object necessary, all the methods from the object will be kept.
Then I created a gstpluginnameelement.c(optional) containing the common init method and gstpluginnameelement.h(always) containing the
GST_ELEMENT_REGISTER_DECLARE macros for all the elements of a plugin.
With this approach we avoid to use gc-sections and -ffunctions-section -fdata-section where the benefits can be undefined:
Only use these options when there are significant benefits from doing so. When you specify these options, the assembler and linker create larger object and executable files and are also slower. You cannot use gprof on all systems if you specify this option, and you may have problems with debugging if you specify both this option and -g.
On gst-build side, the only change here is to introduce
gst-full-elements option which will allow to select the elements from a given plugin and generates
In gst-full only these elements will be present:
coreelementsplugin with all his elements
decodebinfrom playback and
alsasinkfrom alsa in a plugin named
example to demonstrate the gain. Here if we are
meson build-gst-full -Ddoc=disabled -Dintrospection=disabled -Dtests=enabled -Dpython=disabled -Dbuildtype=release -Ddefault_library=static -Dgst-full-version-script= -Dgst-full-elements=coreelements:filesrc,fakesink,identity '-Dgst-full-libraries=' -Dbad=disabled -Dugly=disabled -Dffmpeg=disabled -Dlibav=disabled -Dbase=disabled -Dgood=disabled -Dbackend=ninja
Here is some numbers where only filesrc, identity and fakesink are enabled:
- before any mods in gst repos (except removing base and good from the build, see commit): build without
-Dgst-full-elements=coreelements:filesrc,fakesink,identityin the meson command line.
- Final build with command line above.