Skip to content

[Android] Compress debug sections in coreclr_static.a with -gz=zlib#124587

Open
davidnguyen-tech wants to merge 1 commit intodotnet:mainfrom
davidnguyen-tech:android-compress-debug-symbols
Open

[Android] Compress debug sections in coreclr_static.a with -gz=zlib#124587
davidnguyen-tech wants to merge 1 commit intodotnet:mainfrom
davidnguyen-tech:android-compress-debug-symbols

Conversation

@davidnguyen-tech
Copy link
Member

@davidnguyen-tech davidnguyen-tech commented Feb 19, 2026

Description

Reduces libcoreclr_static.a size on Android by compressing DWARF debug sections using -gz=zlib. This adds a single compiler flag for Android builds in eng/native/configurecompiler.cmake.

Results (android-arm64, Release):

Metric Before After
libcoreclr_static.a size 702 MB 359 MB
Reduction 49%

Debug info is fully preserved (just compressed). The Android NDK linker (lld) and debuggers handle compressed debug sections natively.

Validation

  • Clean build: ./build.sh clr.runtime+clr.alljits+host -os android -arch arm64 -c Release — 0 warnings, 0 errors
  • Link test: singlefilehost links successfully against the compressed archive
  • Also tested -gz=zstd (357 MB) but the gain over zlib is negligible and zlib has broader toolchain compatibility

Consumer compatibility

All consumers of libcoreclr_static.a use the Android NDK toolchain (Clang 18 / lld 18 in NDK r27c), which natively supports compressed debug sections:

Consumer Toolchain Verified?
singlefilehost (CoreCLR build) NDK lld via CMake ✅ Built and linked
AndroidAppBuilder (app packaging) NDK android.toolchain.cmake ✅ Same NDK toolchain
Functional tests (Android.Device_Emulator.JIT.Static.Test) Via AndroidAppBuilder ✅ Same pipeline

The NDK linker decompresses SHF_COMPRESSED debug sections transparently during linking. No changes needed on the consumer side.

Context

Analysis of the archive shows debug info accounts for 85–94% of each object file. The vm directory contributes ~412 MB (62%) and jit ~170 MB (26%) of the total.

Further size reductions (e.g., stripping debug info for the shipped NuGet package, or reducing C++ template bloat) are possible but require broader discussion on diagnosability tradeoffs and are out of scope for this PR.

Contributes to #116531

Reduces libcoreclr_static.a from ~702 MB to ~359 MB by compressing
DWARF debug sections in object files. Debug info is fully preserved
and the Android NDK linker (lld) handles compressed sections natively.

Contributes to dotnet#116531

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR reduces the size of the Android libcoreclr_static.a archive by enabling compression of DWARF debug sections during compilation via Clang’s -gz=zlib flag, applied in the shared native compiler configuration.

Changes:

  • Add -gz=zlib to Clang compile options when targeting Android to compress debug sections.

add_compile_options(-Wno-null-conversion)
add_compile_options(-glldb)
if (CLR_CMAKE_TARGET_ANDROID)
add_compile_options(-gz=zlib)
Copy link

Copilot AI Feb 19, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

-gz=zlib is added unconditionally for Android/Clang. Since this is a non-trivial compiler flag (and Android builds can use different NDK/Clang versions), please gate it with a compiler-flag support check (e.g., check_c_compiler_flag/check_cxx_compiler_flag) before adding it. That will prevent hard build breaks on toolchains that don’t recognize -gz or the =zlib value.

Suggested change
add_compile_options(-gz=zlib)
check_c_compiler_flag("-gz=zlib" C_COMPILER_SUPPORTS_GZ_ZLIB)
check_cxx_compiler_flag("-gz=zlib" CXX_COMPILER_SUPPORTS_GZ_ZLIB)
if (C_COMPILER_SUPPORTS_GZ_ZLIB AND CXX_COMPILER_SUPPORTS_GZ_ZLIB)
add_compile_options(-gz=zlib)
endif()

Copilot uses AI. Check for mistakes.
@dotnet-policy-service
Copy link
Contributor

Tagging subscribers to this area: @agocke, @dotnet/runtime-infrastructure
See info in area-owners.md if you want to be subscribed.

@kotlarmilos
Copy link
Member

kotlarmilos commented Feb 19, 2026

This looks good assuming that no further actions are needed to read the compressed format. Do we need to preserve runtime debug symbols on Android?

@davidnguyen-tech
Copy link
Member Author

davidnguyen-tech commented Feb 19, 2026

This looks good assuming that no further actions are needed to read the compressed format. Do we need to preserve runtime debug symbols on Android?

There shouldn't be a need for further actions to read the compressed format - added a Consumer compatibility section to the PR description.

If I understand the discussion in #116531 correctly, we don't need to preserve them technically - it's more of a design decision. Let's discuss that in the issue.

Copy link
Member

@kotlarmilos kotlarmilos left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, thanks! @jkoritzinsky should sign off.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

Status: No status

Development

Successfully merging this pull request may close these issues.

2 participants

Comments