Commit Graph
5 Commits
Author SHA1 Message Date
Ivan Grokhotkov (bot)andClaude Opus 4.8 d20a986999 feat(build): add options to enable link-time optimization (LTO)
Link-time optimization (LTO) lets the compiler inline and optimize across
translation units. ESP-IDF relies heavily on linker-script placement rules
that match object files by name, which LTO does not preserve, so LTO cannot
be enabled for the whole framework. This change adds two opt-in options that
side-step that conflict:

- CONFIG_COMPILER_LTO_LINKTIME tells the linker to perform LTO on any object
  files that carry LTO information (compiled with -flto). On its own this is
  safe: users can add -flto to specific components (e.g. their own libraries)
  to shrink them, without affecting components that use linker fragments.

- CONFIG_COMPILER_LTO_COMPILETIME automatically compiles most
  components with -flto. A component is excluded when it has its own linker
  fragments, when it opts out via the NO_LTO component property, or when its
  object code is placed by *another* component's linker fragment (matched by
  archive name). The last case is handled by tools/cmake/lto.cmake, which
  scans linker fragments for explicit "archive: libNAME.a" placement and
  excludes those components. Without it, functions that must run from IRAM
  while the flash cache is disabled (e.g. the spi_flash / GDMA HAL routines,
  placed in IRAM by spi_flash/esp_driver_dma fragments) would be moved to
  flash by LTO and the device would panic with a cache error at run time.

Both options are disabled for the bootloader and ESP-TEE builds, which depend
on object-file-name based placement. LTO is also gated off for Clang
(needs LLD, IDF-8286) and host builds.

LTO works together with CONFIG_APP_REPRODUCIBLE_BUILD, but needs extra
flags: LTO defers code generation and most debug-info emission from compile
time to link time, where the reproducible-build path remapping (applied to
compile_options only) does not take effect. When both options are enabled,
three extra flags keep the .elf, .bin and .map byte-identical across build
directories (verified on esp32 / GCC 16.1):

- the -f*-prefix-map options are passed to the linker as well, so the LTO
  code generator remaps DW_AT_comp_dir (otherwise the build dir leaks into
  .debug_str, and cascades into esp_app_desc_t.app_elf_sha256 in the .bin);
- -save-temps makes lto-wrapper use stable LTRANS object names in the build
  dir instead of random $TMPDIR paths that leak into the .map;
- -frandom-seed=1 makes LTO GIMPLE bytecode objects byte-identical (a
  shared seed was verified not to collide, including for C++ file-local
  static variables and anonymous namespaces promoted by LTO).

The gcc-ar / gcc-ranlib wrappers are selected in the GCC toolchain file so
that the LTO plugin is loaded when creating and indexing static archives;
plain ar/ranlib do not record LTO symbols in the archive index.

Note: LTO, like other inlining, can also increase binary size. Enable it
together with CONFIG_COMPILER_OPTIMIZATION_SIZE to get a code-size benefit.

Related: IDF-71, IDF-8286

Closes https://github.com/espressif/esp-idf/issues/18741

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-14 18:59:46 +02:00
Jakub Kocka 2e5d930e6b fix(tools): Windows builds when paths contain spaces (prefix_map, ldgen, CI)
- Harden prefix_map.cmake for paths with spaces on Windows

- ldgen: fragments-list-file, list normalization, CMake integration (tools/cmake + cmakev2)

- CI exclude list for check_tools; test_spaces bundle tweak

Made-with: Cursor
2026-06-04 14:45:05 +08:00
Alexey Gerenkov 97e6873e34 feat(tools): update esp-clang version to esp-21.1.3_20260304 2026-05-07 17:42:32 +03:00
Alexey Lapshin 338cc50125 fix(build): fix passing CMAKE_<LANG>_FLAGS from ExternalProject_Add 2026-03-13 17:23:11 +08:00
Alexey Lapshin 0c1d917f78 feat(build): propagate compiler flags from files to toolchain.cmake
This change improves build consistency across external projects integrated
through CMake by ensuring that compiler flags defined in configuration files
are passed correctly to the toolchain. It covers the majority of use cases,
as external projects are typically also CMake-based. For projects that use
a custom build system, users will still need to specify the required flags
manually.
2025-11-14 21:04:54 +07:00