154

I have a framework (in this instance it's RxSwift) which I've compiled using Xcode 11.0 into the traditional RxSwift.framework style package

This imported fine into Xcode 11.0 and also 11.1 never had any problems with it

Today, upon Apple's release of Xcode 11.2, I upgraded, and I am presented with the error:

Module compiled with Swift 5.1 cannot be imported by the Swift 5.1.2 compiler

I'm used to swift compiler mismatches, and I'm aware I can just recompile RxSwift using Xcode 11.2 and carry on, but the headline feature of Swift 5.1 was module stability.

I was under the impression that now that we have module stability, frameworks won't need to keep getting recompiled with every new Xcode release, yet this is clearly not the case.

If anyone can explain what is going on here I would much appreciate it. Is Xcode 11.2 exhibiting a bug? or did I somehow need to tell it I wanted module stability when I originally compiled with Xcode 11.0?

Orion Edwards
  • 113,829
  • 60
  • 223
  • 307
  • 1
    Related: [Module compiled with Swift 5.0.1 cannot be imported by the Swift 5.1 compiler](https://stackoverflow.com/questions/58130048/module-compiled-with-swift-5-0-1-cannot-be-imported-by-the-swift-5-1-compiler) – Cœur Nov 04 '19 at 08:05
  • For me Toolchain with older swift version worked: https://stackoverflow.com/a/43142147/5846135 – Zeero0 Feb 24 '20 at 17:03

7 Answers7

179

OK, Turns out if you watch the WWDC video, they explain it: https://developer.apple.com/videos/play/wwdc2019/416/

You need to set the Build Libraries for Distribution option to Yes in your framework's build settings, otherwise the swift compiler doesn't generate the neccessary .swiftinterface files which are the key to future compilers being able to load your old library.

This ends up in your project.pbxproj file as:

BUILD_LIBRARY_FOR_DISTRIBUTION = YES;

After setting this flag, a framework I compiled using Xcode 11.0 (swift 5.1) was able to be used by Xcode 11.2 (swift 5.1.2) and everything appears to be working correctly.

Hopefully this question/answer will serve as a useful reference for everyone who hasn't watched all the WWDC videos

If the error still persists go to Product > Clean Build Folder and Build again.

ChiggyB
  • 35
  • 7
Orion Edwards
  • 113,829
  • 60
  • 223
  • 307
  • 47
    This does not help in my case. I set it to "YES" but I am still getting the error. Any ideas? – davidOhara Nov 01 '19 at 16:14
  • 3
    I'm working with **Carthage** and 10 frameworks...ish. Is `carthage` smart enough to pick this up from _my_ **.pbxproj** file, or as @MihaiFratu says above, do all third party framework developers need to set this themselves in their framework projects? – nteissler Nov 01 '19 at 16:25
  • @nteiss I believe Carthage is compiling the frameworks from source for you? In that case this setting doesn’t matter because you just recompile them again. It’s important for us because we distribute frameworks in binary form to other people. I used RxSwift above as an example – Orion Edwards Nov 03 '19 at 18:43
  • 14
    @davidOhara in my case it had to do with this known issue in Xcode 11.2: If a module is built with BUILD_LIBRARIES_FOR_DISTRIBUTION and contains a public type with the same name as the module itself, clients will fail to import the module. (19481048) (FB5863238) in the Xcode 11.2 release notes: https://developer.apple.com/documentation/xcode_release_notes/xcode_11_2_release_notes – Richard Chirino Nov 04 '19 at 14:53
  • 1
    @RichardChirino Is there any workaround, but not to rename the module? – davidOhara Nov 05 '19 at 12:17
  • 1
    @HunaidHassan As the class is added via CocoaPod, I can not just rename it... – davidOhara Nov 05 '19 at 15:09
  • 2
    @davidOhara Sadly I haven't found a workaround. For us renaming the class is also not possible as it's the main class of our framework and would break our customer's code. If I build the framework using Xcode 11.2 then it does compile on Xcode 11.2 but it will not compile on 11.1 or earlier. Today's Xcode 11.2.1 GM release has not fixed the issue. Here's the ticket on the swift issue tracker in case you want to keep an eye on it: https://bugs.swift.org/browse/SR-11704 There's also a radar attached to it. – Richard Chirino Nov 06 '19 at 09:03
  • Superb !! Its Work. – Vinayak Bhor Nov 06 '19 at 11:08
  • What if the package is built with SPM? – Andrea Miotto Dec 10 '19 at 18:37
  • @RichardChirino I'm seeing this issue with Xcode 11.3, as well. – Adrian Dec 27 '19 at 04:31
  • Don't forget to mark this answer as the answer to your question as it helps those of us quickly skimming for valid answers, even if you hardly get any reputation from doing so. – Stunner Feb 13 '20 at 03:05
  • 1
    @Stunner - I'd intended to mark it as accepted originally, but StackOverflow blocks you from accepting self-answers for a time period, and I forgot to come back. Thanks for the bump! – Orion Edwards Feb 14 '20 at 01:28
  • The legacy build system does not support building projects with Swift when SWIFT_ENABLE_LIBRARY_EVOLUTION is enabled. How to fix this? – Harikarthick K Apr 08 '20 at 05:18
  • 1
    This solution works fine up to xcode 11.3, but does not work in 11.3.1 – Saleh Enam Shohag Apr 23 '20 at 13:56
  • @SalehEnamShohag could you elaborate? I have binary frameworks built with Xcode 11.0 using `BUILD_LIBRARY_FOR_DISTRIBUTION = YES` and they worked perfectly under Xcode 11.3.1 and also under Xcode 11.4. What problem are you experiencing? – Orion Edwards Apr 24 '20 at 03:22
  • @OrionEdwards, I got the error "Module compiled with Swift 5.1 cannot be imported by the Swift 5.1.3 compiler:" – Saleh Enam Shohag Apr 24 '20 at 05:25
  • Xcode 11.4.1 not work for me. any suggestions? please – neo999 May 06 '20 at 10:37
  • module compiled with Swift 5.0 cannot be imported by the Swift 5.2.2 compiler in xCode 11.4.1 for razorpay. Not working in XCode 11.4.1 for me. any help please? – Indra KP May 08 '20 at 05:30
  • `BUILD_LIBRARY_FOR_DISTRIBUTION = YES` has been enabled, but it caused another problem which is `:0: error: using bridging headers with module interfaces is unsupported`. Xcode version is 11.4.1.Swift version is 5.2.2. But also `To submit to the App Store you must build your app using the version of Swift that comes included within Xcode.`,original error is `Module compiled with Swift 5.0.1 cannot be imported by the Swift 5.2.2 compiler`,does that means I cannot use `toolchain Swift 5.01` to solve this problem? – zionpi May 09 '20 at 07:43
  • 1
    no Help Still getting same error. Even i do and also clean build but no luck.! BUILD_LIBRARY_FOR_DISTRIBUTION = YES – M Murteza Sep 04 '20 at 12:41
  • me too :( just downloaded the latest playground template from here https://developer.apple.com/download/more/ and it won't compile – Chris Sep 29 '20 at 13:38
7

Module stability and Library evolution support for closed source

[ABI]

Swift v5.0 introduced stable ABI

Swift v5.1 shipped Module stability and Library evolution support which are applicable for closed source(binary) framework(library)(framework is build separately from consumer)

Check Swift version:

Swift Language Version(SWIFT_VERSION)

To enable it you should use Xcode from v11:

Build Libraries for Distribution (BUILD_LIBRARY_FOR_DISTRIBUTION)

Select framework target -> Build Settings -> Build Libraries for Distribution (BUILD_LIBRARY_FOR_DISTRIBUTION) -> Yes

swiftc flags:

-enable-library-evolution
-emit-module-interface

This setting generates .swiftinterface

Swift Module Interfaces (.swiftinterface)

Swift Module uses the same approach as Objective-C module uses - precompiled binary or Compiled Module.

Swift Module Interfaces is a textual representation of module's public API. It is an Swift's alternative for Objective-C's headers .h files.

//previously
consumer(app) -> import Module -> producer(framework) .swiftmodule

//using .swiftinterface
consumer(app) -> import Module -> .swiftinterface -> producer(framework) .swiftmodule

Despite of .swiftmodule which is changeable where you can get

Module compiled with _ cannot be imported by the _ compiler

.swiftinterface is stable and do not need to be update when something changed(e.g. Swift version)

no assamptions

It is located in next folder

<framework_name>.framework/Modules/<framework_name>.swiftmodule

It looks like:

// swift-interface-format-version: 1.0
// swift-compiler-version: Apple Swift version 5.2.4 (swiftlang-1103.0.32.9 clang-1103.0.32.53)
// swift-module-flags: -target x86_64-apple-ios12.2-simulator -enable-objc-interop -enable-library-evolution -swift-version 5 -enforce-exclusivity=checked -Onone -module-name UtilsSwiftFramework
import Foundation
import Swift
@_exported import UtilsSwiftFramework
@_inheritsConvenienceInitializers @objc public class GFISClassA : ObjectiveC.NSObject {
  @objc public static var shared: UtilsSwiftFramework.GFISClassA
  @objc public func GFISprintHelloWorld()
  @objc public func GFISprintHelloWorld(arg1: Swift.String, arg2: Swift.String)
  @objc deinit
  @objc override dynamic public init()
}

As you see it additionally it contains:

swift-interface-format-version
swift-compiler-version
swift-module-flags

*You can get next error if you use dynamic without @objc[About]

Marking non-'@objc' Swift declaration 'dynamic' in library evolution mode is not supported

XCFramework[About] forces you to use it

Apple recommends to use .swiftinterface for closed source and Swift Package Manager[About] for open source

yoAlex5
  • 13,571
  • 5
  • 105
  • 98
2

This made my compiler error go away.

  1. carthage bootstrap --platform ios
  2. brew bundle
  3. pod repo update
Rinni
  • 87
  • 2
  • 1
    `brew bundle`? what does it do? – skywinder Apr 16 '20 at 04:41
  • 9
    Downvote because with carthage you're rebuilding your library on the new compiler. The question is explicitly about loading binary libraries built by the previous compiler – Orion Edwards Apr 19 '20 at 01:54
  • I ran the above commands, and still getting similar build errors: ~"**Skipped installing RxSwift.framework binary due to the error: Incompatible Swift version - framework was built with 5.2.2 (swiftlang-1103.0.32.6 clang-1103.0.32.51) and the local version is 5.1.3 (swiftlang-1100.0.282.1 clang-1100.0.33.15).**" – IgorGanapolsky Jul 29 '20 at 21:05
1

I had the same error importing 3rd party libraries. I fixed it using toolchains in Xcode and taking the release September 19 2019 from here https://swift.org/download/#releases. After that I had to re-import my libraries and it worked.

Sergio
  • 27
  • 1
  • 1
    I have problem on framework Module compiled with Swift 5.1.2 cannot be imported by the Swift 5.2.2 how can we solve this problem ? – Kishan Suthar Apr 18 '20 at 20:17
-1

I experienced this on repo after moving back to Xcode 11.3.1 from Xcode 12.3. I had summarily updated my Command Line Tools and needed to revert them to the earlier version in order to get my dependency building.

Dharman
  • 21,838
  • 18
  • 57
  • 107
Pigpocket
  • 181
  • 2
  • 14
-3

You can use Carthage to add the RxSwift framework.

Basically, Carthage gives you a similar traditional RxSwift.framework style package.

Then try carthage update --no-use-binaries.

iMoeNya
  • 414
  • 2
  • 8
  • 4
    Downvote because with carthage you're just rebuilding your library on the new compiler. The question is explicitly about loading binary libraries built by the previous compiler – Orion Edwards Apr 19 '20 at 01:54
-3

I ran into the same issue where I only switched branches. I deleted derived data + clean build a few times. It didn't work until I restarted Xcode

Honey
  • 24,125
  • 14
  • 123
  • 212