Skip to content

XCFramework Format

XCFramework is Apple’s cross-platform binary distribution format, bundling prebuilt libraries and headers for multiple platforms in a single package. The Swift toolchain for Android and scd both support Android platforms within XCFrameworks.

A generic XCFramework has the following layout in the filesystem:

<name>.xcframework
├ Info.plist
├ <platform-1>
│ ├ Headers
│ │ ├ module.modulemap
│ │ └ <header files for platform-1>
│ └ lib<name>.so
├ <platform-2>
│ ├ Headers
│ │ ├ module.modulemap
│ │ └ <header files for platform-2>
│ └ lib<name>.so

The Info.plist manifest describes supported platforms and the paths to dynamic libraries and header files for each platform.

Here is an example of the Info.plist manifest for the foo library, for Android arm64 and x86_64 platforms:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>AvailableLibraries</key>
<array>
<dict>
<key>BinaryPath</key>
<string>libfoo.so</string>
<key>HeadersPath</key>
<string>Headers</string>
<key>LibraryIdentifier</key>
<string>android-arm64-v8a</string>
<key>LibraryPath</key>
<string>libfoo.so</string>
<key>SupportedArchitectures</key>
<array>
<string>aarch64</string>
</array>
<key>SupportedPlatform</key>
<string>android</string>
</dict>
<dict>
<key>BinaryPath</key>
<string>libfoo.so</string>
<key>HeadersPath</key>
<string>Headers</string>
<key>LibraryIdentifier</key>
<string>android-x86_64</string>
<key>LibraryPath</key>
<string>libfoo.so</string>
<key>SupportedArchitectures</key>
<array>
<string>x86_64</string>
</array>
<key>SupportedPlatform</key>
<string>android</string>
</dict>
</array>
<key>CFBundlePackageType</key>
<string>XFWK</string>
<key>XCFrameworkFormatVersion</key>
<string>1.0</string>
</dict>
</plist>

The corresponding filesystem layout for this XCFramework is:

foo.xcframework
├ Info.plist
├ android-arm64-v8a
│ ├ Headers
│ │ ├ module.modulemap
│ │ └ foo.h
│ └ libfoo.so
├ android-x86_64
│ ├ Headers
│ │ ├ module.modulemap
│ │ └ foo.h
│ └ libfoo.so

To use an XCFramework in the Package.swift manifest, add it as a binary target:

.binaryTarget(
name: "foo",
path: "relative/path/to/foo.xcframework"
)

After that, the foo target can be used in the list of dependencies for any target in the SPM project. See Linking Native Libraries and Embedding Native Libraries for how scd uses XCFrameworks when building and archiving.