Skip to content

build: release-build size optimizations (unwind tables, LTO) - #499

Merged
jow- merged 2 commits into
masterfrom
feat/build-flags
Oct 19, 2026
Merged

jow- merged 2 commits into
masterfrom
feat/build-flags

Conversation

@jow-

@jow- jow- commented Oct 19, 2026

Copy link
Copy Markdown
Collaborator

Two complementary CMake build options to reduce release-build size:

  1. build: drop async stack-unwind tables in release builds — ucode is pure C with no exceptions and implements its own bytecode-level stack traces, so .eh_frame/.eh_frame_hdr unwind tables are dead weight in shipping builds. Omitted via -fno-asynchronous-unwind-tables (Release/MinSizeRel only, gated behind BUILD_NO_UNWIND_TABLES, ON by default). Stripped MinSizeRel libucode drops from ~197 KB to ~173 KB (-12.5%).

  2. build: add opt-in link-time optimization for release builds — new BUILD_LTO option enabling CMake's interprocedural optimization for Release/MinSizeRel only, trimming a further ~2.4% (172 KB -> 168 KB stripped). Off by default because it lengthens builds and assumes a matching LTO toolchain; guarded by check_ipo_supported().

Debug and RelWithDebInfo (and every default/OpenWrt build) are unchanged. Test suite passes unchanged.

jow- added 2 commits October 19, 2026 18:27
ucode is pure C with no exceptions and implements its own bytecode-level
stack traces, so the .eh_frame/.eh_frame_hdr unwind tables are dead weight
in shipping builds: they only serve external native-stack unwinding
(backtrace(), C-level crash reporters, profilers). Omitting them via
-fno-asynchronous-unwind-tables removes about 23 KB from libucode.

Bind the flag to Release and MinSizeRel via a generator expression so
Debug and RelWithDebInfo keep their native stack traces, and gate it behind
a BUILD_NO_UNWIND_TABLES option (ON by default) in the style of the other
codegen options. Stripped MinSizeRel libucode drops from ~197 KB to ~173 KB
(-12.5%), below origin/master's ~193 KB; the test suite passes unchanged.

Signed-off-by: Jo-Philipp Wich <jo@mein.io>
Add a BUILD_LTO option that enables CMake's interprocedural optimization for
the Release and MinSizeRel configurations only, leaving Debug and
RelWithDebInfo (and every default/OpenWrt build) unchanged. IPO performs
cross translation-unit dead code elimination and folds identical functions,
trimming a further ~2.4% from libucode (172 KB -> 168 KB stripped on top of
the unwind-tables change).

Off by default because it lengthens builds and assumes a matching LTO
toolchain. Guarded by check_ipo_supported() with a warning if unavailable.

Signed-off-by: Jo-Philipp Wich <jo@mein.io>
@jow-
jow- force-pushed the feat/build-flags branch from 7aa19e5 to 0dc287e Compare October 19, 2026 16:27
@jow-
jow- merged commit 4a28662 into master Oct 19, 2026
3 checks passed
@jow-
jow- deleted the feat/build-flags branch October 19, 2026 17:44
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.

1 participant