Package.swift 36 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864
  1. // swift-tools-version: 6.2
  2. import CompilerPluginSupport
  3. import Foundation
  4. import PackageDescription
  5. // MARK: - EnvManager
  6. /* GENERATED BY SPMManifestTool BEGIN */
  7. /* DO NOT EDIT */
  8. public protocol EnvironmentProvider {
  9. func value(forKey key: String) -> String?
  10. }
  11. import PackageDescription
  12. public struct PackageContextEnvironmentProvider: EnvironmentProvider {
  13. public init() {}
  14. public func value(forKey key: String) -> String? {
  15. Context.environment[key]
  16. }
  17. }
  18. public final class EnvManager {
  19. nonisolated(unsafe) public static let shared = EnvManager()
  20. private var domains: [String] = []
  21. private var environmentProvider: EnvironmentProvider
  22. /// When true, append raw key as fallback when searching in domains
  23. public var includeFallbackToRawKey: Bool = false
  24. private init() {
  25. self.environmentProvider = PackageContextEnvironmentProvider()
  26. }
  27. /// Set a custom environment provider (useful for testing)
  28. public func setEnvironmentProvider(_ provider: EnvironmentProvider) {
  29. self.environmentProvider = provider
  30. }
  31. /// Reset domains and environment provider (useful for testing)
  32. public func reset() {
  33. domains.removeAll()
  34. includeFallbackToRawKey = false
  35. self.environmentProvider = PackageContextEnvironmentProvider()
  36. }
  37. public func register(domain: String) {
  38. domains.append(domain)
  39. }
  40. public func withDomain<T>(_ domain: String, perform: () throws -> T) rethrows -> T {
  41. domains.append(domain)
  42. defer { domains.removeAll { $0 == domain } }
  43. return try perform()
  44. }
  45. private func envValue<T>(rawKey: String, default defaultValue: T?, searchInDomain: Bool, parser: (String) -> T?) -> T? {
  46. func parseEnvValue(_ key: String) -> (String, T)? {
  47. guard let value = environmentProvider.value(forKey: key),
  48. let result = parser(value) else { return nil }
  49. return (value, result)
  50. }
  51. var keys: [String] = searchInDomain ? domains.map { "\($0.uppercased())_\(rawKey)" } : []
  52. if !searchInDomain || includeFallbackToRawKey {
  53. keys.append(rawKey)
  54. }
  55. for key in keys {
  56. if let (value, result) = parseEnvValue(key) {
  57. print("[Env] \(key)=\(value) -> \(result)")
  58. return result
  59. }
  60. }
  61. let primaryKey = keys.first ?? rawKey
  62. if let defaultValue {
  63. print("[Env] \(primaryKey) not set -> \(defaultValue)(default)")
  64. }
  65. return defaultValue
  66. }
  67. public func envBoolValue(rawKey: String, default defaultValue: Bool? = nil, searchInDomain: Bool) -> Bool? {
  68. envValue(rawKey: rawKey, default: defaultValue, searchInDomain: searchInDomain) { value in
  69. switch value {
  70. case "1": true
  71. case "0": false
  72. default: nil
  73. }
  74. }
  75. }
  76. public func envIntValue(rawKey: String, default defaultValue: Int? = nil, searchInDomain: Bool) -> Int? {
  77. envValue(rawKey: rawKey, default: defaultValue, searchInDomain: searchInDomain) { Int($0) }
  78. }
  79. public func envStringValue(rawKey: String, default defaultValue: String? = nil, searchInDomain: Bool) -> String? {
  80. envValue(rawKey: rawKey, default: defaultValue, searchInDomain: searchInDomain) { $0 }
  81. }
  82. }
  83. public func envBoolValue(_ key: String, default defaultValue: Bool = false, searchInDomain: Bool = true) -> Bool {
  84. EnvManager.shared.envBoolValue(rawKey: key, default: defaultValue, searchInDomain: searchInDomain)!
  85. }
  86. public func envIntValue(_ key: String, default defaultValue: Int = 0, searchInDomain: Bool = true) -> Int {
  87. EnvManager.shared.envIntValue(rawKey: key, default: defaultValue, searchInDomain: searchInDomain)!
  88. }
  89. public func envStringValue(_ key: String, default defaultValue: String, searchInDomain: Bool = true) -> String {
  90. EnvManager.shared.envStringValue(rawKey: key, default: defaultValue, searchInDomain: searchInDomain)!
  91. }
  92. public func envStringValue(_ key: String, searchInDomain: Bool = true) -> String? {
  93. EnvManager.shared.envStringValue(rawKey: key, searchInDomain: searchInDomain)
  94. }
  95. /* GENERATED BY SPMManifestTool END */
  96. EnvManager.shared.register(domain: "ark_ui_basic")
  97. // MARK: - Env and config
  98. #if os(macOS)
  99. // NOTE: #if os(macOS) check is not accurate if we are cross compiling for Linux platform. So we add an env key to specify it.
  100. let buildForDarwinPlatform = envBoolValue("BUILD_FOR_DARWIN_PLATFORM", default: true)
  101. #else
  102. let buildForDarwinPlatform = envBoolValue("BUILD_FOR_DARWIN_PLATFORM")
  103. #endif
  104. // https://github.com/SwiftPackageIndex/SwiftPackageIndex-Server/issues/3061#issuecomment-2118821061
  105. // By-pass https://github.com/swiftlang/swift-package-manager/issues/7580
  106. let isSPIDocGenerationBuild = envBoolValue("SPI_GENERATE_DOCS", searchInDomain: false)
  107. let isSPIBuild = envBoolValue("SPI_BUILD", searchInDomain: false)
  108. // Xcode use clang as linker which supports "-iframework" while SwiftPM use swiftc as linker which supports "-Fsystem"
  109. let systemFrameworkSearchFlag = isXcodeEnv ? "-iframework" : "-Fsystem"
  110. let isXcodeEnv = envStringValue("__CFBundleIdentifier", searchInDomain: false) == "com.apple.dt.Xcode"
  111. let development = envBoolValue("DEVELOPMENT", default: false)
  112. let warningsAsErrorsCondition = envBoolValue("WERROR", default: isXcodeEnv && development)
  113. let swiftCorelibsPath = envStringValue("LIB_SWIFT_PATH") ?? "\(Context.packageDirectory)/Sources/SwiftCorelibs/include"
  114. let releaseVersion = envIntValue("TARGET_RELEASE", default: 2024)
  115. let libraryEvolutionCondition = envBoolValue("LIBRARY_EVOLUTION", default: buildForDarwinPlatform)
  116. let compatibilityTestCondition = envBoolValue("COMPATIBILITY_TEST")
  117. let useLocalDeps = envBoolValue("USE_LOCAL_DEPS", default: false)
  118. // For OpenAttributeGraphShims
  119. let computeCondition = envBoolValue("OPENATTRIBUTESHIMS_COMPUTE", default: false)
  120. let danceUIGraphCondition = envBoolValue("OPENATTRIBUTESHIMS_DANCEUIGRAPH", default: false)
  121. let attributeGraphCondition = envBoolValue("OPENATTRIBUTESHIMS_ATTRIBUTEGRAPH", default: false)
  122. let renderBoxCondition = envBoolValue("RENDERBOX", default: buildForDarwinPlatform && !isSPIBuild)
  123. // For #39
  124. let anyAttributeFix = envBoolValue("ANY_ATTRIBUTE_FIX", default: !buildForDarwinPlatform)
  125. let linkCoreUI = envBoolValue("LINK_COREUI", default: buildForDarwinPlatform && !isSPIBuild)
  126. let linkCoreSVG = envBoolValue("LINK_CORESVG", default: buildForDarwinPlatform && !isSPIBuild)
  127. let linkSFSymbols = envBoolValue("LINK_SFSYMBOLS", default: buildForDarwinPlatform && !isSPIBuild)
  128. let linkBacklightServices = envBoolValue("LINK_BACKLIGHTSERVICES", default: buildForDarwinPlatform && !isSPIBuild)
  129. let linkGestures = envBoolValue("LINK_GESTURES", default: buildForDarwinPlatform && !isSPIBuild && releaseVersion >= 2025)
  130. // This should be disabled for UI test target due to link issue of Testing.
  131. // Only enable for non-UI test targets.
  132. let linkTesting = envBoolValue("LINK_TESTING")
  133. let symbolLocatorCondition = envBoolValue("SYMBOL_LOCATOR", default: buildForDarwinPlatform)
  134. let openCombineCondition = envBoolValue("OPENCOMBINE", default: !buildForDarwinPlatform)
  135. let swiftLogCondition = envBoolValue("SWIFT_LOG", default: !buildForDarwinPlatform)
  136. let swiftCryptoCondition = envBoolValue("SWIFT_CRYPTO", default: !buildForDarwinPlatform)
  137. let renderGTKCondition = envBoolValue("RENDER_GTK", default: !buildForDarwinPlatform)
  138. let swiftUIRenderCondition = envBoolValue("SWIFTUI_RENDERER", default: false)
  139. let ignoreAvailability = envBoolValue("IGNORE_AVAILABILITY", default: !isSPIDocGenerationBuild && !compatibilityTestCondition)
  140. // Run @OpenSwiftUIProject/DarwinPrivateFrameworks repo's Scripts/install_internal_sdk.sh XRSimulator to install internal XRSimulator SDK
  141. let internalXRSDK = envBoolValue("INTERNAL_XR_SDK")
  142. let enablePrivateImports = envBoolValue("ENABLE_PRIVATE_IMPORTS", default: true)
  143. let enableRuntimeConcurrencyCheck = envBoolValue("ENABLE_RUNTIME_CONCURRENCY_CHECK")
  144. let bridgeFramework = envStringValue("OPENSWIFTUI_BRIDGE_FRAMEWORK", default: "SwiftUI")
  145. // Workaround iOS CI build issue (We need to disable this on iOS CI)
  146. let supportMultiProducts: Bool = envBoolValue("SUPPORT_MULTI_PRODUCTS", default: true)
  147. /// CGFloat and CGRect def in CFCGTypes.h will conflict with Foundation's CGSize/CGRect def on Linux.
  148. /// macOS: true -> no issue
  149. /// macOS: false -> use Swift implementation with OpenCoreGraphics Swift CGPath
  150. /// Linux: true + No CGPathRef support in ORBPath -> confilict with Foundation def
  151. /// Linux: false -> use Swift implementation with OpenCoreGraphics Swift CGPath
  152. let cfCGTypes = envBoolValue("CF_CGTYPES", default: buildForDarwinPlatform)
  153. // MARK: - Shared Settings
  154. var sharedCSettings: [CSetting] = [
  155. .define("NDEBUG", .when(configuration: .release)),
  156. // Rewrite malloc() to malloc_type_malloc() for type-isolated allocation buckets (xzone malloc).
  157. .unsafeFlags(["-ftyped-memory-operations"], .when(platforms: .darwinPlatforms)),
  158. .unsafeFlags(["-fmodules"]),
  159. .define("_WASI_EMULATED_SIGNAL", .when(platforms: [.wasi])),
  160. .unsafeFlags(["-isystem", swiftCorelibsPath], .when(platforms: .nonDarwinPlatforms)),
  161. ]
  162. var sharedCxxSettings: [CXXSetting] = [
  163. .define("NDEBUG", .when(configuration: .release)),
  164. // Rewrite malloc() to malloc_type_malloc() for type-isolated allocation buckets (xzone malloc).
  165. .unsafeFlags(["-ftyped-memory-operations"], .when(platforms: .darwinPlatforms)),
  166. // Rewrite operator new/delete to typed variants (operator new(size_t, std::__type_descriptor_t)).
  167. .unsafeFlags(["-ftyped-cxx-new-delete"], .when(platforms: .darwinPlatforms)),
  168. .unsafeFlags(["-fcxx-modules"]),
  169. .define("_WASI_EMULATED_SIGNAL", .when(platforms: [.wasi])),
  170. .unsafeFlags(["-isystem", swiftCorelibsPath], .when(platforms: .nonDarwinPlatforms)),
  171. ]
  172. var sharedSwiftSettings: [SwiftSetting] = [
  173. .enableUpcomingFeature("BareSlashRegexLiterals"),
  174. .enableUpcomingFeature("InternalImportsByDefault"),
  175. .enableUpcomingFeature("InferSendableFromCaptures"),
  176. .enableExperimentalFeature("Extern"),
  177. // FIXME: -unavailable-decl-optimization=stub is not working somehow (eg. Color.vibrancy). Dig into this later
  178. .unsafeFlags(["-unavailable-decl-optimization=stub"]),
  179. .swiftLanguageMode(.v5),
  180. .define("OPENSWIFTUI_RELEASE_\(releaseVersion)"),
  181. .unsafeFlags(["-Xfrontend", "-experimental-spi-only-imports"]),
  182. ]
  183. if releaseVersion >= 2021 {
  184. for year in 2021 ... releaseVersion {
  185. sharedSwiftSettings.append(.define("OPENSWIFTUI_SUPPORT_\(year)_API"))
  186. }
  187. }
  188. if libraryEvolutionCondition {
  189. // NOTE: -enable-library-evolution will cause module verify failure for `swift build`.
  190. // Either set OPENSWIFTUI_LIBRARY_EVOLUTION=0 or add `-Xswiftc -no-verify-emitted-module-interface` after `swift build`
  191. sharedSwiftSettings.append(.unsafeFlags(["-enable-library-evolution", "-no-verify-emitted-module-interface"]))
  192. }
  193. if !compatibilityTestCondition {
  194. sharedCSettings.append(.define("OPENSWIFTUI"))
  195. sharedCxxSettings.append(.define("OPENSWIFTUI"))
  196. sharedSwiftSettings.append(.define("OPENSWIFTUI"))
  197. }
  198. if anyAttributeFix {
  199. sharedSwiftSettings.append(.define("OPENSWIFTUI_ANY_ATTRIBUTE_FIX"))
  200. }
  201. if development {
  202. sharedSwiftSettings.append(.define("OPENSWIFTUI_DEVELOPMENT"))
  203. }
  204. sharedCSettings.append(.define("OPENSWIFTUI_LINK_COREUI", to: linkCoreUI ? "1" : "0"))
  205. sharedCxxSettings.append(.define("OPENSWIFTUI_LINK_COREUI", to: linkCoreUI ? "1" : "0"))
  206. if linkCoreUI {
  207. sharedSwiftSettings.append(.define("OPENSWIFTUI_LINK_COREUI"))
  208. }
  209. sharedCSettings.append(.define("OPENSWIFTUI_LINK_CORESVG", to: linkCoreSVG ? "1" : "0"))
  210. sharedCxxSettings.append(.define("OPENSWIFTUI_LINK_CORESVG", to: linkCoreSVG ? "1" : "0"))
  211. if linkCoreSVG {
  212. sharedSwiftSettings.append(.define("OPENSWIFTUI_LINK_CORESVG"))
  213. }
  214. if linkSFSymbols {
  215. sharedSwiftSettings.append(.define("OPENSWIFTUI_LINK_SFSYMBOLS"))
  216. }
  217. sharedCSettings.append(
  218. .define(
  219. "OPENSWIFTUI_LINK_BACKLIGHTSERVICES",
  220. to: linkBacklightServices ? "1" : "0",
  221. .when(platforms: [.iOS, .visionOS])
  222. )
  223. )
  224. sharedCxxSettings.append(
  225. .define(
  226. "OPENSWIFTUI_LINK_BACKLIGHTSERVICES",
  227. to: linkBacklightServices ? "1" : "0",
  228. .when(platforms: [.iOS, .visionOS])
  229. )
  230. )
  231. if linkBacklightServices {
  232. sharedSwiftSettings.append(
  233. .define(
  234. "OPENSWIFTUI_LINK_BACKLIGHTSERVICES",
  235. .when(platforms: [.iOS, .visionOS])
  236. )
  237. )
  238. }
  239. if linkGestures {
  240. sharedSwiftSettings.append(.define("OPENSWIFTUI_LINK_GESTURES"))
  241. }
  242. if swiftUIRenderCondition {
  243. sharedCSettings.append(.define("OPENSWIFTUI_SWIFTUI_RENDERER", .when(platforms: .darwinPlatforms)))
  244. sharedCxxSettings.append(.define("OPENSWIFTUI_SWIFTUI_RENDERER", .when(platforms: .darwinPlatforms)))
  245. sharedSwiftSettings.append(.define("OPENSWIFTUI_SWIFTUI_RENDERER", .when(platforms: .darwinPlatforms)))
  246. }
  247. if linkTesting {
  248. sharedSwiftSettings.append(.define("OPENSWIFTUI_LINK_TESTING"))
  249. }
  250. if warningsAsErrorsCondition {
  251. // Hold off the werror feature as we can't avoid the concurrency warning.
  252. // Since there is no such group for diagnostic we want to ignore, we enable werror for all known groups instead.
  253. // See detail on [#443](https://github.com/swiftlang/swift-evolution/blob/main/proposals/0443-warning-control-flags.md)
  254. // items we want it to be error:
  255. // [remove_package_import]
  256. // items we want to ignore:
  257. // [error_from_clang] [error_in_future_swift_version]
  258. // sharedSwiftSettings.append(.unsafeFlags(["-warnings-as-errors"]))
  259. sharedSwiftSettings.append(.unsafeFlags(["-Werror", "Unsafe"]))
  260. sharedSwiftSettings.append(.unsafeFlags(["-Werror", "UnknownWarningGroup"]))
  261. sharedSwiftSettings.append(.unsafeFlags(["-Werror", "ExistentialAny"]))
  262. // This will cause conflict when used by Xcode from a non-local dependency
  263. // "Conflicting options '-Wwarning' and '-suppress-warnings'"
  264. // See: https://forums.swift.org/t/warnings-as-errors-in-sub-packages/70810
  265. // So do not enable it by default here.
  266. sharedSwiftSettings.append(.unsafeFlags(["-Wwarning", "DeprecatedDeclaration"])) // We want to use deprecated APIs in test targets)
  267. }
  268. if libraryEvolutionCondition && !openCombineCondition && !swiftLogCondition {
  269. // NOTE: -enable-library-evolution will cause module verify failure for `swift build`.
  270. // Either set OPENSWIFTUI_LIBRARY_EVOLUTION=0 or add `-Xswiftc -no-verify-emitted-module-interface` after `swift build`
  271. sharedSwiftSettings.append(.unsafeFlags(["-enable-library-evolution", "-no-verify-emitted-module-interface"]))
  272. }
  273. if !compatibilityTestCondition {
  274. sharedSwiftSettings.append(.define("OPENSWIFTUI"))
  275. }
  276. sharedSwiftSettings.append(contentsOf: [SwiftSetting].availabilityMacroSettings(ignoreAvailability: ignoreAvailability))
  277. sharedCSettings.append(.define("OPENSWIFTUI_INTERNAL_XR_SDK", to: internalXRSDK ? "1" : "0"))
  278. sharedCxxSettings.append(.define("OPENSWIFTUI_INTERNAL_XR_SDK", to: internalXRSDK ? "1" : "0"))
  279. if internalXRSDK {
  280. sharedSwiftSettings.append(.define("OPENSWIFTUI_INTERNAL_XR_SDK"))
  281. }
  282. if enablePrivateImports {
  283. sharedSwiftSettings.append(.define("OPENSWIFTUI_ENABLE_PRIVATE_IMPORTS"))
  284. sharedSwiftSettings.append(.unsafeFlags(["-Xfrontend", "-enable-private-imports"]))
  285. }
  286. if enableRuntimeConcurrencyCheck {
  287. sharedSwiftSettings.append(.define("OPENSWIFTUI_ENABLE_RUNTIME_CONCURRENCY_CHECK"))
  288. }
  289. if cfCGTypes {
  290. sharedCSettings.append(.define("OPENSWIFTUI_CF_CGTYPES"))
  291. sharedCxxSettings.append(.define("OPENSWIFTUI_CF_CGTYPES"))
  292. sharedSwiftSettings.append(.define("OPENSWIFTUI_CF_CGTYPES"))
  293. sharedCSettings.append(.define("OPENRENDERBOX_CF_CGTYPES"))
  294. sharedCxxSettings.append(.define("OPENRENDERBOX_CF_CGTYPES"))
  295. sharedSwiftSettings.append(.define("OPENRENDERBOX_CF_CGTYPES"))
  296. }
  297. if computeCondition {
  298. sharedCSettings.append(.define("OPENSWIFTUI_COMPUTE"))
  299. sharedCxxSettings.append(.define("OPENSWIFTUI_COMPUTE"))
  300. sharedSwiftSettings.append(.define("OPENSWIFTUI_COMPUTE"))
  301. } else if danceUIGraphCondition {
  302. sharedCSettings.append(.define("OPENSWIFTUI_DANCEUIGRAPH"))
  303. sharedCxxSettings.append(.define("OPENSWIFTUI_DANCEUIGRAPH"))
  304. sharedSwiftSettings.append(.define("OPENSWIFTUI_DANCEUIGRAPH"))
  305. } else if attributeGraphCondition {
  306. sharedCSettings.append(.define("OPENSWIFTUI_ATTRIBUTEGRAPH"))
  307. sharedCxxSettings.append(.define("OPENSWIFTUI_ATTRIBUTEGRAPH"))
  308. sharedSwiftSettings.append(.define("OPENSWIFTUI_ATTRIBUTEGRAPH"))
  309. }
  310. if renderBoxCondition {
  311. sharedCSettings.append(.define("OPENSWIFTUI_RENDERBOX"))
  312. sharedCxxSettings.append(.define("OPENSWIFTUI_RENDERBOX"))
  313. sharedSwiftSettings.append(.define("OPENSWIFTUI_RENDERBOX"))
  314. }
  315. // MARK: - Extension
  316. extension Target {
  317. func addAGSettings() {
  318. // FIXME: Weird SwiftPM behavior for test Target. Otherwize we'll get the following error message
  319. // "could not determine executable path for bundle 'AttributeGraph.framework'"
  320. dependencies.append(.product(name: "AttributeGraph", package: "DarwinPrivateFrameworks"))
  321. }
  322. func addRBSettings() {
  323. // FIXME: Weird SwiftPM behavior for test Target. Otherwize we'll get the following error message
  324. // "could not determine executable path for bundle 'RenderBox.framework'"
  325. dependencies.append(.product(name: "RenderBox", package: "DarwinPrivateFrameworks"))
  326. }
  327. func addCoreUISettings() {
  328. // FIXME: Weird SwiftPM behavior for test Target. Otherwize we'll get the following error message
  329. // "could not determine executable path for bundle 'CoreUI.framework'"
  330. dependencies.append(.product(name: "CoreUI", package: "DarwinPrivateFrameworks"))
  331. }
  332. func addCoreSVGSettings() {
  333. // FIXME: Weird SwiftPM behavior for test Target. Otherwize we'll get the following error message
  334. // "could not determine executable path for bundle 'CoreSVG.framework'"
  335. dependencies.append(.product(name: "CoreSVG", package: "DarwinPrivateFrameworks"))
  336. }
  337. func addSFSymbolsSettings() {
  338. dependencies.append(.product(name: "SFSymbols", package: "DarwinPrivateFrameworks"))
  339. }
  340. func addBacklightServicesSettings() {
  341. // FIXME: Weird SwiftPM behavior for test Target. Otherwize we'll get the following error message
  342. // "could not determine executable path for bundle 'BacklightServices.framework'"
  343. dependencies.append(
  344. .product(
  345. name: "BacklightServices",
  346. package: "DarwinPrivateFrameworks",
  347. condition: .when(platforms: [.iOS, .visionOS])
  348. )
  349. )
  350. }
  351. func addGesturesSettings() {
  352. dependencies.append(.product(name: "Gestures", package: "DarwinPrivateFrameworks"))
  353. }
  354. func addOpenCombineSettings() {
  355. dependencies.append(.product(name: "OpenCombine", package: "OpenCombine"))
  356. dependencies.append(.product(name: "OpenCombineFoundation", package: "OpenCombine"))
  357. var swiftSettings = swiftSettings ?? []
  358. swiftSettings.append(.define("OPENSWIFTUI_OPENCOMBINE"))
  359. self.swiftSettings = swiftSettings
  360. }
  361. func addOpenCombineCSettings() {
  362. var cSettings = cSettings ?? []
  363. cSettings.append(.define("OPENSWIFTUI_OPENCOMBINE"))
  364. self.cSettings = cSettings
  365. var cxxSettings = cxxSettings ?? []
  366. cxxSettings.append(.define("OPENSWIFTUI_OPENCOMBINE"))
  367. self.cxxSettings = cxxSettings
  368. }
  369. func addSwiftLogSettings() {
  370. dependencies.append(.product(name: "Logging", package: "swift-log"))
  371. var swiftSettings = swiftSettings ?? []
  372. swiftSettings.append(.define("OPENSWIFTUI_SWIFT_LOG"))
  373. self.swiftSettings = swiftSettings
  374. }
  375. func addSwiftCryptoSettings() {
  376. dependencies.append(.product(name: "Crypto", package: "swift-crypto"))
  377. var swiftSettings = swiftSettings ?? []
  378. swiftSettings.append(.define("OPENSWIFTUI_SWIFT_CRYPTO"))
  379. self.swiftSettings = swiftSettings
  380. }
  381. }
  382. extension [Platform] {
  383. static var darwinPlatforms: [Platform] {
  384. [.macOS, .iOS, .macCatalyst, .tvOS, .watchOS, .visionOS]
  385. }
  386. static var nonDarwinPlatforms: [Platform] {
  387. [.linux, .android, .wasi, .openbsd, .windows]
  388. }
  389. }
  390. extension [SwiftSetting] {
  391. /// Settings which define commonly-used OS availability macros.
  392. ///
  393. /// These leverage a pseudo-experimental feature in the Swift compiler for
  394. /// setting availability definitions, which was added in
  395. /// [swift#65218](https://github.com/swiftlang/swift/pull/65218).
  396. fileprivate static func availabilityMacroSettings(ignoreAvailability: Bool) -> Self {
  397. let minimumVersion = "iOS 13.0, macOS 10.15, tvOS 13.0, watchOS 6.0, visionOS 1.0"
  398. return [
  399. .enableExperimentalFeature("AvailabilityMacro=OpenSwiftUI_v1_0:\(ignoreAvailability ? minimumVersion : "iOS 13.0, macOS 10.15, tvOS 13.0, watchOS 6.0")"),
  400. .enableExperimentalFeature("AvailabilityMacro=OpenSwiftUI_v1_4:\(ignoreAvailability ? minimumVersion : "iOS 13.4, macOS 10.15.4, tvOS 13.4, watchOS 6.2")"),
  401. .enableExperimentalFeature("AvailabilityMacro=OpenSwiftUI_v2_0:\(ignoreAvailability ? minimumVersion : "iOS 14.0, macOS 11.0, tvOS 14.0, watchOS 7.0")"),
  402. .enableExperimentalFeature("AvailabilityMacro=OpenSwiftUI_macOS_v2_0:\(ignoreAvailability ? minimumVersion : "macOS 11.0")"),
  403. .enableExperimentalFeature("AvailabilityMacro=OpenSwiftUI_v2_1:\(ignoreAvailability ? minimumVersion : "iOS 14.2, macOS 11.0, tvOS 14.1, watchOS 7.1")"),
  404. .enableExperimentalFeature("AvailabilityMacro=OpenSwiftUI_v2_3:\(ignoreAvailability ? minimumVersion : "iOS 14.5, macOS 11.3, tvOS 14.5, watchOS 7.4")"),
  405. .enableExperimentalFeature("AvailabilityMacro=OpenSwiftUI_v3_0:\(ignoreAvailability ? minimumVersion : "iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0")"),
  406. .enableExperimentalFeature("AvailabilityMacro=OpenSwiftUI_v3_2:\(ignoreAvailability ? minimumVersion : "iOS 15.2, macOS 12.1, tvOS 15.2, watchOS 8.3")"),
  407. .enableExperimentalFeature("AvailabilityMacro=OpenSwiftUI_v3_4:\(ignoreAvailability ? minimumVersion : "iOS 15.4, macOS 12.3, tvOS 15.4, watchOS 8.5")"),
  408. .enableExperimentalFeature("AvailabilityMacro=OpenSwiftUI_v4_0:\(ignoreAvailability ? minimumVersion : "iOS 16.0, macOS 13.0, tvOS 16.0, watchOS 9.0")"),
  409. .enableExperimentalFeature("AvailabilityMacro=OpenSwiftUI_v4_1:\(ignoreAvailability ? minimumVersion : "iOS 16.1, macOS 13.0, tvOS 16.1, watchOS 9.1")"),
  410. .enableExperimentalFeature("AvailabilityMacro=OpenSwiftUI_v4_4:\(ignoreAvailability ? minimumVersion : "iOS 16.4, macOS 13.3, tvOS 16.4, watchOS 9.4")"),
  411. .enableExperimentalFeature("AvailabilityMacro=OpenSwiftUI_v5_0:\(ignoreAvailability ? minimumVersion : "iOS 17.0, macOS 14.0, tvOS 17.0, watchOS 10.0")"),
  412. .enableExperimentalFeature("AvailabilityMacro=OpenSwiftUI_v5_1:\(ignoreAvailability ? minimumVersion : "iOS 17.1, macOS 14.1, tvOS 17.1, watchOS 10.1, visionOS 1.0")"),
  413. .enableExperimentalFeature("AvailabilityMacro=OpenSwiftUI_v5_2:\(ignoreAvailability ? minimumVersion : "iOS 17.2, macOS 14.2, tvOS 17.2, watchOS 10.2, visionOS 1.0")"),
  414. .enableExperimentalFeature("AvailabilityMacro=OpenSwiftUI_v5_4:\(ignoreAvailability ? minimumVersion : "iOS 17.4, macOS 14.4, tvOS 17.4, watchOS 10.4, visionOS 1.1")"),
  415. .enableExperimentalFeature("AvailabilityMacro=OpenSwiftUI_v5_5:\(ignoreAvailability ? minimumVersion : "iOS 17.5, macOS 14.5, tvOS 17.5, watchOS 10.5, visionOS 1.2")"),
  416. .enableExperimentalFeature("AvailabilityMacro=OpenSwiftUI_v6_0:\(ignoreAvailability ? minimumVersion : "iOS 18.0, macOS 15.0, tvOS 18.0, watchOS 11.0, visionOS 2.0")"),
  417. .enableExperimentalFeature("AvailabilityMacro=OpenSwiftUI_v7_0:\(ignoreAvailability ? minimumVersion : "iOS 19.0, macOS 16.0, tvOS 19.0, watchOS 12.0, visionOS 3.0")"),
  418. .enableExperimentalFeature("AvailabilityMacro=_distantFuture:iOS 99.0, macOS 99.0, tvOS 99.0, watchOS 99.0, visionOS 99.0"),
  419. ]
  420. }
  421. }
  422. // MARK: - Targets
  423. // MARK: - CGTK Target
  424. let cgtkTarget = Target.systemLibrary(
  425. name: "CGTK",
  426. pkgConfig: "gtk4",
  427. providers: [
  428. .brew(["gtk4"]),
  429. .apt(["libgtk-4-dev clang"]),
  430. ]
  431. )
  432. // MARK: - OpenSwiftUISPI Target
  433. let openSwiftUISPITarget = Target.target(
  434. name: "ark_ui_basic_spi",
  435. dependencies: [
  436. .product(name: "OpenRenderBoxShims", package: "OpenRenderBox"),
  437. ],
  438. publicHeadersPath: ".",
  439. cSettings: sharedCSettings + [.define("_GNU_SOURCE", .when(platforms: .nonDarwinPlatforms))],
  440. cxxSettings: sharedCxxSettings,
  441. linkerSettings: [
  442. // -lMobileGestalt
  443. // For MGCopyAnswer API support
  444. .linkedLibrary("MobileGestalt", .when(platforms: .darwinPlatforms)),
  445. ] + (swiftUIRenderCondition ? [
  446. // For Interpose.c or we can choose to use dlsm approach to load them dynamically
  447. .linkedFramework("SwiftUI", .when(platforms: .darwinPlatforms))
  448. ] : [])
  449. )
  450. // MARK: - ark_ui_basic_macros Target
  451. let openSwiftUIMacrosTarget = Target.macro(
  452. name: "ark_ui_basic_macros",
  453. dependencies: [
  454. .product(name: "SwiftSyntaxMacros", package: "swift-syntax"),
  455. .product(name: "SwiftCompilerPlugin", package: "swift-syntax"),
  456. ],
  457. swiftSettings: sharedSwiftSettings
  458. )
  459. // MARK: - ark_ui_basic_core Target
  460. // NOTE:
  461. // In macOS: Mac Catalyst App will use macOS-varient build of SwiftUI.framework in /System/Library/Framework and iOS varient of SwiftUI.framework in /System/iOSSupport/System/Library/Framework
  462. // Add `|| Mac Catalyst` check everywhere in `ark_ui_basic_core` and `ark_ui_basic_spi`.
  463. let openSwiftUICoreTarget = Target.target(
  464. name: "ark_ui_basic_core",
  465. dependencies: [
  466. "ark_ui_basic_spi",
  467. "ark_ui_basic_macros",
  468. .product(name: "OpenCoreGraphicsShims", package: "OpenCoreGraphics"),
  469. .product(name: "OpenQuartzCoreShims", package: "OpenCoreGraphics"),
  470. .product(name: "OpenAttributeGraphShims", package: "OpenAttributeGraph"),
  471. .product(name: "OpenRenderBoxShims", package: "OpenRenderBox"),
  472. .product(name: "OpenObservation", package: "OpenObservation"),
  473. ] + (swiftUIRenderCondition && symbolLocatorCondition ? ["OpenSwiftUISymbolDualTestsSupport"] : []),
  474. cSettings: sharedCSettings,
  475. cxxSettings: sharedCxxSettings,
  476. swiftSettings: sharedSwiftSettings
  477. )
  478. // MARK: ark_ui_basic Target
  479. let cOpenSwiftUITarget = Target.target(
  480. name: "c_ark_ui_basic",
  481. publicHeadersPath: ".",
  482. cSettings: sharedCSettings + [
  483. .headerSearchPath("../ark_ui_basic_spi"),
  484. ],
  485. cxxSettings: sharedCxxSettings,
  486. swiftSettings: sharedSwiftSettings
  487. )
  488. let openSwiftUITarget = Target.target(
  489. name: "ark_ui_basic",
  490. dependencies: [
  491. "ark_ui_basic_core",
  492. "c_ark_ui_basic",
  493. .product(name: "OpenCoreGraphicsShims", package: "OpenCoreGraphics"),
  494. .product(name: "OpenQuartzCoreShims", package: "OpenCoreGraphics"),
  495. .product(name: "OpenAttributeGraphShims", package: "OpenAttributeGraph"),
  496. .product(name: "OpenRenderBoxShims", package: "OpenRenderBox"),
  497. ],
  498. cSettings: sharedCSettings,
  499. cxxSettings: sharedCxxSettings,
  500. swiftSettings: sharedSwiftSettings,
  501. linkerSettings: [
  502. // Force Objective-C categories from static c_ark_ui_basic into the final framework.
  503. .unsafeFlags(["-Xlinker", "-ObjC"], .when(platforms: .darwinPlatforms)),
  504. // -framework CoreServices
  505. // For CS private API link support
  506. .linkedFramework("CoreServices", .when(platforms: [.iOS])),
  507. // -lAccessibility
  508. // For Accessibility private API link support
  509. .linkedLibrary("Accessibility", .when(platforms: [.iOS])),
  510. ]
  511. )
  512. let openSwiftUIExtensionTarget = Target.target(
  513. name: "ark_ui_basic_extension",
  514. dependencies: [
  515. "ark_ui_basic",
  516. ],
  517. cSettings: sharedCSettings,
  518. cxxSettings: sharedCxxSettings,
  519. swiftSettings: sharedSwiftSettings
  520. )
  521. // MARK: - ark_ui_basic_bridge Target
  522. let openSwiftUIBridgeTarget = Target.target(
  523. name: "ark_ui_basic_bridge",
  524. dependencies: [
  525. "ark_ui_basic",
  526. ],
  527. sources: ["Bridgeable.swift", bridgeFramework],
  528. cSettings: sharedCSettings,
  529. cxxSettings: sharedCxxSettings,
  530. swiftSettings: sharedSwiftSettings
  531. )
  532. // MARK: - OpenSwiftUISymbolDualTests Target
  533. // MARK: - Products
  534. let configuredLibraryType = envStringValue("LIBRARY_TYPE")
  535. let libraryType: PackageDescription.Product.Library.LibraryType?
  536. switch configuredLibraryType {
  537. case "dynamic":
  538. libraryType = .dynamic
  539. case "static":
  540. libraryType = .static
  541. default:
  542. libraryType = nil
  543. }
  544. var products: [PackageDescription.Product] = [
  545. .library(name: "ark_ui_basic", type: libraryType, targets: ["ark_ui_basic"]),
  546. .executable(name: "ui_test", targets: ["ui_test"])
  547. ]
  548. if supportMultiProducts {
  549. products += [
  550. .library(name: "ark_ui_basic_core", type: libraryType, targets: ["ark_ui_basic_core"]),
  551. .library(name: "ark_ui_basic_spi", targets: ["ark_ui_basic_spi"]),
  552. .library(name: "ark_ui_basic_extension", targets: ["ark_ui_basic_extension"]),
  553. .library(name: "ark_ui_basic_bridge", targets: ["ark_ui_basic_bridge"])
  554. ]
  555. }
  556. // MARK: - Package
  557. let package = Package(
  558. name: "ark_ui_basic",
  559. products: products,
  560. dependencies: [
  561. .package(url: "https://github.com/apple/swift-numerics", from: "1.0.3"),
  562. .package(url: "https://github.com/swiftlang/swift-syntax.git", from: "601.0.0"),
  563. ],
  564. targets: [
  565. openSwiftUISPITarget,
  566. openSwiftUIMacrosTarget,
  567. openSwiftUICoreTarget,
  568. cOpenSwiftUITarget,
  569. openSwiftUITarget,
  570. openSwiftUIExtensionTarget,
  571. openSwiftUIBridgeTarget,
  572. .executableTarget(
  573. name: "ui_test",
  574. dependencies: ["ark_ui_basic"],
  575. path: "Sources/ui_test",
  576. swiftSettings: sharedSwiftSettings
  577. )
  578. ]
  579. )
  580. if renderGTKCondition {
  581. package.targets.append(cgtkTarget)
  582. }
  583. if !compatibilityTestCondition {
  584. package.targets += [
  585. ]
  586. }
  587. if buildForDarwinPlatform {
  588. }
  589. if symbolLocatorCondition {
  590. package.dependencies.append(
  591. .package(url: "https://github.com/OpenSwiftUIProject/SymbolLocator.git", from: "0.2.0")
  592. )
  593. package.targets += [
  594. ]
  595. if !compatibilityTestCondition {
  596. }
  597. }
  598. if attributeGraphCondition {
  599. openSwiftUICoreTarget.addAGSettings()
  600. openSwiftUITarget.addAGSettings()
  601. }
  602. if renderBoxCondition {
  603. openSwiftUICoreTarget.addRBSettings()
  604. openSwiftUITarget.addRBSettings()
  605. }
  606. if linkGestures {
  607. openSwiftUICoreTarget.addGesturesSettings()
  608. openSwiftUITarget.addGesturesSettings()
  609. }
  610. if attributeGraphCondition || renderBoxCondition || linkGestures {
  611. let release = EnvManager.shared.withDomain("DarwinPrivateFrameworks") {
  612. envIntValue("TARGET_RELEASE", default: 2024)
  613. }
  614. package.platforms = switch release {
  615. case 2024: [.iOS(.v18), .macOS(.v15), .macCatalyst(.v18), .tvOS(.v18), .watchOS(.v10), .visionOS(.v2)]
  616. case 2025: [.iOS("26.0"), .macOS("26.0"), .macCatalyst("26.0"), .tvOS("26.0"), .watchOS("26.0"), .visionOS("26.0")]
  617. default: nil
  618. }
  619. } else {
  620. // For SPI build issue
  621. package.platforms = [.iOS(.v18), .macOS(.v15), .macCatalyst(.v18), .tvOS(.v18), .watchOS(.v10), .visionOS(.v2)]
  622. }
  623. if linkCoreUI {
  624. openSwiftUICoreTarget.addCoreUISettings()
  625. openSwiftUISPITarget.addCoreUISettings()
  626. }
  627. if linkCoreSVG {
  628. openSwiftUICoreTarget.addCoreSVGSettings()
  629. openSwiftUISPITarget.addCoreSVGSettings()
  630. }
  631. if linkSFSymbols {
  632. openSwiftUICoreTarget.addSFSymbolsSettings()
  633. }
  634. if linkBacklightServices {
  635. openSwiftUITarget.addBacklightServicesSettings()
  636. openSwiftUISPITarget.addBacklightServicesSettings()
  637. }
  638. if useLocalDeps {
  639. var dependencies: [Package.Dependency] = [
  640. .package(path: "../OpenCoreGraphics"),
  641. .package(path: "../OpenAttributeGraph"),
  642. .package(path: "../OpenRenderBox"),
  643. .package(path: "../OpenObservation"),
  644. ]
  645. if attributeGraphCondition || renderBoxCondition || linkCoreUI || linkCoreSVG || linkSFSymbols || linkBacklightServices || linkGestures {
  646. dependencies.append(.package(path: "../DarwinPrivateFrameworks"))
  647. }
  648. package.dependencies += dependencies
  649. } else {
  650. var dependencies: [Package.Dependency] = [
  651. .package(url: "https://github.com/OpenSwiftUIProject/OpenCoreGraphics", branch: "main"),
  652. // FIXME: on Linux platform: OG contains unsafe build flags which prevents us using version dependency
  653. .package(url: "https://github.com/OpenSwiftUIProject/OpenAttributeGraph", branch: "main"),
  654. .package(url: "https://github.com/OpenSwiftUIProject/OpenRenderBox", branch: "main"),
  655. .package(url: "https://github.com/OpenSwiftUIProject/OpenObservation", branch: "main"),
  656. ]
  657. if attributeGraphCondition || renderBoxCondition || linkCoreUI || linkCoreSVG || linkSFSymbols || linkGestures {
  658. dependencies.append(.package(url: "https://github.com/OpenSwiftUIProject/DarwinPrivateFrameworks.git", branch: "main"))
  659. }
  660. package.dependencies += dependencies
  661. }
  662. if openCombineCondition {
  663. package.dependencies.append(
  664. .package(url: "https://github.com/OpenSwiftUIProject/OpenCombine.git", from: "0.15.0")
  665. )
  666. cOpenSwiftUITarget.addOpenCombineCSettings()
  667. openSwiftUICoreTarget.addOpenCombineSettings()
  668. openSwiftUITarget.addOpenCombineSettings()
  669. }
  670. if swiftLogCondition {
  671. package.dependencies.append(
  672. .package(url: "https://github.com/apple/swift-log", from: "1.5.3")
  673. )
  674. openSwiftUICoreTarget.addSwiftLogSettings()
  675. openSwiftUITarget.addSwiftLogSettings()
  676. }
  677. if swiftCryptoCondition {
  678. package.dependencies.append(
  679. .package(url: "https://github.com/apple/swift-crypto.git", from: "3.8.0")
  680. )
  681. openSwiftUICoreTarget.addSwiftCryptoSettings()
  682. openSwiftUITarget.addSwiftCryptoSettings()
  683. }
  684. #if TUIST
  685. import struct ProjectDescription.PackageSettings
  686. import enum ProjectDescription.Product
  687. import enum ProjectDescription.SettingValue
  688. import typealias ProjectDescription.SettingsDictionary
  689. let openSwiftUIBuildAGBackend: String
  690. if let configuredAGBackend = envStringValue("AG_BACKEND_NAME") {
  691. openSwiftUIBuildAGBackend = configuredAGBackend
  692. } else if computeCondition {
  693. openSwiftUIBuildAGBackend = "Compute"
  694. } else if danceUIGraphCondition {
  695. openSwiftUIBuildAGBackend = "DanceUIGraph"
  696. } else if attributeGraphCondition {
  697. openSwiftUIBuildAGBackend = "AttributeGraph"
  698. } else {
  699. openSwiftUIBuildAGBackend = "OpenAttributeGraph"
  700. }
  701. let openSwiftUIBuildRendererBackend = envStringValue("RENDERER_BACKEND_NAME") ?? (swiftUIRenderCondition ? "SwiftUI" : "ark_ui_basic")
  702. let openSwiftUITargetSettings: SettingsDictionary = [
  703. "INFOPLIST_KEY_OpenSwiftUIAGBackend": .string(openSwiftUIBuildAGBackend),
  704. "INFOPLIST_KEY_OpenSwiftUIRendererBackend": .string(openSwiftUIBuildRendererBackend),
  705. "INFOPLIST_KEY_OpenSwiftUILibraryType": .string(configuredLibraryType ?? "automatic"),
  706. "INFOPLIST_KEY_OpenSwiftUIUsesLocalDependencies": .string(useLocalDeps ? "YES" : "NO"),
  707. ]
  708. let packageSettings = PackageSettings(
  709. productTypes: [
  710. "ark_ui_basic": ProjectDescription.Product.framework,
  711. "ark_ui_basic_core": ProjectDescription.Product.staticFramework,
  712. "ark_ui_basic_spi": ProjectDescription.Product.staticFramework,
  713. "c_ark_ui_basic": ProjectDescription.Product.staticFramework,
  714. "ark_ui_basic_macros": ProjectDescription.Product.macro,
  715. "OpenAttributeGraphShims": ProjectDescription.Product.staticFramework,
  716. "OpenCoreGraphicsShims": ProjectDescription.Product.staticFramework,
  717. "OpenObservation": ProjectDescription.Product.staticFramework,
  718. "OpenQuartzCoreShims": ProjectDescription.Product.staticFramework,
  719. "OpenRenderBoxShims": ProjectDescription.Product.staticFramework,
  720. "SymbolLocator": ProjectDescription.Product.staticFramework,
  721. ],
  722. baseProductType: ProjectDescription.Product.staticFramework,
  723. targetSettings: [
  724. "ark_ui_basic": .settings(base: openSwiftUITargetSettings),
  725. ]
  726. )
  727. #endif