Open bes opened 1 year ago
How are you building your iOS application?
If you're using the Xcode + Cargo approach, if you look for LIBRARY_SEARCH_PATHS
in your project.pbxproj
do you see the path to your release binary?
If you're using the Swift package approach, did you include your release binary in the universal library?
But yeah, please go into more detail about your build setup.
I am using the Swift package approach.
The binary is built like this:
cargo build --release --target x86_64-apple-darwin
cargo build --release --target aarch64-apple-darwin
lipo \
./target/aarch64-apple-darwin/release/libmyproj_ios.a \
./target/x86_64-apple-darwin/release/libmyproj_ios.a -create -output \
./target/universal-macos/release/libmyproj_ios.a
cargo build --release --target aarch64-apple-ios
cargo build --release --target x86_64-apple-ios
cargo build --release --target aarch64-apple-ios-sim
lipo \
./target/aarch64-apple-ios-sim/release/libmyproj_ios.a \
./target/x86_64-apple-ios/release/libmyproj_ios.a -create -output \
./target/universal-ios/release/libmyproj_ios.a
swift-bridge-cli create-package \
--bridges-dir ./generated \
--out-dir ../../video-ios/lib-myproj-ios \
--ios target/aarch64-apple-ios/release/libmyproj_ios.a \
--simulator target/universal-ios/release/libmyproj_ios.a \
--macos target/universal-macos/release/libmyproj_ios.a \
--name myprojIos
I didn't originally include the macos target, but added that as a way to see if I could move forward.
I'm happy to share more about my setup, but I'm not sure what to look for. Any help would be appreciated.
Gotcha.
Those symbols should be in the Swift code that swift-bridge
is generating for you.
So, it sounds like your generated Swift code is being included in your Swift package in Debug, but not in Release.
Can you compare the Swift and C code in that ./generated
directory between Debug and Release to see if the symbols are present in debug builds but absent in release builds?
If you'd like to explore yourself you can do clone the swift-bridge
repo and use cargo run -p swift-bridge-cli create-package ...
then poke around in here https://github.com/chinedufn/swift-bridge/blob/master/crates/swift-bridge-build/src/package.rs#L97-L112
If you can make a minimal reproduction of the issue such that we can run something like:
git clone https://github.com/bes/swift-bridge-issue-166
xcodebuild # whatever arguments are necessary ...
Then we can look into this.
The thing is - I'm using the SAME swift-bridge
package for XCiode Debug and XCode Release builds! What I mean is that my XCode project Debug build, the one that I use for debugging locally, is working, but when I switch over to Release to package it for App Store, then it fails - with no changes in the SPM pacakage.
I am also not using a spm-over-git setup, but rather I have embedded the package as a "local" spm package in XCode.
But I compared the output from the xcode compiler, and the code in the generated .swift file:
// ___swift_bridge__$OfflineReceiver$_free
@_cdecl("__swift_bridge__$OfflineReceiver$_free")
I build my xcode project using Fastlane, which looks like this:
lane :build_debug do
gym(
scheme: 'X-debug',
configuration: 'Debug',
include_symbols: true,
export_options: {
compileBitcode: false,
uploadBitcode: false,
uploadSymbols: true,
method: "development",
teamID: "xxx",
provisioningProfiles: {
// ...
},
},
)
end
lane :build_release do
gym(
scheme: "X-release",
configuration: "Release",
export_method: "app-store",
export_options: {
compileBitcode: false,
uploadBitcode: false,
uploadSymbols: true,
method: "app-store",
teamID: "xxx",
provisioningProfiles: {
// ...
},
},
)
end
But the build failure also happens when I switch over to the release profile in xcode and build from there.
I will try to make a proof-of-concept, but that will probably take some time to get working.
Summary:
OK so I made some progress -
@_cdecl("__swift_bridge__$OfflineReceiver$_free")
public func __swift_bridge__OfflineReceiver__free (ptr: UnsafeMutableRawPointer) {
If I slap public
on the header functions generated by extern "Swift"
then it compiles!
Seems like XCode is aggressively pruning those functions in the Release build, for some reason.
For now I'm making do with
sed -i '' 's/^func __swift_bridge__/public func __swift_bridge__/g' mylib.swift
But I feel like either I should modify my XCode build somehow or this is a bug in swift-bridge
.
Yeah we should solve this in swift-bridge
.
We just need to make this a public func
instead of func
https://github.com/chinedufn/swift-bridge/blob/3c0d00da33fdf19e201eb121c7e6e370897f8070/crates/swift-bridge-ir/src/codegen/generate_swift.rs#L317-L319
We can add a mod visibility_codegen_tests
to the codegen tests https://github.com/chinedufn/swift-bridge/blob/3c0d00da33fdf19e201eb121c7e6e370897f8070/crates/swift-bridge-ir/src/codegen/codegen_tests.rs#L30-L49
And then in that module we can add a extern_swift_functions_public
test where we confirm that we generate a public func
@_cdecl
function.
We can use ExpectedRustTokens::SkipTest
and ExpectedCHeader::SkipTest
, like this https://github.com/chinedufn/swift-bridge/blob/4f2a9d70ceabfae1708628bb637c7ba0ac9225d7/crates/swift-bridge-ir/src/codegen/codegen_tests/extern_rust_method_swift_class_placement_codegen_tests.rs#L32-L34 https://github.com/chinedufn/swift-bridge/blob/4f2a9d70ceabfae1708628bb637c7ba0ac9225d7/crates/swift-bridge-ir/src/codegen/codegen_tests/extern_rust_method_swift_class_placement_codegen_tests.rs#L95-L97
@chinedufn I've put up a PR (#262) based on these instructions.
Yeah we should solve this in
swift-bridge
.We just need to make this a
public func
instead offunc
We can add a
mod visibility_codegen_tests
to the codegen testsAnd then in that module we can add a
extern_swift_functions_public
test where we confirm that we generate apublic func
@_cdecl
function.We can use
ExpectedRustTokens::SkipTest
andExpectedCHeader::SkipTest
, like this
lol i ran into the same issue: https://github.com/rustunit/bevy_ios_iap/commit/ba61693731d11a81d15aea11d75519b00f60e284 seems xcode linker optimized funcs away that are not public and not used from inside their own swift package
hey, Im running into the same issue @chinedufn do you think we can make it work without running the script that makes functions public?
If someone writes a PR that solves this issue, I can merge it.
A contributor wrote a pull-request that fixed it, but they are no longer planning to work on addressing the PR's feedback.
https://github.com/chinedufn/swift-bridge/pull/262
Anyone can feel free to fork that branch, or create their own new brach, and then get the fix working.
When I run my iOS application in Debug mode, everything is working correctly and the code is linking properly.
But when I build my iOS app in Release mode, for App Store release, I am greeted with the following errors:
Basically it can't link against anything that is declared
extern "Swift"
. I've tried a few things before reaching out, but I can't figure out what is going wrong.Please help 🙏