[swift-users] How to optionally link swift framework into another framework

Jakub Bednář jakub.bednar at avast.com
Mon Mar 6 11:45:32 CST 2017


C++ puts function pointers (or indexes into virtual function table) into the build binary so it looses track of what exactly it was build against. If in runtime you give it an object that has functions with different signature (types/number of parameters) or different semantics (it does something else), strange things start happening.

Objective-C solved this by remembering selector hashes and looking for the correct method by the selector name rather than using function pointers.

Seems like Swift is doing something different while prohibiting my use case :-(


> On Mar 6, 2017, at 6:29 PM, Rien <Rien at Balancingrock.nl> wrote:
> 
> The way I look at it is that Swift wants all symbols resolved when linking.
> C++ is probably very lenient toward full resolution, and as long as you know that a certain unresolved reference is not used, you can safely ignore the warning.
> Or maybe the C++ compiler is just very clever and can figure out that the reference is never used?
> 
> Regards,
> Rien
> 
> Site: http://balancingrock.nl
> Blog: http://swiftrien.blogspot.com
> Github: http://github.com/Balancingrock
> Project: http://swiftfire.nl
> 
> 
> 
> 
> 
>> On 06 Mar 2017, at 18:09, Jakub Bednář <jakub.bednar at avast.com> wrote:
>> 
>> Hi Rien,
>> 
>> looks like a good way around my problem.
>> 
>> Still I wonder why this does not work in Swift as it does work in Objective-C or even in strongly typed checked C++.
>> 
>> Maybe it is some kind of Swift’s security measure to avoid hard-to-debug bugs in C++ caused by virtual table inconsistencies.
>> 
>> Anyway, thanks for the help.
>> 
>> J.
>> 
>> 
>>> On Mar 6, 2017, at 6:01 PM, Rien <Rien at Balancingrock.nl> wrote:
>>> 
>>> Well, that was a bit short…
>>> 
>>> When you want to use logging, define the ACC “USE_LOGGING” in the build settings.
>>> When you don’t want to use logging, don’t define the ACC.
>>> 
>>> PS: You can get my logging framework from github: https://github.com/Balancingrock/SwifterLog
>>> 
>>> Regards,
>>> Rien
>>> 
>>> Site: http://balancingrock.nl
>>> Blog: http://swiftrien.blogspot.com
>>> Github: http://github.com/Balancingrock
>>> Project: http://swiftfire.nl
>>> 
>>> 
>>> 
>>> 
>>> 
>>>> On 06 Mar 2017, at 17:58, Rien <Rien at Balancingrock.nl> wrote:
>>>> 
>>>> You need conditional compilation.
>>>> 
>>>> Called “Active Compilation Conditions” in the build settings.
>>>> 
>>>> For example define a ACC of “USE_LOGGING”
>>>> 
>>>> Then in your code:
>>>> 
>>>> #if USE_LOGGING
>>>> 
>>>> import Logging
>>>> 
>>>> #else
>>>> 
>>>> struct Logging {
>>>> 	func debug(message: string) {}
>>>> }
>>>> 
>>>> #endif
>>>> 
>>>> 
>>>> 
>>>> 
>>>> Regards,
>>>> Rien
>>>> 
>>>> Site: http://balancingrock.nl
>>>> Blog: http://swiftrien.blogspot.com
>>>> Github: http://github.com/Balancingrock
>>>> Project: http://swiftfire.nl
>>>> 
>>>> 
>>>> 
>>>> 
>>>> 
>>>>> On 06 Mar 2017, at 17:26, Jakub Bednář via swift-users <swift-users at swift.org> wrote:
>>>>> 
>>>>> Hello everyone,
>>>>> 
>>>>> I am trying to add optional logging into my framework, but for sake of this question, lets assume I want to add optional logging into an app. I have created an example with following setup:
>>>>> 
>>>>> 1. Logging.framework declares
>>>>> 
>>>>> 	public protocol Logging {
>>>>> 		func debug(message: String)
>>>>> 	}
>>>>> 
>>>>> 	and I have build the framework for the app to see it.
>>>>> 
>>>>> 2. Application has 
>>>>> 
>>>>> 	import Logging
>>>>> 	
>>>>> 	public class Engine {
>>>>> 
>>>>> 		let logger: Logging?
>>>>> 
>>>>> 		public init(withLogger logger: Logging? = nil) {
>>>>> 			self.logger = logger 
>>>>> 		}
>>>>> 
>>>>> 		public work() {
>>>>> 			self.logger?.debug(“Working”)
>>>>> 		}
>>>>> 	} 
>>>>> 
>>>>> Now I don’t have the Logging.framework in Embed Binaries nor Link Frameworks lists. My app builds ok, but then fails to start telling me that Logging.framework was not loaded. I checked the binary using otool -L and Logging.framework is still referenced by the binary. Is there any way how to achieve my goal? This would be trivial with Objective-C and I still can’t figure it out in Swift.
>>>>> 
>>>>> Thanks a lot,
>>>>> 
>>>>> J.
>>>>> 
>>>>> _______________________________________________
>>>>> swift-users mailing list
>>>>> swift-users at swift.org
>>>>> https://lists.swift.org/mailman/listinfo/swift-users
>>>> 
>>> 
>> 
> 



More information about the swift-users mailing list