Well I see it a bit like the asset catalog support. That's an Xcode feature (if I'm not mistaken), and is a detail of the private SPM fork that Xcode uses (handwavy and probably technically inaccurate).
but we digress from the original topic… sorry
Well I see it a bit like the asset catalog support. That's an Xcode feature (if I'm not mistaken), and is a detail of the private SPM fork that Xcode uses (handwavy and probably technically inaccurate).
but we digress from the original topic… sorry
swift build
supports consuming XCFrameworks imported via .binaryTarget()
. It's not just an Xcode feature.
Has anyone filed an ERs are about this? If so, I’d appreciate you posting any FB numbers (for xcodebuild
) or issue links (for SwiftPM).
Share and Enjoy
Quinn “The Eskimo!” @ DTS @ Apple
Is there a solution to this yet?
Super annoying when trying to make a prebuild SPM plugin because they require a binary target.
I'm struggling to make it work with an SPM that uses @_exported import
.
The Library i try to wrap into the xcframework uses a shared target. Upon importing the created xcframework it throws the issue No such module
(for the @_exported import).
Any idea how to resolve it? Are only the module headers missing or is the code actually missing?
Building an XCFramework is not a platform support, it's Xcode support. I'm not convinced that building an XCFramework is needed at all if you want to use a shared library. Why not just build a dynamic library? That should work on any platform, including Apple platforms.
A distinction without a difference given that Xcode bundles all of the platform support tools. Supporting Xcode is supporting the platforms. xcframework
s are the only way to produce universal frameworks for Apple platforms. This is not a secret process, and Xcode uses libSPM to enable such builds internally. Making SPM itself aware of the format simply moves the support logic down a level and could allow better support for cross compilation. Hell, Apple could limit such support to their version of SPM, they build all of the tools for themselves anyway.
I didn't know that. BTW, what is the difference between "universal frameworks" and "shared libraries"?
If you need just a shared library, here's my example on how one can do that (a proof of concept, to demonstrate that what works on other platforms, certainly works on a Mac):
mkdir test
cd test
swift package init
// Modify the Package.swift *products* section so that the package would produce a *dynamic* library:
.library(
name: "test",
type: .dynamic, // specify this to create a dynamic library
targets: ["test"]),
// Add some public code into the test.swift file, e.g.
public func meaningOfLife() -> Int {
return 42
}
swift build -c release
cd ..
mkdir app
cd app
swift package init --type executable
// Add some code to main.swift that uses shared code from the library, e.g.
import test
print("Meaning of life is \(meaningOfLife())")
// Build the app and link it against the library:
swift build -c release -Xswiftc -I -Xswiftc "./../test/.build/release" -Xswiftc -L -Xswiftc "./../test/.build/release" -Xswiftc -l -Xswiftc test
cp ./../test/.build/release/libtest.dylib .build/release/
.build/release/app
Meaning of life is 42
I say universal because they can be truly universal across all of Apple's platforms. A single bundle can contain macOS, iOS, iOS simulator, and everything else.
But of course we've had dylib
support forever. But it's not what we use on Apple platforms. Before .xcframework
s there were .framework
s (with a history going all the way back to NeXTStep) which can contain what are essentially dylibs (even fat dylibs (PPC/Intel, Intel/AS)) with all sorts of other resources. They can even contain multiple versions, though Apple has never used this capability. xcframework
s go one step beyond framework
s and allow ABI incompatible (probably not the right term) platforms to bundle their framework
s together into one super bundle. It's mostly a bundling mechanism but it requires particular structure and metadata. But it's truly universal: every OS, every simulator, every architecture, all in one bundle.
Ah, now I see. I think these are cool for using in Xcode. The original question by @Srdan_Rasic was about
I thought that dylib
files would be a solution for that, especially when using Swift Package Manager rather than Xcode.
I thought that dylib files would be a solution for that
It depends on what you mean by “universal” |-:
On Apple platforms a universal Mach-O can hold multiple architectures for the same platform. However, if you want to support multiple platforms you need an XCFramework. And, critically, iOS and the iOS Simulator are different platforms, so this requirements comes up all the time.
Share and Enjoy
Quinn “The Eskimo!” @ DTS @ Apple
@Srdan_Rasic Although it works for a simple SPM without any SPM dependencies, it fails when at least one SPM dependency exists. Is there something I am missing?
There was a request here and in the linked Apple Developer Forum post to create Feedback asking for this functionality. If it helps, I created FB13812783
to request this capability built-in to Xcode.
Forked variant has had updates which seems to work for me.
Although in some cases I needed to use
@_implementationOnly import Kingfisher
or new:
internal import Kingfisher
in order for projecting linking xcframework to work.
Hello, since this thread is years old, I wanted to ask about the latest status.
If I want to compile an xcframework from an SPM package, is it still the case that the only way to do that is by using the third-party tool from segment-integrations?
Just to ensure I'm not committing an XY problem, here's what I'm actually after in the form of a specific question. Given that:
if I wanted to compile a dependency like SwiftNIO as xcframeworks and pull them into my project, what is the current practice for doing so?
As there is no official support for building XCFramework from a Swift Package yet, the swift-create-xcframework
seems to be the best solution I found so far among many.
The idea behind that tool is to build from a Swift package Package.swift
, so I'm not sure the relevance of needing a .xcodeproj
for SwiftNIO as you mention?
My understanding is the Xcode 16 updates to Explicitly Built Modules should optimise the source-based dependencies: