How do you enable bitcode for a Swift Package?

How do you enable bitcode for a Swift Package?

Tried this but it doesn't seem to do anything:
swiftSettings: [SwiftSetting.define("ENABLE_BITCODE=YES")]

Also tried this:

            cxxSettings: [.define("ENABLE_BITCODE", to: "YES", .when(configuration: .release)), .define("BITCODE_GENERATION_MODE", to: "bitcode", .when(configuration: .release))]

This also fails.

Reason I need this: when I'm building our app, I am suddenly getting this error:

All frameworks and dylibs for bitcode must be generated from 
Xcode Archive or Install build file '/Users/REDACTED/code/ios
/DerivedData/REDACTED/Build/Products/Release-iphoneos
/PackageFrameworks/REDACTED.framework/REDACTED' 
for architecture arm64

Were you ever able to come up with a solution for this?

Sadly no. I'm reposting to ask if anyone knows a way to disable it now, see my other post here. I'm getting very close to throwing in the towel on using SPM for anything important.

Sadly no luck. This seems to be another one of the settings that Xcode magically infers based on certain context that you, the Package developer have no control over.

While using SPM bitcode should be automatically enabled. When you embed your swift package into your project simply turn bitcode on. However any dependency your swift package depends on needs to have bitcode enabled if it is like a binary. So if that is the case you will need to build the dependency yourself from the framework or static library with bitcode enabled.

My problem is that I need to be able to manually disable bitcode for cases where XCTest is a dependency of a package, because XCTest has not been built with bitcode.

So, the fact that XCode automatically turns on bitcode for a non-test target of a Swift package means that everything that target depends on must also have been built with bitcode on, which is not the case for XCTest.

That's a blocking issue for me.

Why on earth did Apple decide to make bitcode an automatic setting with no manual overrides?

Sorry for the confusion and the struggles you are having. I’m not sure exactly what you are working with, but according to DTS when you are working with a swift package there is no setting to be able to enable bitcode, when the swift package is built that is when Xcode applies bitcode to be enabled. So what you are saying is that you are using a dependency in your test that doesn’t have bitcode enabled? Is it like a Mock library, if so is there another library you can use instead? That might be worth looking into. It is recommended that framework authors enable bitcode to give the SDK consumer the freedom to choose bitcode or no bitcode.

Tell that to whoever wrote XCTest framework!

Someone in my org made a Swift package that adds some custom extensions to XCTest. But it won't compile because the package has bitcode enabled by default and XCTest doesn't.

Just another example of how SPM is not suited for mainstream use yet.

SPM is not really a viable replacement for Xcode project files as a way to define local modules. The way SPM is integrated with Xcode and the design of SPM itself are not built for the same use-cases as Xcode project files and do not allow you to do many things that Xcode projects can do. This makes it totally ill-suited for use as a replacement for Xcode project files for local use, and Apple and other people should never have started recommending it to people as such, because they made no effort to ensure feature parity or to guarantee that for a particular setting or use-case, SPM supports the same capabilities as Xcode project files.

For example SPM:

  • does not support linking a package target to a third-party pre-built framework or XCFramework dependency outside the directory structure of the package itself
  • does not support directly providing an .xcassetcatalog to consumers of a package
  • does not support mixed Obj.C/Swift targets
  • does not support linking a package target to a local Xcode project's build product
  • does not support Xcode's "find implicit dependencies" properly and turning it off leads to phantom dependency cycles unless you list every package in your workspace in the build list
  • does not support linking an Xcode project to a locally-defined Swift package if it uses any "unsafe" flags, which is clearly a bug but no effort has been made to fix it

Every time some measures have been taken to rectify some of these many problems, after going through the Swift evolution process, the resulting change to SPM winds up not addressing the actual need at all. For example when people complained SPM does not allow linking to a prebuilt binary, the "solution" for this was to allow SPM to link to prebuilt binaries—but only if they are inside the directory structure of the package itself, rendering this feature totally useless for most situations in which we need to link to a binary. Or when they added support for AssetCatalogs, they made it extremely limited by forcing you to write a public API to access anything from in the catalog—making this totally incapable of serving assets to a mixed Swift/Obj.C consumer because @objc Swift APIs in Swift packages can't be seen by Obj. C code in consumers of that package, due to the fact that the package framework that gets produced is always missing its Frameworks folder (and thus, there's no bridging header!).

I could go on and on; earlier this year it had become almost a part-time job for me to try to actually report all the SPM bugs and issues to Apple and to constantly get pulled into Zoom calls with other engineers who were running into yet another new bug with the SPM/Xcode integration and no clear solutions. Evenutally I got to the point where I will no longer recommend anyone to use SPM for anything else until I see some actual fixes in a future Xcode.

Which is sad because we can't even use SPM as a package manager due to all the performance issues related to that use-case. Just trying to add Firebase as a dependency takes 15-20 minutes to get past the first step where you paste in the repo URL into Xcode's "Add a remote package dependency" window. on a gigabit connection, because the UI is blocked until Firebase and all its package dependencies, and all those packages' package dependencies, are deep-cloned into a local cache. And then another 15-20 minutes after adding it as a dependency for the same operation to happen again.

12.5 did add the ability for Xcode to cache the result of all this madness so subsequent times when you open the project it will only take a minute or so, but since our CI system rebuilds each Jenkins node from scratch every time, we can't justify adding 20 minutes to our build times. Even if we could due to some new cacheing solution that doesn't exist yet, having all of Firebase's dependencies show up in the remote package dependencies list in Xcode causes the whole IDE to slow down noticeably for some reason.

I have nothing against SPM and I think it's fine for certain use-cases but it has not proven to be ready yet to replace Carthage for a large enterprise app and it's somewhat limited in how you can use it for replacing local Xcode projects. As long as you use it within the safe boundaries of what it currently does well, then it's fine, but this year we've been constantly running into issue after issue where SPM is unable to do something that, by all accounts, it should be able to do, and it's gotten to the point after multiple DTS tickets and no progress made in Xcode that I've started to wonder what's actually going on.

1 Like
Terms of Service

Privacy Policy

Cookie Policy