This repository has been archived by the owner on May 9, 2022. It is now read-only.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
References
Summary
The reason for this change:
During #71 we noticed that the produced debug builds of the job
build-ios-libs
fail at runtime with the error:By inspecting the compiled
xayn_ai_ffi_dart
framework withnm
, we saw that the binary only contained the symbol for thedummy_function
. However, the build of the flutter example was successful so what's going on here?Debug build
First of all, a static library is just a collection of object files. We can extract the object files via
ar -x libxayn_ai_ffi_c_aarch64-apple-ios.a
.The object files are produced by
llvm
and as you can seellvm
splits the code generation of a crate into multiple codegen units (rcgu
stands forrust codegen unit
).Let's see in which file our functions are definded:
nm -m libxayn_ai_ffi_c_aarch64-apple-ios.a
What is noticeable is that
xayn_ai_ffi_c.xan8n3l3v4of3g8.rcgu.o
does not contain anyundefined
symbols. This means that the linker only has to link this file if a user of the library only uses/calls thedummy_function
. And that's exactly what happens in our case. Inbindings/dart/ios/Classes/SwiftXaynAiFfiDartPlugin.swift
we only calldummy_function
, therefore linker only links that one object file, but not the files that for example contain the symbols for_xaynai_new
orerror_message_drop
.If the object files would contain
undefined
symbols the linker would search until the linker found them or not. This blog post explains it quite good how the linker works.We can also illustrate this behavior on a small example.
Example
We create a main that calls
dummy_function
and compile it viaclang
.clang -c main.c -arch arm64 -mios-version-min=9.0 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS14.5.sdk
See what object file the linker will load:
Next we want to see which object file the linker would load when building the final executable.
ld main.o libxayn_ai_ffi_c_aarch64-apple-ios.a -why_load -arch arm64
That's it, it would only load
xayn_ai_ffi_c.xan8n3l3v4of3g8.rcgu.o
.Building the executable
Finally, let's build the executable.
clang main.o libxayn_ai_ffi_c_aarch64-apple-ios.a -arch arm64 -mios-version-min=9.0 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS14.5.sdk
The total size of
a.out
: 34KBThe final executable contians the symbole for the
dummy_function
but none of the_xayn_ai_...
symbols.Release build
Now, we let's do the same with a release build (w/o
lto=true
andcodegen-units=1
).nm -m libxayn_ai_ffi_c_aarch64-apple-ios.a
See what object file the linker will load:
ld main.o libxayn_ai_ffi_c.a -why_load -arch arm64
Since
xayn_ai_ffi_c.xayn_ai_ffi_c.2c44ru24-cgu.6.rcgu.o
containsundefined
symbols the linker loads more object files (until it finds them or not), includingxayn_ai_ffi_c.xayn_ai_ffi_c.2c44ru24-cgu.5.rcgu.o
which contains our_xaynai_*
functions.Building the executable
clang main.o libxayn_ai_ffi_c.a -arch arm64 -mios-version-min=9.0 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS14.5.sdk -framework Security -framework Foundation
The total size of
a.out
: 17,5 MBBy replacing
dummy_function
withxaynai_new
the chances are higher that all of our symbols are included in the final executable. To be on the safe side, we should "call" all of our functions in the swift plugin. However, we have to maintain this part manually and I don't know if it's worth it because it is only affects debug build. When compiling the release build we don't have this issue since we compile it with the flags-Ccodegen-units=1 -Clto=on -Cembed-bitcode=yes
which will produce a single file forxayn-ai
that contains all of our exported symbols.