mirror of
https://github.com/xtool-org/xtool.git
synced 2026-02-04 11:53:30 +01:00
Closes #68 ## On any platform You can now do ```bash xtool dev build --triple arm64-apple-ios-simulator [--ipa] ``` To build a .app/.ipa that works on the simulator. ## On macOS You can do ```bash xtool dev --simulator ``` To one-shot build-and-install on the booted simulator.
94 lines
3.3 KiB
Swift
94 lines
3.3 KiB
Swift
import Foundation
|
|
|
|
public struct BuildSettings: Sendable {
|
|
private static let customBinDir =
|
|
// this is the same option used by SwiftPM itself for dev builds
|
|
ProcessInfo.processInfo.environment["SWIFTPM_CUSTOM_BIN_DIR"].map { URL(fileURLWithPath: $0) }
|
|
|
|
private static let envURL = URL(fileURLWithPath: "/usr/bin/env")
|
|
|
|
public let packagePath: String
|
|
public let configuration: BuildConfiguration
|
|
public let triple: String
|
|
public let sdkOptions: [String]
|
|
public let options: [String]
|
|
|
|
public init(
|
|
configuration: BuildConfiguration,
|
|
triple: String,
|
|
packagePath: String = ".",
|
|
options: [String] = []
|
|
) async throws {
|
|
self.packagePath = packagePath
|
|
self.configuration = configuration
|
|
self.options = options
|
|
self.triple = triple
|
|
|
|
// on macOS we don't explicitly install a Swift SDK but
|
|
// SwiftPM vends "implicit" Darwin SDKs as of Swift 6.1,
|
|
// i.e. we can pass `--swift-sdk arm64-apple-ios` and it
|
|
// just works. See:
|
|
// https://github.com/swiftlang/swift-package-manager/pull/6828
|
|
self.sdkOptions = ["--swift-sdk", triple]
|
|
}
|
|
|
|
#if os(macOS)
|
|
private static func xcrun(_ arguments: [String]) async throws -> String {
|
|
let xcrun = Process()
|
|
let pipe = Pipe()
|
|
xcrun.executableURL = URL(fileURLWithPath: "/usr/bin/xcrun")
|
|
xcrun.arguments = arguments
|
|
xcrun.standardOutput = pipe
|
|
try await xcrun.runUntilExit()
|
|
return String(decoding: pipe.fileHandleForReading.readDataToEndOfFile(), as: UTF8.self)
|
|
.trimmingCharacters(in: .whitespacesAndNewlines)
|
|
}
|
|
|
|
private static let swiftURL = Task {
|
|
try await URL(fileURLWithPath: xcrun(["-f", "swift"]))
|
|
}
|
|
#endif
|
|
|
|
public func swiftPMInvocation(
|
|
forTool tool: String,
|
|
arguments: [String],
|
|
packagePathOverride: String? = nil
|
|
) async throws -> Process {
|
|
let process = Process()
|
|
|
|
let baseArguments: [String]
|
|
if let customBinDir = Self.customBinDir {
|
|
process.executableURL = customBinDir.appendingPathComponent("swift-\(tool)")
|
|
baseArguments = []
|
|
} else {
|
|
#if os(macOS)
|
|
// xcrun/libxcrun (via the /usr/bin/swift trampoline) is very trigger-happy
|
|
// to add SDKROOT=.../MacOSX.sdk to our invocations. We avoid this by
|
|
// 1) invoking the real swift executable (located with `xcrun -f`) and
|
|
// 2) explicitly removing SDKROOT from the env, as it may be inherited
|
|
// through the `swift run pack` invocation.
|
|
process.executableURL = try await Self.swiftURL.value
|
|
#else
|
|
process.executableURL = try await ToolRegistry.locate("swift")
|
|
#endif
|
|
baseArguments = [tool]
|
|
}
|
|
|
|
let extraArguments: [String] = [
|
|
"--package-path", packagePathOverride ?? packagePath,
|
|
"--configuration", configuration.rawValue,
|
|
]
|
|
|
|
var env = ProcessInfo.processInfo.environment
|
|
env.removeValue(forKey: "SDKROOT")
|
|
process.environment = env
|
|
process.arguments = baseArguments + extraArguments + sdkOptions + options + arguments
|
|
return process
|
|
}
|
|
}
|
|
|
|
public enum BuildConfiguration: String, CaseIterable, Sendable {
|
|
case debug
|
|
case release
|
|
}
|