Skip to content

fix(audience): prevent IL2CPP stripping of Unity hooks assembly#790

Open
nattb8 wants to merge 1 commit into
mainfrom
feat/sdk-480-il2cpp-stripping
Open

fix(audience): prevent IL2CPP stripping of Unity hooks assembly#790
nattb8 wants to merge 1 commit into
mainfrom
feat/sdk-480-il2cpp-stripping

Conversation

@nattb8

@nattb8 nattb8 commented Jun 9, 2026

Copy link
Copy Markdown
Collaborator

Fixes SDK-480.

Problem

Games built with IL2CPP + High stripping silently lose all Unity context fields (userAgent, locale, screen, timezone) from every event. The linker strips the entire Immutable.Audience.Unity assembly when it finds no call sites into it — so the [RuntimeInitializeOnLoadMethod] hook never fires and ContextProvider is never registered. Only library and libraryVersion survive because they come from Immutable.Audience.Runtime, which has direct references keeping it alive.

The SDK ships a link.xml to guard against this, but Unity's linker skips it for packages loaded via a file: path outside the project tree. Studios without a project-level link.xml fallback hit this silently.

Confirmed in production on project 18282: ~97% of 0.3.0 events are missing userAgent. All 0.2.2 events from the same project had it — the regression correlates with them switching to an IL2CPP + High stripping build around the 0.3.0 upgrade.

Fix

Two lines in AudienceUnityHooks.cs:

  • [assembly: AlwaysLinkAssembly] — forces the linker to process the assembly regardless of call sites
  • [Preserve] on the class — keeps Install() alive once the assembly is included

[Preserve] alone is not enough: if the linker skips the assembly entirely, it never evaluates the attribute.

Test plan

  • Build example app with IL2CPP + High stripping and no audience lines in link.xml
  • Confirm events include full context (userAgent, locale, screen, timezone)
  • Confirm no PersistentDataPath is required crash on init

Games using IL2CPP with High stripping and no project-level link.xml
lose all Unity context fields (userAgent, locale, screen, timezone).
The linker strips Immutable.Audience.Unity entirely when it finds no
call sites, so the [RuntimeInitializeOnLoadMethod] hooks never fire and
ContextProvider is never registered.

[assembly: AlwaysLinkAssembly] forces the linker to process the assembly
regardless of call sites. [Preserve] on AudienceUnityHooks keeps Install()
alive once the assembly is included. [Preserve] alone is insufficient
because the linker skips the assembly before evaluating attributes.

Fixes SDK-480.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@nattb8 nattb8 requested review from a team as code owners June 9, 2026 08:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

1 participant