I’m attempting to use Swift Build to build and index an Xcode project. This works for simple projects, but the build fails as soon as I add an SPM dependency.
Specifically, building the example project TestProject.xcodeproj , which depends on the swiftui-interface-orientation package, results in the following error:
duplicate output file '/Users/x/Library/Developer/Xcode/DerivedData/TestProject-hgqtmykyujnjhmdfntxdandzmnfj/SourcePackages/checkouts/swiftui-interface-orientation/build/swiftui-interface-orientation
I couldn’t find much documentation on Swift Build, so the code below reflects what I’ve been able to piece together so far. Am I missing a required step or configuration to make Swift Build successfully build an Xcode project that includes SPM dependencies?
let containerPath = "/Users/x/Desktop/TestProject/TestProject.xcodeproj"
let buildService = try await SWBBuildService(connectionMode: .inProcess, variant: .default)
let (sessionResult, _) = await buildService.createSession(
name: "TestSession",
developerPath: "/Applications/Xcode.app/Contents/Developer",
cachePath: nil,
inferiorProductsPath: nil,
environment: [:]
)
let session = try sessionResult.get()
try await session.loadWorkspace(containerPath: containerPath)
try await session.setSystemInfo(.default())
try await session.setUserInfo(.default)
let runDestination = SWBRunDestinationInfo(
platform: "iphoneos",
sdk: "iphoneos",
sdkVariant: "iphoneos",
targetArchitecture: "arm64",
supportedArchitectures: ["arm64"],
disableOnlyActiveArch: false
)
var buildRequest = SWBBuildRequest()
buildRequest.buildCommand = .build(style: .buildOnly)
buildRequest.parameters.action = "build"
buildRequest.parameters.configurationName = "Debug"
buildRequest.parameters.activeRunDestination = runDestination
buildRequest.parameters.activeArchitecture = "arm64"
let workspaceInfo = try await session.workspaceInfo()
for target in workspaceInfo.targetInfos {
var overrides = SWBSettingsOverrides()
overrides.commandLine?.set(value: "YES", for: "ONLY_ACTIVE_ARCH")
var buildParameters = SWBBuildParameters()
buildParameters.activeArchitecture = "arm64"
buildParameters.configurationName = "Debug"
buildParameters.overrides = overrides
buildParameters.activeRunDestination = runDestination
let configuredTarget = SWBConfiguredTarget(guid: target.guid, parameters: buildParameters)
buildRequest.add(target: configuredTarget)
}
let buildOperation = try await session.createBuildOperation(
request: buildRequest,
delegate: BuildOperationDelegate()
)
let eventStream = try await buildOperation.start()
for try await event in eventStream {
logEvent(event) // Logs output to console
}
await buildOperation.waitForCompletion()
try await session.close()