Zephry LTO optimization

Hello!

Code size is quite crucial in our project, naturally CONFIG_SIZE_OPTIMIZATIONS is enabled. In other projects I've experience with LTO (link time optimization), this feature could cut off a few more percents from final binary size. Alas I haven't seen any easily reachable option to activate LTO in Zephyr.

My best guess was the following in CMakeLists.txt:

zephyr_ld_options("-flto")

but the resulting binary size remained the same. I've digged into the build directory and found this in build.ninja:

...
LINK_FLAGS = -gdwarf-4
LINK_LIBRARIES = ... -flto
...

This tells me the build system added -flto to LINK_LIBRARIES instead of LINK_FLAGS. How can I make Zephyr build system use my custom linker flag? Possibly without hacking, the standard Zephyr way is preferred...

Parents
  • There is ongoing work with to enable LTO. Please see PR#11349 - asset_tracker_v2: Enable link time optimization as an example which enables LTO for the application code only. You may try the same technique to get LTO working for the application part of the code.

    What is going on in the mentioned PR is that -flo is passed to the compiler when it compiles the application code. That is what this does:  target_compile_options(app PRIVATE "-flto") and that is done if CONFIG_ASSET_TRACKER_V2_LTO is enabled.

    More about the -flto flag can be found here: https://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html .

    What it really does is that it strips out unused functions from the final executable thereby saving flash space.

    zephyr_ld_options("-flto")

    This only adds the -flto option to the linker stage. The flag should be added to the compile stage instead, as in the PR.

  • I used to have success with LTO in my other projects during the recent years. The required technique usually was to specify -flto both during compile and linking, and at the cost of a much longer linking the resulting binary size was 3-5-7% less than without LTO. In some circumstances this can mean a lot ;)

    I tried the statement found in the PR with more NCS-2.2.0 and NCS-2.4.1 applications, and surprisingly the final binary was usually greater than without LTO!

    Is there any way forcing NCS to use -lflto not only for the application code, but for the rest (Zephyr kernel) too? I'd give it a try...

    Thanks,

Reply
  • I used to have success with LTO in my other projects during the recent years. The required technique usually was to specify -flto both during compile and linking, and at the cost of a much longer linking the resulting binary size was 3-5-7% less than without LTO. In some circumstances this can mean a lot ;)

    I tried the statement found in the PR with more NCS-2.2.0 and NCS-2.4.1 applications, and surprisingly the final binary was usually greater than without LTO!

    Is there any way forcing NCS to use -lflto not only for the application code, but for the rest (Zephyr kernel) too? I'd give it a try...

    Thanks,

Children
No Data
Related