Commit Graph
8 Commits
Author SHA1 Message Date
Ivan Grokhotkov (bot)andClaude Fable 5 b3a0e166fe feat: add compile_options support to idf.py build-file
Allow specifying extra compiler flags (warning flags, preprocessor
definitions, etc.) via a new 'compile_options' entry in the
idf-build-file frontmatter. The options are applied to the source
file via target_compile_options in the generated main component
CMakeLists, with CMake quoting so that flags like -DMSG="hello world"
reach the compiler exactly as written.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-21 22:04:41 +02:00
Ivan Grokhotkov (bot)andClaude Opus 4.8 4c25d4e9ab docs(performance): mention LTO in the optimizing-for-size guide
Document CONFIG_COMPILER_LTO_LINKTIME / CONFIG_COMPILER_LTO_COMPILETIME in the
binary size reduction guide, including the caveats: less accurate per-component
size breakdown, longer build times, incompatibility with custom linker
fragments, and harder debugging.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-14 19:32:19 +02:00
Ivan Grokhotkov (bot)andClaude Opus 4.8 5e192672a2 ci(system): add startup test config with LTO enabled
Add an opt_os_lto configuration to the startup test app that enables size
optimization together with link-time and compile-time LTO, and run it across
the supported targets so the LTO build is exercised on real hardware in CI.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-14 19:32:19 +02:00
Ivan Grokhotkov (bot)andClaude Opus 4.8 8fde15f837 fix(bootloader_support): disable LTO due to linker script rules
bootloader_support relies on linker-script placement that depends on object
file names, which LTO does not preserve. Set the NO_LTO component property so
it is excluded from compile-time LTO.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-14 19:32:19 +02:00
Ivan Grokhotkov (bot)andClaude Opus 4.8 351abea682 fix(esp_attr): avoid section type conflicts in DRAM_STR under LTO
DRAM_STR placed its backing string in a variable named __c in a section named
after DRAM_ATTR's __COUNTER__ value. Under LTO, when translation units are
merged, two such variables from different units could collide on the same name
and section, producing a "section type conflict" error.

Derive both the variable name and a dedicated .dram1.str subsection from a
single __COUNTER__ value so each DRAM_STR expansion is unique after merging.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-14 19:32:19 +02:00
Ivan Grokhotkov (bot)andClaude Opus 4.8 493a770d40 feat(build): support LTO in the build system v2 (cmakev2)
Mirror the link-time optimization support into the cmakev2 build system so
that both build systems behave identically.

- project.cmake (__init_project_configuration): emit -flto=auto as a link
  option when CONFIG_COMPILER_LTO_LINKTIME is set, except for bootloader and
  ESP-TEE builds, otherwise keep -fno-lto.

- build.cmake (idf_build_library): when CONFIG_COMPILER_LTO_COMPILETIME is set,
  compile each linked component with -flto=auto unless it has linker fragments,
  is placed by another component's fragment (see tools/cmake/lto.cmake), has
  opted out via NO_LTO, or is not a static library.

- project.cmake: when CONFIG_APP_REPRODUCIBLE_BUILD is also enabled, apply
  the same three flags as the legacy build system to keep LTO output
  reproducible: pass the prefix-map options to the linker (so link-time code
  generation remaps DW_AT_comp_dir), add -save-temps (stable LTRANS object
  names instead of random $TMPDIR paths in the .map), and pin -frandom-seed
  (byte-identical LTO GIMPLE bytecode). See the commit message of
  "feat(build): add options to enable link-time optimization (LTO)" for the
  full analysis.

The gcc-ar / gcc-ranlib selection and the NO_LTO component property are shared
with the legacy build system through tools/cmake/toolchain.cmake and the common
component registration code, so no cmakev2-specific changes are needed there.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-14 19:32:19 +02:00
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
Ivan Grokhotkov (bot)andClaude Opus 4.6 20b9e06e92 ci: add API compatibility check job for merge requests
Add a check_api_compatibility CI job that uses esp-api-check to detect
breaking API changes in merge requests. The job compares API
declarations between the MR base and head commits using libclang, and
posts a discussion thread on the MR if WARNING or BREAKING changes are
found.

- Add CI job in host-test.yml with clang toolchain and allow_failure
- Add test_api_check project for CMake configuration with all
  components enabled
- Define __DOXYGEN__ and IDF_DOC_BUILD so the checker can see
  declarations behind these guards

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-06 17:12:40 +01:00