openSUSE:LTO
Introduction
Link Time Optimization (LTO) gives GCC the capability of dumping its internal representation (GIMPLE) to disk, so that all the different compilation units that make up a single executable can be optimized as a single module. This expands the scope of inter-procedural optimizations to encompass the whole program (or, rather, everything that is visible at link time). That typically improves speed of an executable and better dead code elimination is responsible for smaller binaries and debug info. The LTO has been developed for quite some time and we as toolchain team believe it is mature enough to be used in production.
LTO enablement in openSUSE:Factory
We would like to enable LTO in project settings, specifically $optflags
, where new RPM macro %{_lto_cflags}
will be added. The macro expands to -flto=N
, where N is number of jobs and it is useful for parallel LTO linking. The $optflags
are automatically expanded to CFLAGS and CXXFLAGS, or accepted by an autoconf replacement like cmake. That will enable LTO in most of the packages that use the GCC compiler.
Based on our experiments there will be packages that can't currently be built with LTO by default. We expect the number of such packages will not extend 5%. We will create openSUSE bugzilla entries for the problematic packages and a brief analysis will be provided. The most common issues will be collected in this WIKI page.
LTO disablement
SPEC file
Disablement of the LTO is very simple. One needs to add %define _lto_cflags %{nil}
into a SPEC file. It is possible to do this only in a certain part of the SPEC file (for example, only in the %check
section).
prjconfig
To disable LTO in a project, add the following to your project config
Macros: %_lto_cflags %nil :Macros
NOTE: This is not recommended way of disabling LTO as it only affects the current project and will not carry over to another project when the package is submitted there.
Reproducing LTO build failures
Right now there is not a staging project where the failure can be seen. However, one can easily add following line to a SPEC file in order to enable LTO:
%global optflags %optflags %{_lto_cflags}
Package build failure FAQ
Symbol versioning
Starting from GCC 10.1 release, symbol versioning is supported as a function attribute.
GObject Introspection
A GNOME package can fail due to following issue. The issue is still under investigation. Sample error message:
Invalid GType function: 'ostree_async_progress_get_type' Failed to find symbol 'ostree_async_progress_get_type'
Static libraries
Some packages ship a static libraries that are made of an archive. The libraries contain of just LTO bytecode and should not be shipped. One should use -ffat-lto-objects
and brp-check-suse
strips the LTO bytecode.
In most cases, the easiest to achieve this is by adding, somewhere near the top of the .spec file:
%global _lto_cflags %{?_lto_cflags} -ffat-lto-objects