Skip to content

SmartLink is what keeps the iOS symbols - #26

Merged
jcant0n merged 1 commit into
mainfrom
smartlink-keeps-the-symbols
Aug 9, 2026
Merged

SmartLink is what keeps the iOS symbols#26
jcant0n merged 1 commit into
mainfrom
smartlink-keeps-the-symbols

Conversation

@jcant0n

@jcant0n jcant0n commented Aug 9, 2026

Copy link
Copy Markdown
Member

iOS links with -dead_strip. ForceLoad pulls every member of the archive in and the strip takes back out whatever nothing references — and nothing does: these entry points are reached from managed code at run time, which the linker cannot see. The archive arrived, the executable grew from 30 MB to 32, and cesium_async_system_create was not defined in it.

SmartLink has the SDK read the assembly's P/Invokes and pass -u for each, naming them as roots the strip has to keep.

Proved before changing anything here

A single -u flag passed by hand from the smoke project:

executable:               45 MB   (was 32)
cesium_ symbols by type:  175 T,  91 t,  31 s
the one under test:       00000001005edc7c T _cesium_async_system_create

175 defined globals — exactly the number of functions the generator emits.

The check is the more useful half of this

It used to grep nm -U for the name. A name matches whether the symbol is a definition or an unresolved reference, so the count sat at 297 across three rounds while the thing underneath changed completely — from U references to T definitions. That is why two rounds were spent reading an aggregate that could not answer the question.

It now prints the type histogram and requires a T.

ForceLoad stays on: it is what puts the members within reach at all, and it is safe now that CesiumC#19 stopped merging libjpeg.a beside libturbojpeg.a.

…types

iOS links with -dead_strip. ForceLoad pulls every member of the archive
in and the strip takes back out whatever nothing references, and nothing
does: these entry points are reached from managed code at run time, which
the linker cannot see. The archive arrived, the executable grew from
30 MB to 32, and cesium_async_system_create was not defined in it.

SmartLink has the SDK read the assembly's P/Invokes and pass -u for each,
naming them as roots the strip has to keep. Proved by passing one such
flag by hand before changing anything here: the executable went to 45 MB
and the cesium_ symbols went from unresolved references to 175 T
definitions, which is exactly the number the generator emits.

ForceLoad stays on. It is what puts the members within reach at all, and
it is safe now that CesiumC no longer merges libjpeg.a beside
libturbojpeg.a or libwebpdecoder.a beside libwebp.a.

The smoke check now reads symbol types rather than grepping for a name,
and that is the more useful half of this commit. A name matches whether
the symbol is a definition or an unresolved reference, so the count sat
at 297 across three rounds while the thing underneath changed completely.
It prints the type histogram and requires a T.
@github-actions

github-actions Bot commented Aug 9, 2026

Copy link
Copy Markdown
Contributor

API gate: additive

Every symbol that existed still exists, unchanged. Nothing that compiled before stops compiling.

Target framework Added Removed
net10.0-ios +0 -0
net10.0 +0 -0

Enum and constant values are part of the measured surface: a renumbering keeps compiling and sends the wrong number to the driver, so it counts as a removal.

@jcant0n
jcant0n merged commit 9770698 into main Aug 9, 2026
4 checks passed
@jcant0n
jcant0n deleted the smartlink-keeps-the-symbols branch August 9, 2026 10:03
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