From 29e5c0a739d088102cddb73e76dd5685b5f78e0f Mon Sep 17 00:00:00 2001 From: commilitia Date: Tue, 7 Jul 2026 21:43:51 +0800 Subject: [PATCH] =?UTF-8?q?=E5=8E=9F=E7=94=9F=20macOS=20=E5=AE=A2=E6=88=B7?= =?UTF-8?q?=E7=AB=AF=E8=84=9A=E6=89=8B=E6=9E=B6=20+=20=E5=85=83=E6=95=B0?= =?UTF-8?q?=E6=8D=AE=E5=AE=8C=E6=95=B4=E5=91=BD=E5=90=8D=E5=8E=BB=E7=BC=A9?= =?UTF-8?q?=E5=86=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 命名去缩写:xcodegen 项目 + 四 target CDrop*→CommilitiaDrop*(CommilitiaDrop / …Share / …Widgets / …Tests);3 个 widget/control kind net.commilitia.cdrop.*→net.commilitia.Commilitia-Drop.*(旧装控件将成孤儿,需在设备重加);Tests @testable import CommilitiaDrop。刻意不动线协议 / 身份标识——bundle ID 家族、URL scheme cdrop://、Bonjour _cdrop._tcp、keychain service、DataChannel cdrop-file、entitlements 文件名——以免破跨端互通或丢会话 - 新增 macOS app target CommilitiaDropMac(platform macOS / deploymentTarget 26.0 / ARCHS arm64 / 与 iOS 同 bundle net.commilitia.Commilitia-Drop,同 App Store 记录 + 同 App Group):sources 仅 MacApp/,Info.plist 经 xcodegen 生成,本地 ad-hoc 免账号编译 - Mac 壳 MacApp/(Allman,#if os(macOS) 守卫,独立 @main 不与 iOS CDropApp 冲突):CommilitiaDropMacApp(@main + 单窗口 Window + windowResizability contentMinSize + 去 ⌘N + MenuBarExtra window 风格)、MacRootView(NavigationSplitView 侧栏五区骨架 传输/文件/消息/设备/设置 + 占位详情 MacPlaceholder + 品牌头)、MacMenuContent(菜单栏占位) - Support/macOS/AppMac.entitlements:App Group group.net.commilitia.Commilitia-Drop 预置待用;macOS 下 App Group 属受限能力须 provisioning profile,故脚手架阶段 project.yml 暂不引用,待 Phase 6 Developer ID 签名再挂 - 根 Justfile:ios-sim-build / ios-device 跟随重命名(项目 / scheme / .app 路径);新增 mac-build(xcodegen + xcodebuild -sdk macosx,本地 ad-hoc) - 验证:CommilitiaDropMac.app 与 CommilitiaDrop.app(iOS 模拟器)均 BUILD SUCCEEDED;WebRTC 走 -clonedSourcePackagesDirPath 复用已缓存 xcframework --- Justfile | 13 +- ios/CDrop/.gitignore | 5 +- ios/CDrop/MacApp/CommilitiaDropMacApp.swift | 38 ++++++ ios/CDrop/MacApp/MacMenuContent.swift | 27 ++++ ios/CDrop/MacApp/MacRootView.swift | 126 +++++++++++++++++++ ios/CDrop/Support/macOS/App-Info.plist | 32 +++++ ios/CDrop/Support/macOS/AppMac.entitlements | 14 +++ ios/CDrop/Tests/LibWebRtcEngineTests.swift | 2 +- ios/CDrop/Widgets/ClipboardControls.swift | 4 +- ios/CDrop/Widgets/CloudClipboardWidget.swift | 2 +- ios/CDrop/project.yml | 71 ++++++++--- 11 files changed, 310 insertions(+), 24 deletions(-) create mode 100644 ios/CDrop/MacApp/CommilitiaDropMacApp.swift create mode 100644 ios/CDrop/MacApp/MacMenuContent.swift create mode 100644 ios/CDrop/MacApp/MacRootView.swift create mode 100644 ios/CDrop/Support/macOS/App-Info.plist create mode 100644 ios/CDrop/Support/macOS/AppMac.entitlements diff --git a/Justfile b/Justfile index a85057e..8764ba7 100644 --- a/Justfile +++ b/Justfile @@ -96,7 +96,14 @@ ios-fonts-fredoka: ios-sim-build: just ios-fonts cd ios/CDrop && xcodegen generate - cd ios/CDrop && xcodebuild -project CDrop.xcodeproj -scheme CDrop -sdk iphonesimulator -destination 'generic/platform=iOS Simulator' -derivedDataPath build/DD build + cd ios/CDrop && xcodebuild -project CommilitiaDrop.xcodeproj -scheme CommilitiaDrop -sdk iphonesimulator -destination 'generic/platform=iOS Simulator' -derivedDataPath build/DD build + +# macOS 原生客户端本地编译验证(ad-hoc 签名,无需 Apple 账号):xcodegen + xcodebuild -sdk macosx。 +# 当前为脚手架(MacApp/ 导航骨架 + 菜单栏占位);引擎 / 复用视图 / 桌面功能随后续阶段并入。 +# 产物 build/DD-mac/Build/Products/Debug/CommilitiaDropMac.app(用于本地打开自测)。 +mac-build: + cd ios/CDrop && xcodegen generate + cd ios/CDrop && xcodebuild -project CommilitiaDrop.xcodeproj -scheme CommilitiaDropMac -sdk macosx -destination 'platform=macOS' -derivedDataPath build/DD-mac build # 真机构建 + 装机(自动 provisioning,经 ASC API Key)。前置:付费 ADP;App ID 的 App Groups / # Push 能力(门户建好或自动建);根目录 gitignore 的 .env 配齐:CDROP_TEAM_ID / CDROP_ASC_KEY_PATH @@ -108,8 +115,8 @@ ios-device udid: [ -n "$CDROP_TEAM_ID" ] && [ -n "$CDROP_ASC_KEY_PATH" ] && [ -n "$CDROP_ASC_KEY_ID" ] && [ -n "$CDROP_ASC_ISSUER_ID" ] || { echo "缺 .env(CDROP_TEAM_ID / CDROP_ASC_KEY_PATH / CDROP_ASC_KEY_ID / CDROP_ASC_ISSUER_ID)——见 ios/CDrop/REALDEVICE.md"; exit 1; } just ios-fonts cd ios/CDrop && xcodegen generate - cd ios/CDrop && xcodebuild -project CDrop.xcodeproj -scheme CDrop -configuration Debug -destination "platform=iOS,id={{udid}}" -derivedDataPath build/DD-device -allowProvisioningUpdates -authenticationKeyPath "$CDROP_ASC_KEY_PATH" -authenticationKeyID "$CDROP_ASC_KEY_ID" -authenticationKeyIssuerID "$CDROP_ASC_ISSUER_ID" DEVELOPMENT_TEAM="$CDROP_TEAM_ID" CODE_SIGN_STYLE=Automatic CODE_SIGN_IDENTITY="Apple Development" build - xcrun devicectl device install app --device {{udid}} ios/CDrop/build/DD-device/Build/Products/Debug-iphoneos/CDrop.app + cd ios/CDrop && xcodebuild -project CommilitiaDrop.xcodeproj -scheme CommilitiaDrop -configuration Debug -destination "platform=iOS,id={{udid}}" -derivedDataPath build/DD-device -allowProvisioningUpdates -authenticationKeyPath "$CDROP_ASC_KEY_PATH" -authenticationKeyID "$CDROP_ASC_KEY_ID" -authenticationKeyIssuerID "$CDROP_ASC_ISSUER_ID" DEVELOPMENT_TEAM="$CDROP_TEAM_ID" CODE_SIGN_STYLE=Automatic CODE_SIGN_IDENTITY="Apple Development" build + xcrun devicectl device install app --device {{udid}} ios/CDrop/build/DD-device/Build/Products/Debug-iphoneos/CommilitiaDrop.app # ---- deploy plumbing ---- diff --git a/ios/CDrop/.gitignore b/ios/CDrop/.gitignore index ee6c161..44cda4b 100644 --- a/ios/CDrop/.gitignore +++ b/ios/CDrop/.gitignore @@ -1,5 +1,6 @@ -# CDrop.xcodeproj 由 xcodegen 从 project.yml 生成——不提交,用 `xcodegen generate` 重建。 -CDrop.xcodeproj/ +# .xcodeproj 由 xcodegen 从 project.yml 生成——不提交,用 `xcodegen generate` 重建。本目录去缩写后 +# 由 CDrop.xcodeproj 改名 CommilitiaDrop.xcodeproj;用通配符防再次改名遗漏。 +*.xcodeproj/ # Xcode 构建产物 build/ diff --git a/ios/CDrop/MacApp/CommilitiaDropMacApp.swift b/ios/CDrop/MacApp/CommilitiaDropMacApp.swift new file mode 100644 index 0000000..3b664a4 --- /dev/null +++ b/ios/CDrop/MacApp/CommilitiaDropMacApp.swift @@ -0,0 +1,38 @@ +#if os(macOS) +import SwiftUI + +// 原生 macOS 客户端入口。单窗口 + 菜单栏常驻,桌面壳(MacRootView)替代 iOS 的标签栏。 +// 当前为脚手架:导航骨架 + 菜单栏占位;引擎(LibWebRtcEngine + 离屏 WebView)、复用视图与 +// 桌面专属功能(剪贴板自动同步 / 全局热键 / 原生通知)随后续阶段并入。iOS 入口另见 CDropApp。 +@main +struct CommilitiaDropMacApp: App +{ + var body: some Scene + { + // 启动即打开的单主窗口。 + Window("Commilitia Drop", id: "main") + { + MacRootView() + .frame(minWidth: 820, minHeight: 560) + } + .defaultLaunchBehavior(.presented) + .windowResizability(.contentMinSize) + .commands + { + // 单窗口应用:移除「新建」(⌘N),对本应用无意义。 + CommandGroup(replacing: .newItem) {} + } + + // 菜单栏常驻:状态 + 快捷剪贴板 / Quick Send(当前占位)。 + MenuBarExtra + { + MacMenuContent() + } + label: + { + Image(systemName: "paperplane") + } + .menuBarExtraStyle(.window) + } +} +#endif diff --git a/ios/CDrop/MacApp/MacMenuContent.swift b/ios/CDrop/MacApp/MacMenuContent.swift new file mode 100644 index 0000000..fe1eca9 --- /dev/null +++ b/ios/CDrop/MacApp/MacMenuContent.swift @@ -0,0 +1,27 @@ +#if os(macOS) +import SwiftUI + +// 菜单栏常驻内容(占位):后续接入连接状态 + 一键剪贴板 push/pull + Quick Send。 +struct MacMenuContent: View +{ + @Environment(\.openWindow) private var openWindow + + var body: some View + { + VStack(alignment: .leading, spacing: 10) + { + Text("Commilitia Drop") + .font(.headline) + Text("桌面功能适配中") + .font(.caption) + .foregroundStyle(.secondary) + + Divider() + Button("打开主窗口") { openWindow(id: "main") } + Button("退出") { NSApplication.shared.terminate(nil) } + } + .padding(12) + .frame(width: 240) + } +} +#endif diff --git a/ios/CDrop/MacApp/MacRootView.swift b/ios/CDrop/MacApp/MacRootView.swift new file mode 100644 index 0000000..f0b92fe --- /dev/null +++ b/ios/CDrop/MacApp/MacRootView.swift @@ -0,0 +1,126 @@ +#if os(macOS) +import SwiftUI + +// 桌面根界面:NavigationSplitView 侧栏(传输 / 文件 / 消息 / 设备 / 设置)+ 详情 NavigationStack, +// 替代 iOS 的标签栏。当前为脚手架:各区详情为占位(MacPlaceholder),随后续阶段接入复用视图 +// 与桌面专属功能。分区标签暂硬编中文;接入 i18n(Shared/I18n)后改走 t()(与 iOS 单一真源一致)。 +struct MacRootView: View +{ + @State private var selection: MacSection = .transfers + + var body: some View + { + NavigationSplitView + { + List(selection: $selection) + { + brandHeader + .listRowInsets(EdgeInsets(top: 10, leading: 8, bottom: 14, trailing: 8)) + .listRowSeparator(.hidden) + .selectionDisabled() + Section + { + ForEach(MacSection.sidebar) + { section in + Label(section.title, systemImage: section.icon) + .tag(section) + } + } + } + .navigationSplitViewColumnWidth(min: 200, ideal: 220, max: 280) + .navigationTitle("Commilitia Drop") + } + detail: + { + NavigationStack + { + detail + } + } + } + + @ViewBuilder + private var detail: some View + { + switch selection + { + case .transfers: + MacPlaceholder(section: .transfers) + case .files: + MacPlaceholder(section: .files) + case .messages: + MacPlaceholder(section: .messages) + case .devices: + MacPlaceholder(section: .devices) + case .settings: + MacPlaceholder(section: .settings) + } + } + + private var brandHeader: some View + { + HStack(spacing: 10) + { + Image(systemName: "paperplane.fill") + .font(.title2) + .foregroundStyle(.tint) + Text("Commilitia Drop") + .font(.title3.weight(.semibold)) + .lineLimit(1) + } + } +} + +// 侧栏分区。与 iOS 标签一致:传输 / 文件 / 消息 / 设备 / 设置。 +enum MacSection: Hashable, Identifiable, CaseIterable +{ + case transfers, files, messages, devices, settings + + var id: Self { self } + + var title: String + { + switch self + { + case .transfers: return "传输" + case .files: return "文件" + case .messages: return "消息" + case .devices: return "设备" + case .settings: return "设置" + } + } + + var icon: String + { + switch self + { + case .transfers: return "arrow.up.arrow.down" + case .files: return "folder" + case .messages: return "bubble.left.and.bubble.right" + case .devices: return "laptopcomputer.and.iphone" + case .settings: return "gearshape" + } + } + + static var sidebar: [MacSection] { MacSection.allCases } +} + +// 阶段占位详情:标明该区将接入的功能,随后续阶段替换为实际视图。 +struct MacPlaceholder: View +{ + let section: MacSection + + var body: some View + { + ContentUnavailableView + { + Label(section.title, systemImage: section.icon) + } + description: + { + Text("即将接入(原生数据面复用 iOS 引擎,桌面功能适配中)。") + } + .navigationTitle(section.title) + } +} +#endif diff --git a/ios/CDrop/Support/macOS/App-Info.plist b/ios/CDrop/Support/macOS/App-Info.plist new file mode 100644 index 0000000..95d6468 --- /dev/null +++ b/ios/CDrop/Support/macOS/App-Info.plist @@ -0,0 +1,32 @@ + + + + + CFBundleDevelopmentRegion + zh-Hans + CFBundleDisplayName + Commilitia Drop + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleLocalizations + + zh-Hans + zh-Hant + en + + CFBundleName + Commilitia Drop + CFBundlePackageType + APPL + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + LSMinimumSystemVersion + 26.0 + + diff --git a/ios/CDrop/Support/macOS/AppMac.entitlements b/ios/CDrop/Support/macOS/AppMac.entitlements new file mode 100644 index 0000000..1adf03e --- /dev/null +++ b/ios/CDrop/Support/macOS/AppMac.entitlements @@ -0,0 +1,14 @@ + + + + + + com.apple.security.application-groups + + group.net.commilitia.Commilitia-Drop + + + diff --git a/ios/CDrop/Tests/LibWebRtcEngineTests.swift b/ios/CDrop/Tests/LibWebRtcEngineTests.swift index a9d53dc..b559af0 100644 --- a/ios/CDrop/Tests/LibWebRtcEngineTests.swift +++ b/ios/CDrop/Tests/LibWebRtcEngineTests.swift @@ -1,5 +1,5 @@ import XCTest -@testable import CDrop +@testable import CommilitiaDrop // LibWebRtcEngine 环回端到端测试:两个引擎在同进程内交叉连,跑完整线协议 // (offer/answer/ICE + meta/分片/done + ack + 收尾),验证收到的文件字节与源逐字节相等。 diff --git a/ios/CDrop/Widgets/ClipboardControls.swift b/ios/CDrop/Widgets/ClipboardControls.swift index 46c0a51..239b9a9 100644 --- a/ios/CDrop/Widgets/ClipboardControls.swift +++ b/ios/CDrop/Widgets/ClipboardControls.swift @@ -20,7 +20,7 @@ struct UploadClipboardControl: ControlWidget { var body: some ControlWidgetConfiguration { - StaticControlConfiguration(kind: "net.commilitia.cdrop.control.upload") + StaticControlConfiguration(kind: "net.commilitia.Commilitia-Drop.control.upload") { ControlWidgetButton(action: UploadClipboardIntent()) { @@ -35,7 +35,7 @@ struct PullClipboardControl: ControlWidget { var body: some ControlWidgetConfiguration { - StaticControlConfiguration(kind: "net.commilitia.cdrop.control.pull") + StaticControlConfiguration(kind: "net.commilitia.Commilitia-Drop.control.pull") { ControlWidgetButton(action: PullClipboardIntent()) { diff --git a/ios/CDrop/Widgets/CloudClipboardWidget.swift b/ios/CDrop/Widgets/CloudClipboardWidget.swift index be53d92..1ca805c 100644 --- a/ios/CDrop/Widgets/CloudClipboardWidget.swift +++ b/ios/CDrop/Widgets/CloudClipboardWidget.swift @@ -107,7 +107,7 @@ struct CloudClipboardWidget: Widget { var body: some WidgetConfiguration { - StaticConfiguration(kind: "net.commilitia.cdrop.widget.clipboard", provider: ClipboardWidgetProvider()) + StaticConfiguration(kind: "net.commilitia.Commilitia-Drop.widget.clipboard", provider: ClipboardWidgetProvider()) { entry in ClipboardWidgetView(entry: entry) } diff --git a/ios/CDrop/project.yml b/ios/CDrop/project.yml index 9b76237..ee699c5 100644 --- a/ios/CDrop/project.yml +++ b/ios/CDrop/project.yml @@ -1,13 +1,17 @@ -name: CDrop +name: CommilitiaDrop options: bundleIdPrefix: net.commilitia deploymentTarget: iOS: "26.0" + macOS: "26.0" createIntermediateGroups: true + # 源码以简体中文撰写;字符串目录承载 zh-Hant / en 翻译。语言跟随系统设置。 + developmentLanguage: zh-Hans # 原生数据面:iOS 走 libwebrtc(Safari 同款,与 iOS 网络栈原生集成)。预编译 xcframework 经 # stasel/WebRTC 以 SPM 分发,仅二进制 target,pin 精确版本避免上游 M 版跳变改 API。替换早先 # gomobile/pion 路径——pion 的 Go raw socket 不与 iOS Network framework 集成,真机确证不可靠 -# (见 desktop/NATIVE-TRANSFER.md §7 / cdrop-native-data-plane 记忆)。 +# (见 desktop/NATIVE-TRANSFER.md §7 / cdrop-native-data-plane 记忆)。libwebrtc 亦含 macOS 切片 +# (macos-x86_64_arm64 + maccatalyst),故同一 LibWebRtcEngine 可在原生 Mac target 复用。 packages: WebRTC: url: https://github.com/stasel/WebRTC @@ -17,12 +21,12 @@ settings: SWIFT_VERSION: "5.0" # 模拟器用 ad-hoc 签名(身份 "-",无需 Apple 账号),使 App Group / Push 等 entitlement 在 # 模拟器实际生效(否则共享容器不创建、远程通知注册失败)。真机签名须付费 ADP 配 - # team / provisioning profile(账号门控,见 REALDEVICE.md)。 + # team / provisioning profile(账号门控,见 REALDEVICE.md)。macOS 本地开发同走 ad-hoc。 CODE_SIGN_IDENTITY: "-" CODE_SIGNING_REQUIRED: "NO" CODE_SIGNING_ALLOWED: "YES" targets: - CDrop: + CommilitiaDrop: type: application platform: iOS deploymentTarget: "26.0" @@ -30,9 +34,9 @@ targets: - path: Sources - path: Shared dependencies: - - target: CDropShare + - target: CommilitiaDropShare embed: true - - target: CDropWidgets + - target: CommilitiaDropWidgets embed: true # 原生数据面引擎(libwebrtc):SPM 预编 xcframework,Xcode 自动嵌入 + 签名。仅主 app 链接—— # Share / 控件扩展不碰数据面,避免超扩展 120MB 内存限。见 LibWebRtcEngine.swift。 @@ -98,7 +102,7 @@ targets: CODE_SIGN_ENTITLEMENTS: CDrop.entitlements # Share Extension:抓分享文件 → App Group 收件箱 → 深链主 app 选设备发送(只交接、不跑引擎, # 见 PLAN §I5)。只编 ShareViewController + 共享的 AppGroup,绝不拉主 app Sources(避超 120MB)。 - CDropShare: + CommilitiaDropShare: type: app-extension platform: iOS deploymentTarget: "26.0" @@ -129,7 +133,7 @@ targets: CODE_SIGN_ENTITLEMENTS: Share/CDropShare.entitlements # 控制中心剪贴板两控件(WidgetKit ControlWidget,iOS 18+,PLAN §I4)。纯原生 REST + 控件专用 # 设备会话(不跑引擎)。i18n JSON 一并打包使控件标签随设备语言(t() 经 no-subdir 回退读 bundle)。 - CDropWidgets: + CommilitiaDropWidgets: type: app-extension platform: iOS deploymentTarget: "26.0" @@ -150,30 +154,67 @@ targets: CODE_SIGN_ENTITLEMENTS: Widgets/CDropWidgets.entitlements # 单元 / 集成测试(模拟器,无需签名):原生数据面 libwebrtc 引擎的环回端到端测试——两个 # LibWebRtcEngine 在同进程内交叉连,跑完整线协议(offer/answer/ICE + meta/分片/done + ack + - # 收尾)验证文件字节完整性。宿主即 CDrop app(@testable import 取内部类型 + 经 app 链接 WebRTC)。 - CDropTests: + # 收尾)验证文件字节完整性。宿主即主 app(@testable import 取内部类型 + 经 app 链接 WebRTC)。 + CommilitiaDropTests: type: bundle.unit-test platform: iOS deploymentTarget: "26.0" sources: - path: Tests dependencies: - - target: CDrop + - target: CommilitiaDrop - package: WebRTC settings: base: PRODUCT_BUNDLE_IDENTIFIER: net.commilitia.Commilitia-Drop.tests - TEST_HOST: "$(BUILT_PRODUCTS_DIR)/CDrop.app/CDrop" + TEST_HOST: "$(BUILT_PRODUCTS_DIR)/CommilitiaDrop.app/CommilitiaDrop" BUNDLE_LOADER: "$(TEST_HOST)" GENERATE_INFOPLIST_FILE: "YES" + # 原生 macOS 客户端:桌面壳(MacApp/)替代 iOS 标签栏,@main 的 #if os(macOS) 分支驱动单窗口 + + # 菜单栏。与 iOS 同 bundle(net.commilitia.Commilitia-Drop,同 App Store 记录 / 同 App Group)。 + # 当前为脚手架:仅编 MacApp/(导航骨架 + 菜单栏占位);引擎(LibWebRtcEngine + 离屏 WebView)与 + # 复用视图随后续阶段并入。ARCHS arm64(本机 Apple Silicon);本地 ad-hoc 签名(base 继承)。 + CommilitiaDropMac: + type: application + platform: macOS + deploymentTarget: "26.0" + sources: + - path: MacApp + info: + path: Support/macOS/App-Info.plist + properties: + CFBundleName: Commilitia Drop + CFBundleDisplayName: Commilitia Drop + LSMinimumSystemVersion: "26.0" + CFBundleDevelopmentRegion: zh-Hans + CFBundleLocalizations: + - zh-Hans + - zh-Hant + - en + settings: + base: + PRODUCT_BUNDLE_IDENTIFIER: net.commilitia.Commilitia-Drop + PRODUCT_NAME: CommilitiaDropMac + ARCHS: arm64 + # App Group entitlement(Support/macOS/AppMac.entitlements)在 macOS 属受限能力,即便 + # ad-hoc 签名也须 provisioning profile;脚手架阶段(本地免账号编译 / 自测)暂不挂,待桌面 + # 剪贴板 / 小组件共享落地 + Developer ID 签名(Phase 6)再引用该文件。见 AppMac.entitlements。 schemes: - CDrop: + CommilitiaDrop: build: targets: - CDrop: all + CommilitiaDrop: all test: targets: - - CDropTests + - CommilitiaDropTests gatherCoverageData: false run: config: Debug + CommilitiaDropMac: + build: + targets: + CommilitiaDropMac: all + run: + config: Debug + archive: + config: Release