Skip to content

Make the bindings resolvable on iOS - #13

Merged
jcant0n merged 1 commit into
mainfrom
ios-internal-dllimport
Aug 9, 2026
Merged

Make the bindings resolvable on iOS#13
jcant0n merged 1 commit into
mainfrom
ios-internal-dllimport

Conversation

@jcant0n

@jcant0n jcant0n commented Aug 9, 2026

Copy link
Copy Markdown
Member

The package has shipped runtimes/ios-arm64/native/libJoltC.a since its first release, and no consumer could ever have used it: every DllImport named "JoltC", the project built one TFM where __IOS__ is never defined, and the targets file linked nothing on iOS. Held until the pattern was proven in Evergine.Bindings.CesiumNative, which shipped it to nuget.org this morning as 2026.8.9.34.

What changes

  • The generator emits Native.Dll / Native.Conv instead of literals — the shape VuforiaGen uses, Vuforia being the one package in this fleet confirmed working on iOS in a real Evergine project. One line changed; 1280 declarations regenerated.
  • Native.cs switches on __IOS__ to "__Internal" — the only name that reaches symbols linked into the executable.
  • The project multi-targets net10.0;net10.0-ios, so __IOS__ is actually defined.
  • The targets file gains the iOS block that went green in Cesium, verbatim in shape: the injected _FrameworkNativeReference (the shape that was actually validated), ForceLoad (the linker keeps only referenced members and every entry point here is reached from managed code) and SmartLink (iOS links with -dead_strip; without -u roots the strip removes what ForceLoad brought in).

Jolt is simpler than Cesium in the two places that cost rounds there

  • The archive is self-contained by construction — JoltC and Jolt merged, no vcpkg dependencies — so the duplicate-symbol failure class cannot occur.
  • The file keeps its libJoltC.a name: with __Internal the name is irrelevant, unlike wasm where the module name comes from the file name.

The smoke leg ships with its instrument already corrected

nm dumps to a file (never nm | grep -q under pipefail, which reports the opposite of the truth at volume), and the assertion requires JoltC_Init to be a T — a defined global — because a name alone matches an unresolved reference just as well.

Verified locally, as far as Windows allows

net10.0       __Internal: False
net10.0-ios   __Internal: True
lib/: net10.0, net10.0-ios26.0  +  buildTransitive  +  both iOS archives
desktop smoke vs the multi-targeted package: PASS (48 steps, y=0.480, unchanged)

The iOS leg itself needs a CD artifact to run against; that is the next step after merging.

The package has shipped runtimes/ios-arm64/native/libJoltC.a since its
first release and no consumer could ever have used it: every DllImport
named "JoltC", the project built one TFM where __IOS__ is never defined,
and the targets file linked nothing on iOS. Task #49, held until the
pattern was proven in Evergine.Bindings.CesiumNative, which shipped it to
nuget.org this morning.

The generator emits Native.Dll and Native.Conv instead of literals, the
shape VuforiaGen uses -- Vuforia being the one package in this fleet
confirmed working on iOS inside a real Evergine project. Native.cs
switches on __IOS__ to "__Internal", the only name that reaches symbols
linked into the executable, and the project multi-targets so __IOS__ is
actually defined. 1280 declarations regenerated from a one-line change.

The targets file gains the iOS block that went green in Cesium, verbatim
in shape and with all three settings that were measured there the hard
way: the injected _FrameworkNativeReference (the shape that was actually
validated, over the public item that never was), ForceLoad because the
linker keeps only referenced members and every entry point here is
reached from managed code, and SmartLink because iOS links with
-dead_strip and without -u roots the strip removes what ForceLoad
brought in. In Cesium that combination was the difference between an
executable defining zero entry points and all of them.

Jolt is simpler than Cesium in the two places that cost rounds there: the
archive is self-contained by construction (JoltC and Jolt merged, no
vcpkg dependencies), so the duplicate-symbol class of failure cannot
occur, and the file keeps its libJoltC.a name because with __Internal the
name is irrelevant -- unlike wasm, where the module name comes from the
file name and the archive ships renamed.

The smoke leg is ported with its instrument already corrected: nm dumps
to a file because `nm | grep -q` under pipefail reports the opposite of
the truth at this volume, and the assertion requires JoltC_Init to be a
T -- a defined global -- because a name alone matches an unresolved
reference just as well.

Verified locally as far as Windows allows: both assemblies build, the
iOS one carries "__Internal" and the desktop one does not, the package
lays out lib/net10.0, lib/net10.0-ios26.0, the targets file and both iOS
archives, and the desktop smoke passes against the multi-targeted
package with the same 48 steps and y=0.480 as before the change.
@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 +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 35bf338 into main Aug 9, 2026
6 checks passed
@jcant0n
jcant0n deleted the ios-internal-dllimport branch August 9, 2026 12:13
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