Differences between revisions 2 and 3
Revision 2 as of 2019-04-18 08:49:58
Size: 3401
Editor: ?Fabio
Comment: update links and fix a typo
Revision 3 as of 2019-04-26 20:24:30
Size: 3401
Editor: ?Fabio
Comment: typo
Deletions are marked like this. Additions are marked like this.
Line 27: Line 27:
 * Add all CLFAGS/CXXFLAGS to LDFLAGS, including the -flto  * Add all CFLAGS/CXXFLAGS to LDFLAGS, including the -flto

Link Time Optimization

LTO abbreviates Link Time Optimization (or Link Time Optimisation for some). This page gives a quick rough summary on what to expect from it, how to get it into your Debian packages, and why (or why not) to go for it.

LTO grants the compiler the opportunity to see more than a single .o file at a time. This grants extra freedom for the optimisation that yields:

  • reduced code size (seen binaries down to 40%, but expect some 5-20% reduction)
  • increased execution speed (hey, there is less code for the same thing, how much faster depends on how the application, obviously)

The reduced code size is a good control to learn if the LTO truly kicked in. Sidenote: All other optimisation flags still apply.

Downsides of LTO are

  • increased compile time
  • bit of extra effort to get the parameters right
  • unclear compatibility with other compilers than gcc/g++
  • it is not so very wide-spread, you may run into compiler errors (or not notice them, which would be worse). There is a thread on Debian Devel collecting experiences (https://lists.debian.org/debian-devel/2016/03/msg00399.html) and opinions that yet speak against its wider utilisation in Debian. Particularly when doing tricky bits as in the Linux Kernel (https://lwn.net/Articles/512548/) you should be careful. Well, the maintainers decide for themselves and we have the experimental section when in doubt. It is all routine for the GCC developers now (https://gcc.gnu.org/wiki/LinkTimeOptimization).

  • it may not always work (e.g. http://www.phoronix.com/scan.php?page=article&item=gcc_471_lto&num=2) but this is 5 years ago and the sizes of binaries are not mentioned as a check that LTO had kicked in. Find problems with how parameters are passed to the linker if binaries do not get smaller. One rarely gets it right at the first attempt. There is little to no reason why more freedom to optimize should get something worse.

How to get LTO into your Debian packages

There is only one weird thing: The compiler still compiles when you think it should be linking. This is why you pass the compile time flags (like -O2 etc.) also at link time. Here a recipe that seems to work:

  • Add -flto CFLAGS and/or CXXFLAGS depending
  • Add all CFLAGS/CXXFLAGS to LDFLAGS, including the -flto
  • Redirect linker, ranlib and ar

    CFLAGS="-flto ${CFLAGS}"
    LD=gcc
    LDFLAGS="$(CFLAGS) ${LDFLAGS}"
    AR=gcc-ar
    RANLIB=gcc-ranlib

Frankly speaking, there is apparently the same effect by just adding -flto to the LDFLAGS, not the whole $CFLAGS. Anyway - that is why this is a wiki, please add your piece of wisdom to this page. For ideas how to integrate the environment variables into the build have a peek at this wiki's Hardening page.

Examples: