Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 14 additions & 5 deletions .github/workflows/package-smoke.yml
Original file line number Diff line number Diff line change
Expand Up @@ -440,11 +440,20 @@ jobs:
exit 1
fi

# And the symbols themselves, which is what would be missing if Native.Dll had compiled
# to "CesiumNativeC" rather than "__Internal".
if ! nm -U "$exe" 2>/dev/null | grep -q "cesium_async_system_create"; then
echo "::error::cesium_async_system_create is not defined in the executable"
# Types, not a count, and the difference matters more than it looks. iOS links with
# -dead_strip, so an entry point reached only from managed code can be present as an
# unresolved reference and absent as a definition. A grep for the name matches both,
# which is how three rounds were spent reading 297 unchanged matches while the symbols
# underneath went from references to definitions.
echo " cesium_ symbols by type:"
nm "$exe" 2>/dev/null | grep cesium_ | awk '{print $(NF-1)}' | sort | uniq -c | sed 's/^/ /'

# T is a defined global. U would mean the linker never resolved it, which is what a
# missing SmartLink produces and what a P/Invoke would then fail on at run time.
if ! nm "$exe" 2>/dev/null | grep -qE "T _?cesium_async_system_create$"; then
echo "::error::cesium_async_system_create is not a defined symbol in the executable"
nm "$exe" 2>/dev/null | grep cesium_async_system_create | sed 's/^/ /'
exit 1
fi
echo " ok cesium_async_system_create is defined in the executable"
echo " ok cesium_async_system_create is defined (T) in the executable"
echo "PASS"
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,21 @@
it into the bundle afterwards; an archive is linked and does not travel, so none of that
applies here.

ForceLoad is on, and both settings were tried against a real link before this one stayed.
SmartLink is what actually keeps the symbols, and it took three measured rounds to find out.

iOS links with -dead_strip. ForceLoad pulls every member of the archive in and the strip
then 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. So 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, which names them
as roots the strip must keep. Proved by passing one such flag by hand: the executable went
to 45 MB and the 297 cesium_ symbols went from unresolved references to 175 T definitions,
the exact number the generator emits.

ForceLoad stays on. It is what puts the members within reach in the first place, and it is
safe now that CesiumC no longer merges libjpeg.a beside libturbojpeg.a or libwebpdecoder.a
beside libwebp.a, which used to make the link fail on duplicate symbols.

Without it the linker keeps only the members something references, and every entry point
here is reached from managed code rather than from native. The application built, weighed
Expand Down Expand Up @@ -63,7 +77,7 @@
<_FrameworkNativeReference Include="$(_CesiumNativeIosArchive)">
<Kind>Static</Kind>
<ForceLoad>true</ForceLoad>
<SmartLink>false</SmartLink>
<SmartLink>true</SmartLink>
</_FrameworkNativeReference>
</ItemGroup>
</Target>
Expand Down
Loading