Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Package.resolved

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

249 changes: 167 additions & 82 deletions Package.swift
Original file line number Diff line number Diff line change
@@ -1,52 +1,166 @@
// swift-tools-version: 6.1
// The swift-tools-version declares the minimum version of Swift required to build this package.

import Foundation
import PackageDescription

func envEnable(_ key: String, default defaultValue: Bool = false) -> Bool {
guard let value = Context.environment[key] else {
return defaultValue
/* GENERATED BY SPMManifestTool BEGIN */
/* DO NOT EDIT */

public protocol EnvironmentProvider {
func value(forKey key: String) -> String?
}

import PackageDescription
public struct PackageContextEnvironmentProvider: EnvironmentProvider {
public init() {}

public func value(forKey key: String) -> String? {
Context.environment[key]
}
if value == "1" {
return true
} else if value == "0" {
return false
} else {
}

// MARK: - Env Manager

public final class EnvManager {
nonisolated(unsafe) public static let shared = EnvManager()

private var domains: [String] = []
private var environmentProvider: EnvironmentProvider

/// When true, append raw key as fallback when searching in domains
public var includeFallbackToRawKey: Bool = false

private init() {
self.environmentProvider = PackageContextEnvironmentProvider()
}

/// Set a custom environment provider (useful for testing)
public func setEnvironmentProvider(_ provider: EnvironmentProvider) {
self.environmentProvider = provider
}

/// Reset domains and environment provider (useful for testing)
public func reset() {
domains.removeAll()
includeFallbackToRawKey = false
self.environmentProvider = PackageContextEnvironmentProvider()
}

public func register(domain: String) {
domains.append(domain)
}

public func withDomain<T>(_ domain: String, perform: () throws -> T) rethrows -> T {
domains.append(domain)
defer { domains.removeAll { $0 == domain } }
return try perform()
}

private func envValue<T>(rawKey: String, default defaultValue: T?, searchInDomain: Bool, parser: (String) -> T?) -> T? {
func parseEnvValue(_ key: String) -> (String, T)? {
guard let value = environmentProvider.value(forKey: key),
let result = parser(value) else { return nil }
return (value, result)
}
var keys: [String] = searchInDomain ? domains.map { "\($0.uppercased())_\(rawKey)" } : []
if !searchInDomain || includeFallbackToRawKey {
keys.append(rawKey)
}
for key in keys {
if let (value, result) = parseEnvValue(key) {
print("[Env] \(key)=\(value) -> \(result)")
return result
}
}
let primaryKey = keys.first ?? rawKey
if let defaultValue {
print("[Env] \(primaryKey) not set -> \(defaultValue)(default)")
}
return defaultValue
}

public func envBoolValue(rawKey: String, default defaultValue: Bool? = nil, searchInDomain: Bool) -> Bool? {
envValue(rawKey: rawKey, default: defaultValue, searchInDomain: searchInDomain) { value in
switch value {
case "1": true
case "0": false
default: nil
}
}
}

public func envIntValue(rawKey: String, default defaultValue: Int? = nil, searchInDomain: Bool) -> Int? {
envValue(rawKey: rawKey, default: defaultValue, searchInDomain: searchInDomain) { Int($0) }
}

public func envStringValue(rawKey: String, default defaultValue: String? = nil, searchInDomain: Bool) -> String? {
envValue(rawKey: rawKey, default: defaultValue, searchInDomain: searchInDomain) { $0 }
}
}

public func envBoolValue(_ key: String, default defaultValue: Bool = false, searchInDomain: Bool = true) -> Bool {
EnvManager.shared.envBoolValue(rawKey: key, default: defaultValue, searchInDomain: searchInDomain)!
}

public func envIntValue(_ key: String, default defaultValue: Int = 0, searchInDomain: Bool = true) -> Int {
EnvManager.shared.envIntValue(rawKey: key, default: defaultValue, searchInDomain: searchInDomain)!
}

public func envStringValue(_ key: String, default defaultValue: String, searchInDomain: Bool = true) -> String {
EnvManager.shared.envStringValue(rawKey: key, default: defaultValue, searchInDomain: searchInDomain)!
}

public func envStringValue(_ key: String, searchInDomain: Bool = true) -> String? {
EnvManager.shared.envStringValue(rawKey: key, searchInDomain: searchInDomain)
}

/* GENERATED BY SPMManifestTool END */
EnvManager.shared.register(domain: "OpenAttributeGraph")
EnvManager.shared.register(domain: "OpenSwiftUI")

// MARK: - Env and config

#if os(macOS)
// 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.
let buildForDarwinPlatform = envEnable("OPENSWIFTUI_BUILD_FOR_DARWIN_PLATFORM", default: true)
let buildForDarwinPlatform = envBoolValue("BUILD_FOR_DARWIN_PLATFORM", default: true)
#else
let buildForDarwinPlatform = envEnable("OPENSWIFTUI_BUILD_FOR_DARWIN_PLATFORM")
let buildForDarwinPlatform = envBoolValue("BUILD_FOR_DARWIN_PLATFORM")
#endif


// https://github.com/SwiftPackageIndex/SwiftPackageIndex-Server/issues/3061#issuecomment-2118821061
// By-pass https://github.com/swiftlang/swift-package-manager/issues/7580
let isSPIDocGenerationBuild = envEnable("SPI_GENERATE_DOCS", default: false)
let isSPIBuild = envEnable("SPI_BUILD")

// MARK: - Env and Config
let isSPIDocGenerationBuild = envBoolValue("SPI_GENERATE_DOCS", searchInDomain: false)
let isSPIBuild = envBoolValue("SPI_BUILD", searchInDomain: false)

let isXcodeEnv = Context.environment["__CFBundleIdentifier"] == "com.apple.dt.Xcode"
let development = envEnable("OPENATTRIBUTEGRAPH_DEVELOPMENT", default: false)
let isXcodeEnv = envStringValue("__CFBundleIdentifier", searchInDomain: false) == "com.apple.dt.Xcode"
let development = envBoolValue("DEVELOPMENT", default: false)
let warningsAsErrorsCondition = envBoolValue("WERROR", default: isXcodeEnv && development)

// From Swift toolchain being installed or from Swift SDK.
func detectLibSwiftPath() -> String {
guard let libSwiftPath = Context.environment["OPENATTRIBUTEGRAPH_LIB_SWIFT_PATH"] else {
let libSwiftPath = {
// From Swift toolchain being installed or from Swift SDK.
guard let libSwiftPath = envStringValue("LIB_SWIFT_PATH") else {
// Fallback when LIB_SWIFT_PATH is not set
let swiftBinPath = Context.environment["OPENATTRIBUTEGRAPH_BIN_SWIFT_PATH"] ?? Context.environment["_"] ?? "/usr/bin/swift"
let swiftBinPath = envStringValue("BIN_SWIFT_PATH") ?? envStringValue("_", searchInDomain: false) ?? "/usr/bin/swift"
let swiftBinURL = URL(fileURLWithPath: swiftBinPath)
let SDKPath = swiftBinURL.deletingLastPathComponent().deletingLastPathComponent().deletingLastPathComponent().path
return SDKPath.appending("/usr/lib/swift")
}
return libSwiftPath
}
let libSwiftPath = detectLibSwiftPath()
}()

let swiftToolchainPath = envStringValue("SWIFT_TOOLCHAIN_PATH") ?? (development ? "/Volumes/BuildMachine/swift-project" : "")
let swiftToolchainVersion = envStringValue("SWIFT_TOOLCHAIN_VERSION") ?? (development ? "6.0.2" : "")
let swiftToolchainSupported = envBoolValue("SWIFT_TOOLCHAIN_SUPPORTED", default: !swiftToolchainVersion.isEmpty)

let releaseVersion = envIntValue("TARGET_RELEASE", default: 2024)

let libraryEvolutionCondition = envBoolValue("LIBRARY_EVOLUTION", default: buildForDarwinPlatform)
let compatibilityTestCondition = envBoolValue("COMPATIBILITY_TEST", default: false)

let useLocalDeps = envBoolValue("USE_LOCAL_DEPS")
let attributeGraphCondition = envBoolValue("ATTRIBUTEGRAPH", default: buildForDarwinPlatform && !isSPIBuild)

// MARK: - Shared Settings

var sharedCSettings: [CSetting] = [
.unsafeFlags(["-I", libSwiftPath], .when(platforms: .nonDarwinPlatforms)),
Expand All @@ -57,9 +171,9 @@ var sharedSwiftSettings: [SwiftSetting] = [
.enableUpcomingFeature("InternalImportsByDefault"),
.enableExperimentalFeature("Extern"),
.swiftLanguageMode(.v5),
]

// MARK: [env] OPENATTRIBUTEGRAPH_SWIFT_TOOLCHAIN_PATH
.define("OPENATTRIBUTEGRAPH_RELEASE_\(releaseVersion)"),
]

// Modified from: https://github.com/swiftlang/swift/blob/main/SwiftCompilerSources/Package.swift
//
Expand All @@ -74,7 +188,6 @@ var sharedSwiftSettings: [SwiftSetting] = [
//
// where <$OPENATTRIBUTEGRAPH_SWIFT_TOOLCHAIN_PATH> is the parent directory of the swift repository.

let swiftToolchainPath = Context.environment["OPENATTRIBUTEGRAPH_SWIFT_TOOLCHAIN_PATH"] ?? (development ? "/Volumes/BuildMachine/swift-project" : "")
if !swiftToolchainPath.isEmpty {
sharedCSettings.append(
.unsafeFlags(
Expand All @@ -95,60 +208,52 @@ if !swiftToolchainPath.isEmpty {
)
)
}

// MARK: [env] OPENATTRIBUTEGRAPH_SWIFT_TOOLCHAIN_VERSION

let swiftToolchainVersion = Context.environment["OPENATTRIBUTEGRAPH_SWIFT_TOOLCHAIN_VERSION"] ?? (development ? "6.0.2" : "")
if !swiftToolchainVersion.isEmpty {
sharedCSettings.append(
.define("OPENATTRIBUTEGRAPH_SWIFT_TOOLCHAIN_VERSION", to: swiftToolchainVersion)
)
}

// MARK: - [env] OPENATTRIBUTEGRAPH_SWIFT_TOOLCHAIN_SUPPORTED

let swiftToolchainSupported = envEnable("OPENATTRIBUTEGRAPH_SWIFT_TOOLCHAIN_SUPPORTED", default: !swiftToolchainVersion.isEmpty)
if swiftToolchainSupported {
sharedCSettings.append(.define("OPENATTRIBUTEGRAPH_SWIFT_TOOLCHAIN_SUPPORTED"))
sharedSwiftSettings.append(.define("OPENATTRIBUTEGRAPH_SWIFT_TOOLCHAIN_SUPPORTED"))
}

// MARK: - [env] OPENATTRIBUTEGRAPH_TARGET_RELEASE

let releaseVersion = Context.environment["OPENATTRIBUTEGRAPH_TARGET_RELEASE"].flatMap { Int($0) } ?? 2024
//sharedCSettings.append(.define("OPENATTRIBUTEGRAPH_RELEASE", to: "\(releaseVersion)"))
sharedSwiftSettings.append(.define("OPENATTRIBUTEGRAPH_RELEASE_\(releaseVersion)"))
if releaseVersion >= 2021 {
for year in 2021 ... releaseVersion {
sharedSwiftSettings.append(.define("OPENATTRIBUTEGRAPH_SUPPORT_\(year)_API"))
}
}

// MARK: - [env] OPENATTRIBUTEGRAPH_WERROR

let warningsAsErrorsCondition = envEnable("OPENATTRIBUTEGRAPH_WERROR", default: isXcodeEnv && development)
if warningsAsErrorsCondition {
sharedSwiftSettings.append(.unsafeFlags(["-warnings-as-errors"]))
}

// MARK: - [env] OPENATTRIBUTEGRAPH_LIBRARY_EVOLUTION

let libraryEvolutionCondition = envEnable("OPENATTRIBUTEGRAPH_LIBRARY_EVOLUTION", default: buildForDarwinPlatform)

if libraryEvolutionCondition {
// NOTE: -enable-library-evolution will cause module verify failure for `swift build`.
// Either set OPENATTRIBUTEGRAPH_LIBRARY_EVOLUTION=0 or add `-Xswiftc -no-verify-emitted-module-interface` after `swift build`
sharedSwiftSettings.append(.unsafeFlags(["-enable-library-evolution", "-no-verify-emitted-module-interface"]))
}

// MARK: - [env] OPENATTRIBUTEGRAPH_COMPATIBILITY_TEST

let compatibilityTestCondition = envEnable("OPENATTRIBUTEGRAPH_COMPATIBILITY_TEST", default: false)
sharedCSettings.append(.define("OPENATTRIBUTEGRAPH", to: compatibilityTestCondition ? "1" : "0"))
if !compatibilityTestCondition {
sharedCSettings.append(.define("OPENATTRIBUTEGRAPH"))
sharedSwiftSettings.append(.define("OPENATTRIBUTEGRAPH"))
}

// MARK: - Extension

extension Target {
func addAGSettings() {
dependencies.append(
.product(name: "AttributeGraph", package: "DarwinPrivateFrameworks")
)
var swiftSettings = swiftSettings ?? []
swiftSettings.append(.define("OPENATTRIBUTEGRAPH_ATTRIBUTEGRAPH"))
self.swiftSettings = swiftSettings
}
}

extension [Platform] {
static var nonDarwinPlatforms: [Platform] {
[.linux, .android, .wasi, .openbsd, .windows]
}
}

// MARK: - Targets

let openAttributeGraphTarget = Target.target(
Expand Down Expand Up @@ -233,35 +338,20 @@ let package = Package(
cxxLanguageStandard: .cxx20
)

extension Target {
func addAGSettings() {
dependencies.append(
.product(name: "AttributeGraph", package: "DarwinPrivateFrameworks")
)
var swiftSettings = swiftSettings ?? []
swiftSettings.append(.define("OPENATTRIBUTEGRAPH_ATTRIBUTEGRAPH"))
self.swiftSettings = swiftSettings
}
}

if !compatibilityTestCondition {
if compatibilityTestCondition {
openAttributeGraphCompatibilityTestsTarget.addAGSettings()
} else {
package.targets += [
openAttributeGraphTestsTarget,
openAttributeGraphCxxTestsTarget,
openAttributeGraphShimsTestsTarget,
]
} else {
openAttributeGraphCompatibilityTestsTarget.addAGSettings()
}

if buildForDarwinPlatform {
package.targets.append(openAttributeGraphCompatibilityTestsTarget)
}

let useLocalDeps = envEnable("OPENATTRIBUTEGRAPH_USE_LOCAL_DEPS")

let attributeGraphCondition = envEnable("OPENATTRIBUTEGRAPH_ATTRIBUTEGRAPH", default: buildForDarwinPlatform && !isSPIBuild)

if attributeGraphCondition {
let privateFrameworkRepo: Package.Dependency
if useLocalDeps {
Expand All @@ -271,8 +361,10 @@ if attributeGraphCondition {
}
package.dependencies.append(privateFrameworkRepo)
openAttributeGraphShimsTarget.addAGSettings()

let agVersion = Context.environment["DARWIN_PRIVATE_FRAMEWORKS_TARGET_RELEASE"].flatMap { Int($0) } ?? 2024

let agVersion = EnvManager.shared.withDomain("DARWIN_PRIVATE_FRAMEWORKS") {
envIntValue("TARGET_RELEASE", default: 2024)
}
package.platforms = switch agVersion {
case 2024: [.iOS(.v18), .macOS(.v15), .macCatalyst(.v18), .tvOS(.v18), .watchOS(.v10), .visionOS(.v2)]
case 2021: [.iOS(.v15), .macOS(.v12), .macCatalyst(.v15), .tvOS(.v15), .watchOS(.v7)]
Expand All @@ -282,10 +374,3 @@ if attributeGraphCondition {
openAttributeGraphShimsTarget.dependencies.append("OpenAttributeGraph")
package.platforms = [.iOS(.v13), .macOS(.v10_15), .macCatalyst(.v13), .tvOS(.v13), .watchOS(.v5)]
}


extension [Platform] {
static var nonDarwinPlatforms: [Platform] {
[.linux, .android, .wasi, .openbsd, .windows]
}
}