Skip to content

[Source Build] NativeAOT dotnet CLI library is packaged with embedded symbols #55381

Description

@baronfel

Describe the bug

PR #55329 enables the NativeAOT dotnet CLI library in Source Build SDK layouts. The successful CentOS Source Build from unified build 1515137 packages a 51.58 MiB libdotnet-aot.so that contains DWARF debug sections and full ELF symbol/string tables.

Regular platform builds already externalize or remove this information. From main build 1517524:

Build Packaged library File size AOT-accounted size Symbol state
Linux x64 libdotnet-aot.so 17.68 MiB 15.27 MiB Stripped; .gnu_debuglink present
Windows x64 dotnet-aot.dll 19.01 MiB 15.33 MiB Symbols externalized to PDB
macOS arm64 libdotnet-aot.dylib 17.00 MiB 15.64 MiB No embedded DWARF sections
Source Build CentOS x64 libdotnet-aot.so 51.58 MiB — DWARF and full symbol tables embedded

The normal SDK archives contain only the native library, not the corresponding .dbg, PDB, or dSYM content.

The platform .mstat sizes are all approximately 15–16 MiB, so the Source Build difference is not caused by substantially more generated AOT code.

Steps to reproduce

  1. Download SB_CentOSStream10_Online_MsftSdk_x64_Artifacts from unified build 1515137.
  2. Extract dotnet-sdk-11.0.100-ci-centos.10-x64.tar.gz.
  3. Inspect the library:
$ file sdk/11.0.100-ci/libdotnet-aot.so
ELF 64-bit LSB shared object, x86-64, with debug_info, not stripped

$ stat -c %s sdk/11.0.100-ci/libdotnet-aot.so
54082536

$ readelf -SW sdk/11.0.100-ci/libdotnet-aot.so
...
.debug_info
.debug_str
.debug_line
.symtab
.strtab
...

Stripping a copy gives:

$ llvm-strip --strip-debug libdotnet-aot.so
44884056

$ llvm-strip --strip-unneeded libdotnet-aot.so
17856312

--strip-unneeded preserved all nine dynamic exports.

Expected behavior

Source Build should use the same NativeAOT symbol separation and stripping behavior as regular SDK builds. The SDK archive should contain the deployable native library, while any diagnostic symbols should be retained in the appropriate build/symbol artifacts.

Prefer enabling the existing NativeAOT symbol-handling mechanism—such as the appropriate StripSymbols/publish properties—rather than adding a platform-specific post-copy strip command to the layout.

Actual behavior

The Source Build SDK contains the complete unstripped ELF:

Treatment Raw size Raw saving Estimated gzip size
Current 51.58 MiB — 15.96 MiB
Debug sections removed 42.80 MiB 8.77 MiB 10.14 MiB
Unneeded symbols removed 17.03 MiB 34.55 MiB (67%) 7.41 MiB

Fully stripping the library could therefore save approximately:

  • 34.55 MiB from each installed Source Build SDK.
  • 8.55 MiB from the compressed SDK archive, based on isolated gzip measurements.

Additional stripping offers effectively no savings for normal builds: zero bytes on Linux and Windows, and only 2,112 bytes on macOS.

Is this a regression?

This is a new path introduced while enabling Source Build support in #55329. Regular NativeAOT SDK builds already produce symbol-separated libraries.

Are there any workarounds?

Distributors can run llvm-strip --strip-unneeded before packaging, but that duplicates NativeAOT SDK behavior and risks inconsistencies in build IDs, debug links, exports, signing, and platform tool selection.

dotnet --info output

N/A

IDE version

N/A

Other details

Related: #33476 documents the existing NativeAOT symbol-separation model and CopyOutputSymbolsToPublishDirectory.

Activity

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

Metadata

Metadata

Assignees

Labels

Area-SourceBuildArea-dotnet AOTItems that are part of the dotnet CLI AOT-ification effortcookieIssue Monster Loves Cookies!

Type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions