5. Targets, Products, dan Dependencies
5. Targets, Products, dan Dependencies
Tiga konsep ini sering dicampur-aduk. Mari lurus-kan.
Target
Unit kompilasi. Satu folder di Sources/, di-compile jadi satu module. Tipe target:
.target— library Swift biasa..executableTarget— punya@mainataumain.swift..testTarget— di-compile dengan XCTest/Swift Testing linked..binaryTarget— pre-built XCFramework (lihat Bagian 8)..plugin— build/command plugin (lihat Bagian 10)..systemLibrary— wrapper untuk C library system..macro— Swift Macro implementation (Swift 5.9+).
Product
API publik yang bisa di-depend dari luar package. Jenis:
.library— bisa.static,.dynamic, atau.automatic(default)..executable— binary executable..plugin— plugin yang bisa dipakai package lain.
Satu product bisa terdiri dari banyak target. Satu target bisa di-expose oleh banyak product.
products: [
// Library yang menggabungkan dua target
.library(name: "AppKit", targets: ["AppCore", "AppUI"]),
// Library yang hanya satu target
.library(name: "Logger", targets: ["Logger"]),
]
Dependency Resolution per Target
Default behavior: target hanya bisa pakai target lain di package yang sama, atau product dari package eksternal.
.target(
name: "AppCore",
dependencies: [
"Logger", // internal target
.product(name: "Collections", package: "swift-collections"), // external product
]
)
Static vs Dynamic Library
Default .automatic membiarkan SPM memutuskan (biasanya static).
products: [
.library(name: "MyLib", type: .static, targets: ["MyLib"]),
.library(name: "MyLib", type: .dynamic, targets: ["MyLib"]),
]
Static — code di-link ke binary host. Tidak ada cost runtime load, tapi binary lebih besar dan duplicate kalau dipakai di banyak target.
Dynamic — di-link saat runtime. Cocok untuk shared between app extension (kurangi total app size).
Anti-pattern umum: memaksa dynamic untuk semua library → app launch lebih lambat (banyak dylib resolve).