aliceatlas / buildstatic

build Swift modules as static libraries, include them about as easily as normal frameworks. [• STATUS: still working last time I checked but possibly a bit outdated – should hopefully be fully obsolete when there's more Swift Package Manager + Xcode integration •]
77 stars 2 forks source link

Extension symbols missing when linked framework statically #1

Open DeeSee opened 8 years ago

DeeSee commented 8 years ago

Hi!

I've tried your approach to link Swift frameworks statically and ran into the following issue: if I have an extension conforming some protocol for some type (struct, for instance) in other file than the main declaration of this type and other than the protocol declaration, I can't cast the object to this protocol. For instance, I have:

file1.swift:

public struct TestStruct {
  public init() {}
}

file2.swift:

public protocol TestProtocol {}

file3.swift:

extension TestStruct: TestProtocol {}

If I build these files in a framework using your approach and use this framework into my app, the code TestStruct() is TestProtocol crashes instead of returning true (yes, crashes, not returning false). Did you encounter this issue before?

Here's a sample project for convenience.

earltedly commented 8 years ago

I've been experimenting with this and found the same issue. Have either of you figured out a workaround at all?

DeeSee commented 8 years ago

Actually, there is a workaround: you can use -load_all flag or link your static framework with -force_load instead of adding it to linking build phase. The thing is that it's unclear why this flag affects Swift code (originally it was a workaround for lost symbols from Objective-C)

earltedly commented 8 years ago

Thanks - that is fixing it for me, I should have thought of it!

Re: the difference:

-all_load   Loads all members of static archive libraries.
-ObjC       Loads all members of static archive libraries that implement an Objective-C
              class or category.

(http://stackoverflow.com/a/21844874/1194572)

DeeSee commented 8 years ago

For 64-bit and iPhone OS applications, there is a linker bug that prevents -ObjC from loading objects files from static libraries that contain only categories and no classes.

I.e. this flag was intended for ObjC, not Swift. That's why it's weird that it works.

maximkhatskevich commented 7 years ago

@DeeSee thanks for the "TestApp" sample project! It helped me to figure out how to make my command line tool target to see the sources from my framework (built statically). I did all the steps from Readme, but it didn't work until I've put "$(inherited) @executable_path/Frameworks" into "Runpath Search Paths" build setting of the command line tool target. @aliceatlas this might be worth to put into Readme as well, would be useful for developers like me, who are not so experienced with how linker works.