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

Jonathan Prescott jprescott12 at icloud.com
Mon Mar 6 11:38:57 CST 2017


In most systems, including macOS, everyone uses the same linker, no matter what language.  swiftc, at the object code level, supports the same ABI as clang(C/C++/Obj-C/Objc-C++), and in fact, uses a lot of the compiler infrastructure as clang, including pieces of clang.  

Your example is the same as the C pre-processor used in the C-family of languages.  The major difference is that the #… processing is performed in the Swift lexical analyzer, and does not support all the myriad functionality of the C pre-processor, whereas conceptually, there is a separate pass of text replacement performed by the pre-processor when compiling C, et al.  The conditional compilation is the same between the two, and is affecting the lexical analysis of the program.  Has nothing to do with linking, etc..

Jonathan

> On Mar 6, 2017, at 12:29 PM, Rien via swift-users <swift-users at swift.org> 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
>>>> 
>>> 
>> 
> 
> _______________________________________________
> 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