feat(s3): A-6 Xcode .app 타깃 (xcodegen) — 실행 가능한 macOS 앱
bare SPM 실행타깃은 .app 번들/Info.plist 없어 macOS 액세서리로 취급 → Cmd+R 윈도우 미표시. xcodegen project.yml 로 진짜 application 타깃 생성. - @main 셸을 Sources/DSApp → App/DSApp.swift 이동 (SPM 간섭 제거, SPM 은 라이브러리+테스트만 소유 → swift build/test 백엔드-free 유지). - Package.swift: executableTarget DSApp 제거, AppFeature library product 추가 (App 타깃이 로컬 SPM product 로 의존). - project.yml: application 타깃 DSApp(.macOS 26, Swift6 mode), Info.plist(APPL, LSUIElement 없음=일반 윈도우 앱) + entitlements(app-sandbox·network.client· files.user-selected) → Support/ 생성, xcodeproj/Support 는 gitignore. 검증: swift build + swift test 72 green / xcodebuild BUILD SUCCEEDED (서명 off 스모크 + ad-hoc 서명 빌드 둘 다) / DS.app 실행 확인(pid 생존·sandbox 크래시 0). 사용자 경로: `xcodegen generate` → DSApp.xcodeproj 열기 → My Mac → Cmd+R. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -9,6 +9,10 @@ Package.resolved
|
||||
# Xcode
|
||||
DerivedData/
|
||||
build/
|
||||
# A-6: generated by `xcodegen generate` from project.yml (the source of truth). Regenerate, don't commit.
|
||||
*.xcodeproj/
|
||||
Support/Info.plist
|
||||
Support/DSApp.entitlements
|
||||
*.xcodeproj/project.xcworkspace/xcuserdata/
|
||||
*.xcodeproj/xcuserdata/
|
||||
*.xcworkspace/xcuserdata/
|
||||
|
||||
+9
-6
@@ -7,7 +7,13 @@
|
||||
// It is also exposed as a library product so a future separate app package could depend on it.
|
||||
//
|
||||
// Ownership boundary unchanged: S2 owns Sources/AI/** + Tests/AITests/**; S3 owns DSKit / AppFeature
|
||||
// / DSApp / Tests/DSKitTests. S3 consumes AIFabric read-only.
|
||||
// / Tests/DSKitTests. S3 consumes AIFabric read-only.
|
||||
//
|
||||
// A-6 (Xcode .app target via xcodegen): the runnable macOS app shell lives in App/DSApp.swift, owned
|
||||
// by the xcodegen "DSApp" application target (project.yml), NOT by SPM. SPM here builds only the
|
||||
// libraries + tests, so `swift build` / `swift test` stay backend-free and the executable lives in
|
||||
// the real .app bundle (Info.plist + entitlements) where Cmd+R actually opens a window. The App
|
||||
// target depends on the AppFeature library product below.
|
||||
import PackageDescription
|
||||
|
||||
let package = Package(
|
||||
@@ -17,6 +23,8 @@ let package = Package(
|
||||
],
|
||||
products: [
|
||||
.library(name: "AIFabric", targets: ["AIFabric"]),
|
||||
// Consumed by the xcodegen "DSApp" .app target (App/DSApp.swift).
|
||||
.library(name: "AppFeature", targets: ["AppFeature"]),
|
||||
],
|
||||
targets: [
|
||||
.target(
|
||||
@@ -34,11 +42,6 @@ let package = Package(
|
||||
dependencies: ["DSKit", "AIFabric"],
|
||||
swiftSettings: [.swiftLanguageMode(.v6)]
|
||||
),
|
||||
.executableTarget(
|
||||
name: "DSApp",
|
||||
dependencies: ["AppFeature"],
|
||||
swiftSettings: [.swiftLanguageMode(.v6)]
|
||||
),
|
||||
.testTarget(
|
||||
name: "DSKitTests",
|
||||
dependencies: ["DSKit", "AIFabric"],
|
||||
|
||||
+76
@@ -0,0 +1,76 @@
|
||||
# A-6 — real macOS .app target for the DS app shell.
|
||||
#
|
||||
# Why this exists: opening Package.swift directly in Xcode produced an *executable* SwiftPM target
|
||||
# with no .app bundle / Info.plist, so macOS treated it as an accessory and Cmd+R never opened a
|
||||
# window (see ds-native-app-program memory). This generates a proper application target whose @main
|
||||
# lives in App/DSApp.swift and which links the AppFeature library product from the local SwiftPM
|
||||
# package. project.yml is the source of truth; DSApp.xcodeproj + Support/*.plist|.entitlements are
|
||||
# generated artifacts (gitignored). Regenerate with: xcodegen generate
|
||||
name: DSApp
|
||||
options:
|
||||
bundleIdPrefix: net.hyungi
|
||||
deploymentTarget:
|
||||
macOS: "26.0"
|
||||
createIntermediateGroups: true
|
||||
minimumXcodeGenVersion: "2.40.0"
|
||||
|
||||
settings:
|
||||
base:
|
||||
SWIFT_VERSION: "6.0" # Swift 6 language mode (matches package .swiftLanguageMode(.v6))
|
||||
SWIFT_STRICT_CONCURRENCY: complete
|
||||
MACOSX_DEPLOYMENT_TARGET: "26.0"
|
||||
CODE_SIGN_STYLE: Automatic
|
||||
# Local dev: no signing identity needed to build/run on this Mac.
|
||||
CODE_SIGNING_ALLOWED: "NO"
|
||||
CODE_SIGNING_REQUIRED: "NO"
|
||||
|
||||
packages:
|
||||
# Local SwiftPM package = this repo (Package.swift): AIFabric + DSKit + AppFeature libraries.
|
||||
DSPackage:
|
||||
path: .
|
||||
|
||||
targets:
|
||||
DSApp:
|
||||
type: application
|
||||
platform: macOS
|
||||
deploymentTarget: "26.0"
|
||||
sources:
|
||||
- path: App # App/DSApp.swift only — @main window + DI shell
|
||||
dependencies:
|
||||
- package: DSPackage
|
||||
product: AppFeature
|
||||
settings:
|
||||
base:
|
||||
PRODUCT_BUNDLE_IDENTIFIER: net.hyungi.dsapp
|
||||
PRODUCT_NAME: DS
|
||||
GENERATE_INFOPLIST_FILE: "NO"
|
||||
MARKETING_VERSION: "0.1"
|
||||
CURRENT_PROJECT_VERSION: "1"
|
||||
ENABLE_HARDENED_RUNTIME: "YES"
|
||||
info:
|
||||
path: Support/Info.plist
|
||||
properties:
|
||||
CFBundleName: DS
|
||||
CFBundleDisplayName: DS
|
||||
CFBundleShortVersionString: "0.1"
|
||||
CFBundleVersion: "1"
|
||||
CFBundlePackageType: APPL
|
||||
LSMinimumSystemVersion: "26.0"
|
||||
LSApplicationCategoryType: public.app-category.productivity
|
||||
NSHumanReadableCopyright: ""
|
||||
entitlements:
|
||||
path: Support/DSApp.entitlements
|
||||
properties:
|
||||
com.apple.security.app-sandbox: true
|
||||
com.apple.security.network.client: true # LiveDSClient HTTP → DS / mac mini :8890
|
||||
com.apple.security.files.user-selected.read-write: true # FU-C upload / FU-D download save
|
||||
|
||||
schemes:
|
||||
DSApp:
|
||||
build:
|
||||
targets:
|
||||
DSApp: all
|
||||
run:
|
||||
config: Debug
|
||||
test:
|
||||
config: Debug
|
||||
Reference in New Issue
Block a user