I am developing a command line app in Swift which will call out to swift
in order to initialize packages, compile things, test things, etc.
I am using the swift package manager and Xcode.
In my tool, I call swift
from a Process
.
If I am running my tool from the command line, this works fine.
However, if I am running my tool from Xcode, some strange things are printed to standard error.
In particular, I get
Failed to open macho file at /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/swift for reading: Too many levels of symbolic links
What is causing this? Is there some way I can avoid it, or can I just not run/test this utility from Xcode?
Here are reproduction steps:
mkdir XcodeRedirectionTest
cd XcodeRedirectionTest
swift package init
open Package.swift
Then in Tests/XcodeRedirectionTestTests/XcodeRedirectionTestTests.swift
, paste
import XCTest
final class XcodeRedirectionTestTests: XCTestCase {
func testExample() {
let process = Process()
process.launchPath = "/usr/bin/swift"
process.arguments = ["--version"]
let standardOutput = Pipe()
let standardError = Pipe()
process.standardOutput = standardOutput
process.standardError = standardError
process.launch()
process.waitUntilExit()
guard let output = String(data: standardOutput.fileHandleForReading.readDataToEndOfFile(), encoding: .utf8) else { XCTFail(); return }
guard let error = String(data: standardError.fileHandleForReading.readDataToEndOfFile(), encoding: .utf8) else { XCTFail(); return }
XCTAssertEqual(process.terminationReason, .exit)
XCTAssertEqual(process.terminationStatus, 0)
XCTAssertEqual(error, "")
XCTAssert(output.starts(with: "Apple Swift version 5.4"))
}
}
Testing in Xcode fails with
file://.../XcodeRedirectionTest/Tests/XcodeRedirectionTestTests/XcodeRedirectionTestTests.swift: test failure: XcodeRedirectionTestTests.testExample() failed: XCTAssertEqual failed: ("2021-05-18 19:43:18.084463-0400 swift[2836:4100702] Failed to open macho file at /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/swift for reading: Too many levels of symbolic links
") is not equal to ("")
That is (so you don't have to scroll (as much)), the standard error ends up being
Failed to open macho file at /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/swift for reading: Too many levels of symbolic links
However, running swift test
from the command line succeeds. No standard error!
If it matters, I am running Xcode 12.5 on macOS Big Sur 11.2.3.
I was able to narrow this down to the environment variable
OS_ACTIVITY_DT_MODE
. It seems that Xcode sets this to1
when running programs. If this variable is unset, the error is not displayed. The code I used to accomplish this isThis requires more testing to understand the relationship between the
PWD
passed in the environment andProcess.currentDirectoryURL
, but this at least gets the ball rolling.