-
Notifications
You must be signed in to change notification settings - Fork 62
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Make extern Swift functions public to prevent stripping in Release builds #262
base: master
Are you sure you want to change the base?
Conversation
This is a very good idea. Here's one solution off the top of my head
Just a quick idea. You might have a better solution in mind. |
@chinedufn Ok I've create both a reproduction case that fails to build against the I'm not sure we want this amount of code duplication for the repro case and the success case. There's probably also a smarter way to specify which versions of the dependencies to build e.g. using the If you have any suggestions for how to structure this code better, avoid the duplication etc. I'd be happy to make those changes. I did have a go at reproducing the issue by just calling |
Thanks for putting this together.
We don't need to maintain two cases. The purpose of making the failure case was for us to be sure that we weren't accidentally landing a test that would have always passed. For example, you found that the we just need to land one of the test crates, not both. Then we can have confidence that your code for going from
Great. Thanks for figuring this out. In the test crate's README Let's document what we tried and why we think it didn't work. This helps with:
In short, a maintainer should be able to clearly understand why we are using a more complex solution (Swift Package + xcodebuild) instead of a simpler one (swiftc). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great work on this. I left some minor feedback, but overall this looks good.
Thanks for coming up with the idea for testing this and figuring out a nice and clean way to do it.
@@ -0,0 +1,7 @@ | |||
# Test Release Builds Fail |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's document:
-
Why it would infer that they were dead code (as in, mention
func
vs.public func
) -
show an example of a problematic
cdecl
function. Explain that we now prependpublic
.@_cdecl("__swift_bridge__$add") func __swift_bridge__add (ptr: UnsafeMutableRawPointer) { /* .. */ }
- This will help orient the reader and give them a better understanding of what we're testing
-
How the test works. How are we accomplishing what you've explained here? Maybe explain how the test works step by step.
-
How to run the test.
-
Mention that this test gets ran during
test-swift-rust-integration.sh
All of this will help future maintainers understand what's going on and be in a better position to make changes/improvements to it.
import Foundation | ||
import TestReleaseFails | ||
|
||
call_swift_add() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe call_rust()
to make it clear that we're calling into Rust.
Right now it seems like we're calling a Swift function.
/// Verify that extern "Swift" methods are declared `public` to prevent them from | ||
/// being stripped by the Swift compiler when building in `Release` mode. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great docs
if ! sh ./test-release-fails/build.sh; then | ||
echo "Build failed as expected" | ||
else | ||
echo "Error: Build succeeded but was expected to fail" | ||
exit 1 | ||
fi |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We don't need to maintain two cases.
When I said to make a failing cast I just meant to
- Make it fail
- Change
swift-bridge
- Confirm that it now passes
So that we were sure that our changes actually worked and that we didn't:
- Make a test that already passed (BAD)
- Make swift-bridge changes
- Confirm that test passes (BAD, it already passed to begin with. It was a bad test)
Does that make sense?
Are you able to complete this pull request? Looks like the main remaining work is to delete one of the test packages. Is there anything that I can help with? |
would be awesome to get this merged |
Thank you for the review. I've been quite busy with other projects recently, but I should have a bit more time to get this finished next week. |
Hello, hello. Anticipate having any time for this? |
I had a quick stab at fixing #166, if I have understood the instructions correctly this would resolve the issue at the cost of changing the visibility of functions in the module.
@chinedufn let me know if I'm on the right track here.
So far I have only added tests for the
swift-bridge-ir
crate, I'm guessing it might make sense to also add a small repro example to runxcodebuild
in release mode on CI.