From b426506ef612c09db18abc55ee84fe6a0fafc024 Mon Sep 17 00:00:00 2001 From: Brandon Sneed Date: Wed, 27 Mar 2024 14:18:42 -0700 Subject: [PATCH 1/6] Update README.md --- README.md | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 51ce9da..5e2bee2 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,7 @@ +# NOTE: + +This tool is a maintained fork of the original unsignedapps/swift-create-xcframework. This unlinked fork started off to add Xcode 15 support, after waiting for 8+ months for the original author to merge the PR. Things like the github action, and mint installation haven't been tested. It's currently been set up to install via `brew` or manually. More to come, please file bugs/PRs here. + # swift-create-xcframework swift-create-xcframework is a very simple tool designed to wrap `xcodebuild` and the process of creating multiple frameworks for a Swift Package and merging them into a single XCFramework. @@ -138,10 +142,10 @@ jobs: ## Installation -You can install using mint: +You can install using brew: ```shell -mint install unsignedapps/swift-create-xcframework +brew install segment-integrations/formulae/swift-create-xcframework ``` Or manually: From c229d13fbe3935abfe3d325af86f95305a833fe7 Mon Sep 17 00:00:00 2001 From: Hanley Lee Date: Sat, 1 Jun 2024 11:48:54 +0800 Subject: [PATCH 2/6] fix: user encounter error when use option: `--xc-setting OTHER_SWIFT_FLAGS="-debug-prefix-map $PWD=."` --- Sources/CreateXCFramework/BuildSetting.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sources/CreateXCFramework/BuildSetting.swift b/Sources/CreateXCFramework/BuildSetting.swift index a7482c7..afddc0d 100644 --- a/Sources/CreateXCFramework/BuildSetting.swift +++ b/Sources/CreateXCFramework/BuildSetting.swift @@ -16,7 +16,7 @@ struct BuildSetting: ExpressibleByArgument { let value: String init?(argument: String) { - let components = argument.components(separatedBy: "=") + let components = argument.split(separator: "=", maxSplits: 1) guard components.count == 2 else { return nil } self.name = components[0].trimmingCharacters(in: .whitespacesAndNewlines) self.value = components[1].trimmingCharacters(in: .whitespacesAndNewlines) From 0f3122108afb99874127241531534227067ddcf2 Mon Sep 17 00:00:00 2001 From: Hanley Lee Date: Sat, 1 Jun 2024 12:39:07 +0800 Subject: [PATCH 3/6] add 'action' option, can assign 'build' or 'archive' --- .../CreateXCFramework/Command+Options.swift | 3 ++ .../CreateXCFramework/XcodeBuildAction.swift | 13 ++++++++ Sources/CreateXCFramework/XcodeBuilder.swift | 32 ++++++++++++++----- 3 files changed, 40 insertions(+), 8 deletions(-) create mode 100644 Sources/CreateXCFramework/XcodeBuildAction.swift diff --git a/Sources/CreateXCFramework/Command+Options.swift b/Sources/CreateXCFramework/Command+Options.swift index 238e46c..551cda9 100644 --- a/Sources/CreateXCFramework/Command+Options.swift +++ b/Sources/CreateXCFramework/Command+Options.swift @@ -25,6 +25,9 @@ extension Command { @Option(help: ArgumentHelp("Build with a specific configuration", valueName: "debug|release")) var configuration = PackageModel.BuildConfiguration.release + @Option(help: ArgumentHelp("Action used to create artifact", valueName: "archive|build")) + var action: XcodeBuildAction = .archive + @Flag(inversion: .prefixedNo, help: "Whether to clean before we build") var clean = true diff --git a/Sources/CreateXCFramework/XcodeBuildAction.swift b/Sources/CreateXCFramework/XcodeBuildAction.swift new file mode 100644 index 0000000..7c3da5a --- /dev/null +++ b/Sources/CreateXCFramework/XcodeBuildAction.swift @@ -0,0 +1,13 @@ +// +// XcodeBuildAction.swift +// swift-create-xcframework +// +// Created by Hanley Lee on 2024/6/1. +// + +import ArgumentParser + +enum XcodeBuildAction: String, ExpressibleByArgument { + case build + case archive +} diff --git a/Sources/CreateXCFramework/XcodeBuilder.swift b/Sources/CreateXCFramework/XcodeBuilder.swift index a48b1e9..9c1de7f 100644 --- a/Sources/CreateXCFramework/XcodeBuilder.swift +++ b/Sources/CreateXCFramework/XcodeBuilder.swift @@ -109,12 +109,17 @@ struct XcodeBuilder { "xcodebuild", "-project", self.path.pathString, "-configuration", self.options.configuration.xcodeConfigurationName, - "-archivePath", self.buildDirectory.appendingPathComponent(self.productName(target: target)).appendingPathComponent(sdk.archiveName).path, "-destination", sdk.destination, "BUILD_DIR=\(self.buildDirectory.path)", "SKIP_INSTALL=NO" ] + if self.options.action == .archive { + command += [ + "-archivePath", self.buildDirectory.appendingPathComponent(self.productName(target: target)).appendingPathComponent(sdk.archiveName).path, + ] + } + // add SDK-specific build settings if let settings = sdk.buildSettings { for setting in settings { @@ -136,19 +141,30 @@ struct XcodeBuilder { command += [ "-scheme", target ] // and the command - command += [ "archive" ] + if self.options.action == .build { + command += [ "build" ] + } else { + 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.productName(target: target)) - .appendingPathComponent(sdk.archiveName) - .appendingPathComponent("Products/Library/Frameworks") - .appendingPathComponent("\(self.productName(target: target)).framework") - .absoluteURL + if self.options.action == .build { + return self.buildDirectory + .appendingPathComponent(sdk.releaseFolder) + .appendingPathComponent("\(self.productName(target: target)).framework") + .absoluteURL + } else { + return self.buildDirectory + .appendingPathComponent(self.productName(target: target)) + .appendingPathComponent(sdk.archiveName) + .appendingPathComponent("Products/Library/Frameworks") + .appendingPathComponent("\(self.productName(target: target)).framework") + .absoluteURL + } } // MARK: - Debug Symbols From c094bd16c1c7a8f3223558ae694f87a8fbc92503 Mon Sep 17 00:00:00 2001 From: Aaron Alexander Date: Thu, 2 Jan 2025 13:13:22 -0800 Subject: [PATCH 4/6] fixed typo in readme --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 5e2bee2..95ecfb6 100644 --- a/README.md +++ b/README.md @@ -95,7 +95,7 @@ Because of the low-friction to adding command line options with [swift-argument- ## Packaging for distribution -swift-create-xcframework provides a `--zip` option to automatically zip up your newly created XCFrameworks ready for upload to GitHub as a release artefact, or anywhere you choose. +swift-create-xcframework provides a `--zip` option to automatically zip up your newly created XCFrameworks ready for upload to GitHub as a release artifact, or anywhere you choose. If the target you are creating an XCFramework happens to be a dependency, swift-create-xcframework will look back into the package graph, locate the version that dependency resolved to, and append the version number to your zip file name. eg: `ArgumentParser-0.0.6.zip` From 979f5e6de36d4673bf96e10e4bed460e907d3eaf Mon Sep 17 00:00:00 2001 From: Chris Leonavicius Date: Wed, 26 Mar 2025 18:21:35 -0700 Subject: [PATCH 5/6] Add support for visionOS --- Sources/CreateXCFramework/Platforms.swift | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/Sources/CreateXCFramework/Platforms.swift b/Sources/CreateXCFramework/Platforms.swift index b4c1dd5..af6c4ff 100644 --- a/Sources/CreateXCFramework/Platforms.swift +++ b/Sources/CreateXCFramework/Platforms.swift @@ -14,6 +14,7 @@ enum TargetPlatform: String, ExpressibleByArgument, CaseIterable { case maccatalyst case tvos case watchos + case visionos init?(argument: String) { self.init(rawValue: argument.lowercased()) @@ -27,6 +28,7 @@ enum TargetPlatform: String, ExpressibleByArgument, CaseIterable { case .maccatalyst: return "macos" case .tvos: return "tvos" case .watchos: return "watchos" + case .visionos: return "visionos" } } @@ -108,6 +110,21 @@ enum TargetPlatform: String, ExpressibleByArgument, CaseIterable { buildSettings: nil ) ] + case .visionos: + return [ + SDK ( + destination: "generic/platform=visionOS", + archiveName: "visionos.xcarchive", + releaseFolder: "Release-xros", + buildSettings: nil + ), + SDK ( + destination: "generic/platform=visionOS Simulator", + archiveName: "visionsimulator.xcarchive", + releaseFolder: "Release-xrsimulator", + buildSettings: nil + ) + ] } } } From 9bb228b37c06d0f1b1057641b194c1bd08c47200 Mon Sep 17 00:00:00 2001 From: Chris Leonavicius Date: Wed, 26 Mar 2025 18:29:04 -0700 Subject: [PATCH 6/6] Add an option to skip project generation for binary targets (vs throwing an error) --- Sources/CreateXCFramework/Command+Options.swift | 2 ++ Sources/CreateXCFramework/PackageInfo.swift | 2 +- Sources/CreateXCFramework/ProjectGenerator.swift | 6 ++++-- Sources/Xcodeproj/generate.swift | 6 +++++- Sources/Xcodeproj/pbxproj.swift | 8 +++++++- 5 files changed, 19 insertions(+), 5 deletions(-) diff --git a/Sources/CreateXCFramework/Command+Options.swift b/Sources/CreateXCFramework/Command+Options.swift index 551cda9..d528752 100644 --- a/Sources/CreateXCFramework/Command+Options.swift +++ b/Sources/CreateXCFramework/Command+Options.swift @@ -77,6 +77,8 @@ extension Command { @Flag(help: .hidden) var githubAction: Bool = false + @Flag(help: "Skip binary targets for project generation. Useful for creating and distributing a library from one Package.swift") + var skipBinaryTargets: Bool = false // MARK: - Targets diff --git a/Sources/CreateXCFramework/PackageInfo.swift b/Sources/CreateXCFramework/PackageInfo.swift index 5147997..561c286 100644 --- a/Sources/CreateXCFramework/PackageInfo.swift +++ b/Sources/CreateXCFramework/PackageInfo.swift @@ -147,7 +147,7 @@ struct PackageInfo { // check the graph for binary targets let binary = self.graph.allTargets.filter { $0.type == .binary } - if binary.isEmpty == false { + if !options.skipBinaryTargets, binary.isEmpty == false { errors.append(.containsBinaryTargets(binary.map(\.name))) } diff --git a/Sources/CreateXCFramework/ProjectGenerator.swift b/Sources/CreateXCFramework/ProjectGenerator.swift index dc2b9c8..fd04de3 100644 --- a/Sources/CreateXCFramework/ProjectGenerator.swift +++ b/Sources/CreateXCFramework/ProjectGenerator.swift @@ -84,7 +84,8 @@ struct ProjectGenerator { extraFiles: [], options: XcodeprojOptions ( xcconfigOverrides: (self.package.overridesXcconfig?.path).flatMap { try AbsolutePath(validating: $0) }, - useLegacySchemeGenerator: true + useLegacySchemeGenerator: true, + skipBinaryTargets: package.options.skipBinaryTargets ), fileSystem: localFileSystem, observabilityScope: self.package.observabilitySystem.topScope @@ -97,7 +98,8 @@ struct ProjectGenerator { extraFiles: [], options: XcodeprojOptions ( xcconfigOverrides: (self.package.overridesXcconfig?.path).flatMap { AbsolutePath($0) }, - useLegacySchemeGenerator: true + useLegacySchemeGenerator: true, + skipBinaryTargets: package.options.skipBinaryTargets ), diagnostics: self.package.diagnostics ) diff --git a/Sources/Xcodeproj/generate.swift b/Sources/Xcodeproj/generate.swift index 6db6cd8..7fe2699 100644 --- a/Sources/Xcodeproj/generate.swift +++ b/Sources/Xcodeproj/generate.swift @@ -45,13 +45,16 @@ public struct XcodeprojOptions { /// Reference to manifest loader, if present. public var manifestLoader: ManifestLoader? + public var skipBinaryTargets: Bool + public init( flags: PackageModel.BuildFlags = PackageModel.BuildFlags(), xcconfigOverrides: AbsolutePath? = nil, isCodeCoverageEnabled: Bool? = nil, useLegacySchemeGenerator: Bool? = nil, enableAutogeneration: Bool? = nil, - addExtraFiles: Bool? = nil + addExtraFiles: Bool? = nil, + skipBinaryTargets: Bool? = nil ) { self.flags = flags self.xcconfigOverrides = xcconfigOverrides @@ -59,6 +62,7 @@ public struct XcodeprojOptions { self.useLegacySchemeGenerator = useLegacySchemeGenerator ?? false self.enableAutogeneration = enableAutogeneration ?? false self.addExtraFiles = addExtraFiles ?? true + self.skipBinaryTargets = skipBinaryTargets ?? false } } diff --git a/Sources/Xcodeproj/pbxproj.swift b/Sources/Xcodeproj/pbxproj.swift index 4f244b7..b59ff91 100644 --- a/Sources/Xcodeproj/pbxproj.swift +++ b/Sources/Xcodeproj/pbxproj.swift @@ -396,7 +396,13 @@ public func xcodeProject( productType = .framework case .test: productType = .unitTest - case .systemModule, .binary, .plugin, .macro: + case .binary: + if options.skipBinaryTargets { + continue + } else { + fallthrough + } + case .systemModule, .plugin, .macro: throw InternalError("\(target.type) not supported") }