diff --git a/Sources/XToolSupport/SDKCommand.swift b/Sources/XToolSupport/SDKCommand.swift index cdb0bfc..2ac5484 100644 --- a/Sources/XToolSupport/SDKCommand.swift +++ b/Sources/XToolSupport/SDKCommand.swift @@ -171,7 +171,7 @@ struct DarwinSDK { let hostClangResources = URL(filePath: output.trimmingCharacters(in: .whitespacesAndNewlines)) let hostInclude = hostClangResources.appending(path: "include") let sdkInclude = sdk.appending(path: "Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/swift/clang/include") - try FileManager.default.copyItem(at: hostInclude, to: sdkInclude) + try await FileManager.default.copyItem(at: hostInclude, to: sdkInclude, preserveOwner: false) } static func current() async throws -> DarwinSDK? { @@ -264,7 +264,7 @@ struct InstallSDKOperation { if path.hasSuffix(".xtoolsdk") { print("Installing prebuilt SDK...") - try FileManager.default.copyItem(at: URL(filePath: path), to: sdkPath) + try await FileManager.default.copyItem(at: URL(filePath: path), to: sdkPath, preserveOwner: false) } else { // validate input before removing existing SDK let input = try SDKBuilder.Input(path: path) diff --git a/Sources/XUtils/Foundation+Utils.swift b/Sources/XUtils/Foundation+Utils.swift index 50d02df..3067a86 100644 --- a/Sources/XUtils/Foundation+Utils.swift +++ b/Sources/XUtils/Foundation+Utils.swift @@ -1,4 +1,7 @@ import Foundation +#if canImport(Subprocess) +import Subprocess +#endif extension Data { // AsyncBytes is Darwin-only :/ @@ -20,6 +23,30 @@ extension Data { } } +extension FileManager { + /// Like `copyItem(at:to:)` but allows opting out of preserving the owner + package func copyItem( + at srcURL: URL, + to dstURL: URL, + preserveOwner: Bool, + ) async throws { + // why this is needed: https://github.com/xtool-org/xtool/issues/254 + + #if canImport(Subprocess) + if !preserveOwner { + try await Subprocess.run( + .name("cp"), + arguments: ["-R", srcURL.path, dstURL.path], + output: .discarded, + ).checkSuccess() + return + } + #endif + + try self.copyItem(at: srcURL, to: dstURL) + } +} + package func stderrPrint(_ message: String, terminator: String = "\n") { try? FileHandle.standardError.write(contentsOf: Data("\(message)\(terminator)".utf8)) }