Skip to content

Split the v1 implementation into functional translation units - #331

Merged
lovyan03 merged 1 commit into
m5stack:developfrom
ainyan03:tu_split
Oct 2, 2026
Merged

lovyan03 merged 1 commit into
m5stack:developfrom
ainyan03:tu_split

Conversation

@ainyan03

@ainyan03 ainyan03 commented Oct 2, 2026

Copy link
Copy Markdown
Contributor

Brings the translation unit split of 0.2.32 (#330) to develop.

Why

0.2.30 built the whole v1 implementation as one translation unit. With the esp-2021r2 toolchain (GCC 8.4 / binutils 2.35: arduino-esp32 2.0.x, PlatformIO espressif32 6.x / 7.x) on RISC-V targets such as the ESP32-C3, unused panel and touch code and its data tables were no longer removed by --gc-sections, which added several hundred kilobytes to a firmware that uses a single SPI panel.

The older RISC-V assembler appends the CFI relocations of .rela.eh_frame after the FDE header relocations, so they are not in offset order. When the linker marks the FDE of a used function, it walks relocations from that FDE up to its end without a lower bound, so the last FDE of an object also picks up the out-of-order relocations of the other functions and keeps them. Newer assemblers emit the relocations in order.

Changes

  • Four hubs include the *.inl files of their group: lgfx_v1.cpp (sprite, button, misc), lgfx_v1_panel.cpp, lgfx_v1_touch.cpp, lgfx_v1_platforms.cpp.
  • LGFXBase.cpp, lgfx_fonts.cpp and panel/Panel_M5HDMI.cpp (FPGA bitstream) build on their own (renamed from .inl, only the include guard removed).
  • The ESP-IDF CMake and make lists take the new files. check_inl_sources.py accepts several hubs and standalone sources and rejects an *.inl reached from two hubs.

0.2.30 built the whole v1 implementation as one translation unit
(lgfx_v1.cpp included every *.inl file). With the esp-2021r2 toolchain
(GCC 8.4 / binutils 2.35, used by arduino-esp32 2.0.x and the PlatformIO
espressif32 6.x / 7.x platforms) unused panel and touch code and its
data tables were no longer removed by --gc-sections on RISC-V targets
such as the ESP32-C3, which added several hundred kilobytes to a
firmware that uses a single SPI panel.

The older RISC-V assembler appends the CFI relocations of .rela.eh_frame
after the FDE header relocations, so they are not in offset order. When
the linker marks the FDE of a live function, it walks relocations from
that FDE up to its end offset without a lower bound, so the last FDE of
an object also picks up the out-of-order relocations of earlier
functions and keeps them. Within one object this pulled in nearly the
whole library.

Keep the shared header parsing of the single translation unit, but split
the implementation by function: lgfx_v1.cpp (sprite, button, misc),
lgfx_v1_panel.cpp, lgfx_v1_touch.cpp and lgfx_v1_platforms.cpp include
the *.inl files of their group, and LGFXBase.cpp, lgfx_fonts.cpp and
panel/Panel_M5HDMI.cpp (FPGA bitstream) build on their own.

The ESP-IDF CMake and make lists take the new files. The source check
accepts several hubs and standalone sources, and rejects an *.inl
reached from two hubs.

The direct includes of esp_private/periph_ctrl.h get the same
-Wliteral-suffix suppression as spi_common_internal.h: as one
translation unit, the latter always included it first, but the platform
hub now reaches esp32/common.inl before Bus_SPI.hpp.
@lovyan03
lovyan03 merged commit e1c00fe into m5stack:develop Oct 2, 2026
25 checks passed
@ainyan03
ainyan03 deleted the tu_split branch October 2, 2026 07:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants