-
Notifications
You must be signed in to change notification settings - Fork 271
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
Swift: missing symbols in ios_framework
bundle
#332
Comments
This is an interesting bug. Thanks for the awesome repro case, without that I definitely wouldn't have looked into this. So the core problem is this limitation of the linker when it comes to Swift code https://bugs.swift.org/browse/SR-6004 the tl;dr of that is that there is no equivalent of The bazel specific issue here, and how it differs from xcodebuild, is that bazel first builds a static library target from all your I think one possible thing we could do in bazel is pass |
Brilliant! Thanks for the great explanation. I confirmed Agreed that handling this automatically with default |
One thing I'd like to comment is that We already do a similar thing to Another thing to consider is that C code gets deadstripped from dylibs if not being used and not marked as public/exportable, so that adds another vector of issues for missing symbols. We don't currently have proposed solution and I don't believe anyone's actively working on this given that workarounds are available. |
@sergiocampama what has made you want to remove use of
What's the difference between this and |
We'd like to remove |
Passing .o files to |
FWIW, I previously came up with a technique to solve the ObjC category linking problem, which works for linking apps. The approach is to annotate both category declarations and definitions with a macro. The definition gets a symbol that can be linked to (A), and the declaration gets a weak symbol that links to the one in the definition (&A). Then, if any file imports the category header, it will cause the linker to load the object file that contains the category definition via the associated symbol (A). This allows .a files to contain categories, and be linked without |
I just got this issue too, and making the |
Any idea how to make |
I would expect setting |
@keith it is a bit different in my case, I want it to propagate the other way, i.e., for the rule that will generate the final |
Ah got it, adding |
Yeah. Found this rabbit hole actually related to bigger Bazel issue: bazelbuild/bazel#7362 The |
Is there no equivalent flag for gold? |
ios_framework isn't meant for packaging so it doesn't need to link all dependents. ios_static_framework does do a whole archive link. |
Somehow it doesn't work with: Cool, thanks for the clarification on the |
The flag probably differs, you probably want |
Yeah, that has some whole other issues (multiple definitions due to some transitive dependencies), and even just |
I came across this issue and seemed to be having the same problem with a test using symbols in a test host For my case, it was possible workaround this in LD with the
Also, in a large single module app, Bazel should also link the object files directly to the app for performance reasons e.g. not linking 2x. This would also be addressed with object file propagation! You could probably take the rule in rules_ios as-is or re-work into a PR: bazel-ios/rules_ios#358 |
ld has different behavior when loading members of a static library VS objects as far as visibility. Under `-dynamic` - linked _swift object files_ can have public visibility - symbols from _swift static libraries_ are omitted unless used, and not visible otherwise By using `-force_load`, we can load static libraries in the attributes of an application's direct depenencies. These args need go at the _front_ of the linker invocation otherwise these arguments don't work with lds logic. Why not put it into `rules_apple`? Ideally it could be, and perhaps consider a PR to there .The underlying java rule, `AppleBinary.linkMultiArchBinary` places `extraLinkopts` at the end of the linker invocation. At the time of writing these args need to go into the current rule context where `AppleBinary.linkMultiArchBinary` is called. One use case of this is that iOS developers want to load above mentioned symbols from applications. Another alternate could be to create an aspect, that actually generates a different application and linker invocation instead of force loading symbols. This could be more complicated from an integration perspective so it isn't used. Another case is present in dynamic frameworks in rules_apple ( bazelbuild/rules_apple#332 )
* A rule to link with `-force_load` for direct`deps` ld has different behavior when loading members of a static library VS objects as far as visibility. Under `-dynamic` - linked _swift object files_ can have public visibility - symbols from _swift static libraries_ are omitted unless used, and not visible otherwise By using `-force_load`, we can load static libraries in the attributes of an application's direct depenencies. These args need go at the _front_ of the linker invocation otherwise these arguments don't work with lds logic. Why not put it into `rules_apple`? Ideally it could be, and perhaps consider a PR to there .The underlying java rule, `AppleBinary.linkMultiArchBinary` places `extraLinkopts` at the end of the linker invocation. At the time of writing these args need to go into the current rule context where `AppleBinary.linkMultiArchBinary` is called. One use case of this is that iOS developers want to load above mentioned symbols from applications. Another alternate could be to create an aspect, that actually generates a different application and linker invocation instead of force loading symbols. This could be more complicated from an integration perspective so it isn't used. Another case is present in dynamic frameworks in rules_apple ( bazelbuild/rules_apple#332 )
With most of the heavy lifting done by @steeve (see #223), I made a working
ios_framework
rule for building dynamic frameworks that can be dropped into vanilla (non-Bazel) Xcode projects. At runtime, I discovered that certain symbols that are present in the object file created by theswift_library
rule are missing from the framework binary created by theios_framework
rule.I believe I traced this to the following weird phenomenon: if a Swift source file contains any ObjC classes, all of its symbols make it into the framework binary, even if they're not bridged to ObjC. But if a Swift source file does not contain any ObjC classes, (say, if it only contains protocols, structs, and classes that don't extend
NSObject
), theapple_binary
compile subcommand is totally stripping out all symbols generated from that source file's corresponding object file. I was able to debug up to this point, but it wasn't obvious to me from the wrappedclang
command why this would be happening.I created a simple repro repository here. The
./repro.sh
bash script should print:Is this a known issue?
The text was updated successfully, but these errors were encountered: