Skip to content
This repository was archived by the owner on Apr 11, 2024. It is now read-only.

Added support for Catalyst #20

Merged
merged 4 commits into from
Oct 20, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ jobs:
path: Vexil

- name: 📦 Package Vexil
run: cd Vexil && ../.build/release/swift-create-xcframework --zip --zip-version 1.2.2 --platform ios --platform macos --platform tvos --platform watchos Vexil Vexillographer
run: cd Vexil && ../.build/release/swift-create-xcframework --zip --zip-version 1.2.2 --platform ios --platform macos --platform tvos --platform watchos

tests-xcode-12:
name: Test Builds - Xcode 12
Expand All @@ -57,4 +57,4 @@ jobs:
path: Vexil

- name: 📦 Package Vexil
run: cd Vexil && ../.build/release/swift-create-xcframework --zip --zip-version 1.2.2 --platform ios --platform macos --platform tvos --platform watchos Vexil Vexillographer
run: cd Vexil && ../.build/release/swift-create-xcframework --zip --zip-version 1.2.2 --platform ios --platform macos --platform tvos --platform watchos
8 changes: 6 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,10 @@ You can specify a subset of the platforms to build using the `--platform` option
swift create-xcframework --platform ios --platform macos ...
```

#### Catalyst

You can build your XCFrameworks with support for Mac Catalyst by specifying `--platform maccatalyst` on the command line. As you can't include or exclude Catalyst support in your `Package.swift` we don't try to build it automatically.

### Choosing Products

Because we wrap `xcodebuild`, you can actually build XCFrameworks from anything that will be mapped to an Xcode project as a Framework target. This includes all of the dependencies your Package has.
Expand Down Expand Up @@ -126,7 +130,7 @@ jobs:
- uses: actions/checkout@v2

- name: Create XCFramework
uses: unsignedapps/swift-create-xcframework@v1
uses: unsignedapps/swift-create-xcframework@v1.3

# Create a release
# Upload those artifacts to the release
Expand All @@ -137,7 +141,7 @@ jobs:
You can install using mint:

```shell
mint install unsignedapps/swift-create-xcframework@1.0.5
mint install unsignedapps/swift-create-xcframework@1.3.0
```

Or manually:
Expand Down
4 changes: 2 additions & 2 deletions Sources/CreateXCFramework/Command+Options.swift
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ extension Command {
valueName: TargetPlatform.allCases.map({ $0.rawValue }).joined(separator: "|")
)
)
var platform: [TargetPlatform]
var platform: [TargetPlatform] = []

@Option(help: ArgumentHelp("Where to place the compiled .xcframework(s)", valueName: "directory"))
var output = "."
Expand All @@ -69,7 +69,7 @@ extension Command {
// MARK: - Targets

@Argument(help: "An optional list of products (or targets) to build. Defaults to building all `.library` products")
var products: [String]
var products: [String] = []
}
}

Expand Down
2 changes: 1 addition & 1 deletion Sources/CreateXCFramework/Command.swift
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ struct Command: ParsableCommand {

Supported platforms: \(TargetPlatform.allCases.map({ $0.rawValue }).joined(separator: ", "))
""",
version: "1.2.1"
version: "1.3.0"
)


Expand Down
9 changes: 5 additions & 4 deletions Sources/CreateXCFramework/PackageInfo.swift
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,8 @@ struct PackageInfo {
/// check if our command line platforms are supported by the package definition
func supportedPlatforms () throws -> [TargetPlatform] {

let supported = self.options.platform.nonEmpty ?? TargetPlatform.allCases
// if they have specified platforms all good, if not go everything except catalyst
let supported = self.options.platform.nonEmpty ?? TargetPlatform.allCases.filter { $0 != .maccatalyst }

// do we have package platforms defined?
guard let packagePlatforms = self.manifest.platforms.nonEmpty else {
Expand All @@ -169,11 +170,11 @@ struct PackageInfo {

// filter our package platforms to make sure everything is supported
let target = packagePlatforms
.compactMap { platform -> TargetPlatform? in
return supported.first(where: { $0.rawValue == platform.platformName })
.compactMap { platform -> [TargetPlatform]? in
return supported.filter({ $0.platformName == platform.platformName })
}
.flatMap { $0 }

// are they different then?
return target
}

Expand Down
35 changes: 26 additions & 9 deletions Sources/CreateXCFramework/Platforms.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import PackageModel
enum TargetPlatform: String, ExpressibleByArgument, CaseIterable {
case ios
case macos
case maccatalyst
case tvos
case watchos

Expand All @@ -19,36 +20,52 @@ enum TargetPlatform: String, ExpressibleByArgument, CaseIterable {
}


var platformName: String {
switch self {
case .ios: return "ios"
case .macos: return "macos"
case .maccatalyst: return "macos"
case .tvos: return "tvos"
case .watchos: return "watchos"
}
}

// MARK: - Target SDKs

struct SDK {
let sdkName: String
let directorySuffix: String
let destination: String
let archiveName: String
let buildSettings: [String: String]?
}

var sdks: [SDK] {
switch self {
case .ios:
return [
SDK(sdkName: "iphoneos", directorySuffix: "-iphoneos"),
SDK(sdkName: "iphonesimulator", directorySuffix: "-iphonesimulator")
SDK(destination: "generic/platform=iOS", archiveName: "iphoneos.xcarchive", buildSettings: nil),
SDK(destination: "generic/platform=iOS Simulator", archiveName: "iphonesimulator.xcarchive", buildSettings: nil)
]

case .macos:
return [
SDK(sdkName: "macosx", directorySuffix: "")
SDK(destination: "platform=macOS", archiveName: "macos.xcarchive", buildSettings: nil)
]

case .maccatalyst:
return [
SDK(destination: "platform=macOS,variant=Mac Catalyst", archiveName: "maccatalyst.xcarchive", buildSettings: [ "SUPPORTS_MACCATALYST": "YES" ])
]

case .tvos:
return [
SDK(sdkName: "appletvos", directorySuffix: "-appletvos"),
SDK(sdkName: "appletvsimulator", directorySuffix: "-appletvsimulator")
SDK(destination: "generic/platform=tvOS", archiveName: "appletvos.xcarchive", buildSettings: nil),
SDK(destination: "generic/platform=tvOS Simulator", archiveName: "appletvsimulator.xcarchive", buildSettings: nil)
]

case .watchos:
return [
SDK(sdkName: "watchos", directorySuffix: "-watchos"),
SDK(sdkName: "watchsimulator", directorySuffix: "-watchsimulator")
SDK(destination: "generic/platform=watchOS", archiveName: "watchos.xcarchive", buildSettings: nil),
SDK(destination: "generic/platform=watchOS Simulator", archiveName: "watchsimulator.xcarchive", buildSettings: nil)
]
}
}
Expand Down
5 changes: 4 additions & 1 deletion Sources/CreateXCFramework/ProjectGenerator.swift
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,10 @@ struct ProjectGenerator {
graph: self.package.graph,
extraDirs: [],
extraFiles: [],
options: XcodeprojOptions(xcconfigOverrides: (self.package.overridesXcconfig?.path).flatMap { AbsolutePath($0) }),
options: XcodeprojOptions (
xcconfigOverrides: (self.package.overridesXcconfig?.path).flatMap { AbsolutePath($0) },
useLegacySchemeGenerator: true
),
diagnostics: self.package.diagnostics
)

Expand Down
57 changes: 36 additions & 21 deletions Sources/CreateXCFramework/XcodeBuilder.swift
Original file line number Diff line number Diff line change
Expand Up @@ -68,21 +68,23 @@ struct XcodeBuilder {
// MARK: - Build

func build (targets: [String], sdk: TargetPlatform.SDK) throws -> [String: Foundation.URL] {
let process = TSCBasic.Process (
arguments: try self.buildCommand(targets: targets, sdk: sdk),
outputRedirection: .none
)

try process.launch()
let result = try process.waitUntilExit()

switch result.exitStatus {
case let .terminated(code: code):
if code != 0 {
throw Error.nonZeroExit(code)
for target in targets {
let process = TSCBasic.Process (
arguments: try self.buildCommand(target: target, sdk: sdk),
outputRedirection: .none
)

try process.launch()
let result = try process.waitUntilExit()

switch result.exitStatus {
case let .terminated(code: code):
if code != 0 {
throw Error.nonZeroExit(code)
}
case let .signalled(signal: signal):
throw Error.signalExit(signal)
}
case let .signalled(signal: signal):
throw Error.signalExit(signal)
}

return targets
Expand All @@ -91,29 +93,40 @@ struct XcodeBuilder {
}
}

private func buildCommand (targets: [String], sdk: TargetPlatform.SDK) throws -> [String] {
private func buildCommand (target: String, sdk: TargetPlatform.SDK) throws -> [String] {
var command: [String] = [
"xcrun",
"xcodebuild",
"-project", self.path.pathString,
"-configuration", self.options.configuration.xcodeConfigurationName,
"-sdk", sdk.sdkName,
"BUILD_DIR=\(self.buildDirectory.path)"
"-archivePath", self.buildDirectory.appendingPathComponent(self.productName(target: target)).appendingPathComponent(sdk.archiveName).path,
"-destination", sdk.destination,
"BUILD_DIR=\(self.buildDirectory.path)",
"SKIP_INSTALL=NO"
]

// add any build settings
if let settings = sdk.buildSettings {
for setting in settings {
command.append("\(setting.key)=\(setting.value)")
}
}

// add our targets
command += targets.flatMap { [ "-target", $0 ] }
command += [ "-scheme", target ]

// and the command
command += [ "build" ]
command += [ "archive" ]

return command
}

// we should probably pull this from the build output but we just make assumptions here
private func frameworkPath (target: String, sdk: TargetPlatform.SDK) -> Foundation.URL {
return self.buildDirectory
.appendingPathComponent(self.options.configuration.xcodeConfigurationName + sdk.directorySuffix)
.appendingPathComponent(self.productName(target: target))
.appendingPathComponent(sdk.archiveName)
.appendingPathComponent("Products/Library/Frameworks")
.appendingPathComponent("\(self.productName(target: target)).framework")
.absoluteURL
}
Expand All @@ -124,6 +137,9 @@ struct XcodeBuilder {
func merge (target: String, frameworks: [Foundation.URL]) throws -> Foundation.URL {
let outputPath = self.xcframeworkPath(target: target)

// try to remove it if its already there, otherwise we're going to get errors
try? FileManager.default.removeItem(at: outputPath)

let process = TSCBasic.Process (
arguments: self.mergeCommand(outputPath: outputPath, frameworks: frameworks),
outputRedirection: .none
Expand Down Expand Up @@ -156,7 +172,6 @@ struct XcodeBuilder {

// and the output
command += [ "-output", outputPath.path ]

return command
}

Expand Down