From f705ed219b03d142c1c8da4db76b00dd65845b2e Mon Sep 17 00:00:00 2001 From: Robert Connell Date: Mon, 24 Nov 2025 14:40:30 -0500 Subject: [PATCH 1/5] SwiftBuild support for invoking metal compiler using xcrun --- .../Metal/SimpleCompileArgs/Package.swift | 32 ++++++++ .../Plugins/MetalCompilerPlugin.swift | 74 +++++++++++++++++++ .../Sources/MyRenderer/Renderer.swift | 4 + .../Sources/MyRenderer/Shaders.metal | 12 +++ .../MySharedTypes/include/SharedTypes.h | 14 ++++ Fixtures/Metal/SimpleLibrary/Package.swift | 19 +++++ .../Sources/MyRenderer/Renderer.swift | 4 + .../Sources/MyRenderer/Shaders.metal | 12 +++ .../MySharedTypes/include/SharedTypes.h | 14 ++++ .../MyRendererTests/MyRendererTests.swift | 6 ++ Package.swift | 9 ++- .../SwiftBuildSupport/PackagePIFBuilder.swift | 37 ++++++++++ .../PackagePIFProjectBuilder.swift | 2 + Sources/XCBuildSupport/PIF.swift | 1 + Tests/BuildMetalTests/BuildMetalTests.swift | 58 +++++++++++++++ 15 files changed, 297 insertions(+), 1 deletion(-) create mode 100644 Fixtures/Metal/SimpleCompileArgs/Package.swift create mode 100644 Fixtures/Metal/SimpleCompileArgs/Plugins/MetalCompilerPlugin.swift create mode 100644 Fixtures/Metal/SimpleCompileArgs/Sources/MyRenderer/Renderer.swift create mode 100644 Fixtures/Metal/SimpleCompileArgs/Sources/MyRenderer/Shaders.metal create mode 100644 Fixtures/Metal/SimpleCompileArgs/Sources/MySharedTypes/include/SharedTypes.h create mode 100644 Fixtures/Metal/SimpleLibrary/Package.swift create mode 100644 Fixtures/Metal/SimpleLibrary/Sources/MyRenderer/Renderer.swift create mode 100644 Fixtures/Metal/SimpleLibrary/Sources/MyRenderer/Shaders.metal create mode 100644 Fixtures/Metal/SimpleLibrary/Sources/MySharedTypes/include/SharedTypes.h create mode 100644 Fixtures/Metal/SimpleLibrary/Tests/MyRendererTests/MyRendererTests.swift create mode 100644 Tests/BuildMetalTests/BuildMetalTests.swift diff --git a/Fixtures/Metal/SimpleCompileArgs/Package.swift b/Fixtures/Metal/SimpleCompileArgs/Package.swift new file mode 100644 index 00000000000..9a6d3c0fc62 --- /dev/null +++ b/Fixtures/Metal/SimpleCompileArgs/Package.swift @@ -0,0 +1,32 @@ +// swift-tools-version: 6.2 +// The swift-tools-version declares the minimum version of Swift required to build this package. + +import PackageDescription + +let package = Package( + name: "MyRenderer", + products: [ + .library( + name: "MyRenderer", + targets: ["MyRenderer"]), + .plugin( + name: "MetalCompilerPlugin", + targets: ["MetalCompilerPlugin"]), + ], + targets: [ + .target( + name: "MyRenderer", + dependencies: ["MySharedTypes"], + plugins: [ + .plugin(name: "MetalCompilerPlugin") + ]), + + .target(name: "MySharedTypes"), + + .plugin( + name: "MetalCompilerPlugin", + capability: .buildTool() + ), + ], + swiftLanguageModes: [.v6] +) diff --git a/Fixtures/Metal/SimpleCompileArgs/Plugins/MetalCompilerPlugin.swift b/Fixtures/Metal/SimpleCompileArgs/Plugins/MetalCompilerPlugin.swift new file mode 100644 index 00000000000..b124be2a091 --- /dev/null +++ b/Fixtures/Metal/SimpleCompileArgs/Plugins/MetalCompilerPlugin.swift @@ -0,0 +1,74 @@ +import PackagePlugin +import struct Foundation.URL + +@main +struct MetalCompilerPlugin: BuildToolPlugin { + + func createBuildCommands(context: PluginContext, target: Target) async throws -> [Command] { + Diagnostics.remark("MetalCompilerPlugin: Starting plugin execution") + + guard let sourceFiles = target.sourceModule?.sourceFiles else { + Diagnostics.remark("MetalCompilerPlugin: No source files found") + return [] + } + + Diagnostics.remark("MetalCompilerPlugin: Found \(sourceFiles.count) source files") + for file in sourceFiles { + Diagnostics.remark(" - \(file.path.lastComponent)") + } + + let metalFiles = sourceFiles.filter { $0.path.extension == "metal" } + + Diagnostics.remark("MetalCompilerPlugin: Found \(metalFiles.count) .metal files") + + guard !metalFiles.isEmpty else { + Diagnostics.remark("MetalCompilerPlugin: No .metal files to compile") + return [] + } + + var commands: [Command] = [] + var airFiles: [URL] = [] + + // Compile each .metal file to .air + for metalFile in metalFiles { + let airFile = context.pluginWorkDirectoryURL.appendingPathComponent( + metalFile.path.stem + ".air" + ) + airFiles.append(airFile) + + commands.append(.buildCommand( + displayName: "Compiling Metal shader \(metalFile.path.lastComponent)", + executable: URL(fileURLWithPath: "/usr/bin/xcrun"), + arguments: [ + "metal", + "-c", + "-g", // Include debug symbols + metalFile.url.path, + "-o", + airFile.path + ], + inputFiles: [metalFile.url], + outputFiles: [airFile] + )) + } + + // Link all .air files into default.metallib + let metallibPath = context.pluginWorkDirectoryURL.appendingPathComponent("default.metallib") + + var metallibArgs = ["metallib", "-o", metallibPath.path] + metallibArgs.append(contentsOf: airFiles.map { $0.path }) + + commands.append(.buildCommand( + displayName: "Linking Metal library", + executable: URL(fileURLWithPath: "/usr/bin/xcrun"), + arguments: metallibArgs, + inputFiles: airFiles, + outputFiles: [metallibPath] + )) + + Diagnostics.remark("MetalCompilerPlugin: Will generate metallib at \(metallibPath.path)") + + return commands + } +} + diff --git a/Fixtures/Metal/SimpleCompileArgs/Sources/MyRenderer/Renderer.swift b/Fixtures/Metal/SimpleCompileArgs/Sources/MyRenderer/Renderer.swift new file mode 100644 index 00000000000..816eb50119b --- /dev/null +++ b/Fixtures/Metal/SimpleCompileArgs/Sources/MyRenderer/Renderer.swift @@ -0,0 +1,4 @@ +import MySharedTypes + + +let vertex = AAPLVertex(position: .init(250, -250), color: .init(1, 0, 0, 1)) diff --git a/Fixtures/Metal/SimpleCompileArgs/Sources/MyRenderer/Shaders.metal b/Fixtures/Metal/SimpleCompileArgs/Sources/MyRenderer/Shaders.metal new file mode 100644 index 00000000000..491edf63048 --- /dev/null +++ b/Fixtures/Metal/SimpleCompileArgs/Sources/MyRenderer/Shaders.metal @@ -0,0 +1,12 @@ +// A relative path to SharedTypes.h. +#import "../MySharedTypes/include/SharedTypes.h" + +#include +using namespace metal; + +vertex float4 simpleVertexShader(const device AAPLVertex *vertices [[buffer(0)]], + uint vertexID [[vertex_id]]) { + AAPLVertex in = vertices[vertexID]; + return float4(in.position.x, in.position.y, 0.0, 1.0); +} + diff --git a/Fixtures/Metal/SimpleCompileArgs/Sources/MySharedTypes/include/SharedTypes.h b/Fixtures/Metal/SimpleCompileArgs/Sources/MySharedTypes/include/SharedTypes.h new file mode 100644 index 00000000000..ea51fd839d4 --- /dev/null +++ b/Fixtures/Metal/SimpleCompileArgs/Sources/MySharedTypes/include/SharedTypes.h @@ -0,0 +1,14 @@ +#ifndef SharedTypes_h +#define SharedTypes_h + + +#import + + +typedef struct { + vector_float2 position; + vector_float4 color; +} AAPLVertex; + + +#endif /* SharedTypes_h */ diff --git a/Fixtures/Metal/SimpleLibrary/Package.swift b/Fixtures/Metal/SimpleLibrary/Package.swift new file mode 100644 index 00000000000..36228ca965d --- /dev/null +++ b/Fixtures/Metal/SimpleLibrary/Package.swift @@ -0,0 +1,19 @@ +// swift-tools-version: 6.2 +// The swift-tools-version declares the minimum version of Swift required to build this package. +import PackageDescription + +let package = Package( + name: "MyRenderer", + products: [ + .library( + name: "MyRenderer", + targets: ["MyRenderer"]), + ], + targets: [ + .target( + name: "MyRenderer", + dependencies: ["MySharedTypes"]), + + .target(name: "MySharedTypes") + ] +) diff --git a/Fixtures/Metal/SimpleLibrary/Sources/MyRenderer/Renderer.swift b/Fixtures/Metal/SimpleLibrary/Sources/MyRenderer/Renderer.swift new file mode 100644 index 00000000000..816eb50119b --- /dev/null +++ b/Fixtures/Metal/SimpleLibrary/Sources/MyRenderer/Renderer.swift @@ -0,0 +1,4 @@ +import MySharedTypes + + +let vertex = AAPLVertex(position: .init(250, -250), color: .init(1, 0, 0, 1)) diff --git a/Fixtures/Metal/SimpleLibrary/Sources/MyRenderer/Shaders.metal b/Fixtures/Metal/SimpleLibrary/Sources/MyRenderer/Shaders.metal new file mode 100644 index 00000000000..491edf63048 --- /dev/null +++ b/Fixtures/Metal/SimpleLibrary/Sources/MyRenderer/Shaders.metal @@ -0,0 +1,12 @@ +// A relative path to SharedTypes.h. +#import "../MySharedTypes/include/SharedTypes.h" + +#include +using namespace metal; + +vertex float4 simpleVertexShader(const device AAPLVertex *vertices [[buffer(0)]], + uint vertexID [[vertex_id]]) { + AAPLVertex in = vertices[vertexID]; + return float4(in.position.x, in.position.y, 0.0, 1.0); +} + diff --git a/Fixtures/Metal/SimpleLibrary/Sources/MySharedTypes/include/SharedTypes.h b/Fixtures/Metal/SimpleLibrary/Sources/MySharedTypes/include/SharedTypes.h new file mode 100644 index 00000000000..ea51fd839d4 --- /dev/null +++ b/Fixtures/Metal/SimpleLibrary/Sources/MySharedTypes/include/SharedTypes.h @@ -0,0 +1,14 @@ +#ifndef SharedTypes_h +#define SharedTypes_h + + +#import + + +typedef struct { + vector_float2 position; + vector_float4 color; +} AAPLVertex; + + +#endif /* SharedTypes_h */ diff --git a/Fixtures/Metal/SimpleLibrary/Tests/MyRendererTests/MyRendererTests.swift b/Fixtures/Metal/SimpleLibrary/Tests/MyRendererTests/MyRendererTests.swift new file mode 100644 index 00000000000..fad1d528b79 --- /dev/null +++ b/Fixtures/Metal/SimpleLibrary/Tests/MyRendererTests/MyRendererTests.swift @@ -0,0 +1,6 @@ +import Testing +@testable import MyRenderer + +@Test func example() async throws { + // Write your test here and use APIs like `#expect(...)` to check expected conditions. +} diff --git a/Package.swift b/Package.swift index aa32ba1e384..84a06043ec1 100644 --- a/Package.swift +++ b/Package.swift @@ -991,6 +991,13 @@ let package = Package( name: "SwiftBuildSupportTests", dependencies: ["SwiftBuildSupport", "_InternalTestSupport", "_InternalBuildTestSupport"] ), + .testTarget( + name: "BuildMetalTests", + dependencies: [ + "_InternalTestSupport", + "Basics" + ] + ), // Examples (These are built to ensure they stay up to date with the API.) .executableTarget( name: "package-info", @@ -1163,7 +1170,7 @@ if !shouldUseSwiftBuildFramework { if ProcessInfo.processInfo.environment["SWIFTCI_USE_LOCAL_DEPS"] == nil { package.dependencies += [ - .package(url: "https://github.com/swiftlang/swift-build.git", branch: relatedDependenciesBranch), + .package(path: "../swift-build"), ] } else { package.dependencies += [ diff --git a/Sources/SwiftBuildSupport/PackagePIFBuilder.swift b/Sources/SwiftBuildSupport/PackagePIFBuilder.swift index 53c7a428be8..48ab9b535c1 100644 --- a/Sources/SwiftBuildSupport/PackagePIFBuilder.swift +++ b/Sources/SwiftBuildSupport/PackagePIFBuilder.swift @@ -19,6 +19,8 @@ import struct Basics.SourceControlURL import struct Basics.Diagnostic import struct Basics.ObservabilityMetadata import class Basics.ObservabilityScope +import class Basics.AsyncProcess +import struct Basics.AsyncProcessResult import class PackageModel.Manifest import class PackageModel.Package @@ -179,6 +181,9 @@ public final class PackagePIFBuilder { /// The file system to read from. let fileSystem: FileSystem + /// Path to the Metal compiler, resolved via `xcrun --find metal` or 'metal' if not found. + let metalCompilerPath: String + /// Whether to suppress warnings from compilers, linkers, and other build tools for package dependencies. private var suppressWarningsForPackageDependencies: Bool { UserDefaults.standard.bool(forKey: "SuppressWarningsForPackageDependencies", defaultValue: true) @@ -215,6 +220,7 @@ public final class PackagePIFBuilder { self.fileSystem = fileSystem self.observabilityScope = observabilityScope self.addLocalRpaths = addLocalRpaths + self.metalCompilerPath = Self.findMetalCompilerPath(observabilityScope: observabilityScope) } public init( @@ -239,6 +245,7 @@ public final class PackagePIFBuilder { self.packageDisplayVersion = packageDisplayVersion self.fileSystem = fileSystem self.observabilityScope = observabilityScope + self.metalCompilerPath = Self.findMetalCompilerPath(observabilityScope: observabilityScope) } /// Build an empty PIF project. @@ -660,6 +667,36 @@ public final class PackagePIFBuilder { self.rule = resource.rule } } + + private static func findMetalCompilerPath(observabilityScope: ObservabilityScope) -> String { + do { + let result = try AsyncProcess.popen( + arguments: ["xcrun", "--find", "metal"] + ) + guard result.exitStatus == .terminated(code: 0) else { + observabilityScope.emit( + debug: "Failed to find Metal compiler using xcrun, exited with \(result.exitStatus). Defaulting to 'metal'" + ) + return "metal" + } + + let output = try result.utf8Output() + + let path = output.trimmingCharacters(in: .whitespacesAndNewlines) + + guard !path.isEmpty else { + observabilityScope.emit(debug: "Metal compiler path is empty, defaulting to 'metal'") + return "metal" + } + + return path + } catch { + observabilityScope.emit( + debug: "Error \(error) finding Metal compiler, defaulting to 'metal'" + ) + return "metal" + } + } } // MARK: - Helpers diff --git a/Sources/SwiftBuildSupport/PackagePIFProjectBuilder.swift b/Sources/SwiftBuildSupport/PackagePIFProjectBuilder.swift index 6684a2e5e9e..1e39e7304ae 100644 --- a/Sources/SwiftBuildSupport/PackagePIFProjectBuilder.swift +++ b/Sources/SwiftBuildSupport/PackagePIFProjectBuilder.swift @@ -220,6 +220,8 @@ struct PackagePIFProjectBuilder { settings[.COREML_COMPILER_CONTAINER] = "swift-package" settings[.COREML_CODEGEN_LANGUAGE] = "None" + settings[.MTL_COMPILER_PATH] = self.pifBuilder.metalCompilerPath + self.project[keyPath: resourcesTargetKeyPath].common.addBuildConfig { id in BuildConfig(id: id, name: "Debug", settings: settings) } diff --git a/Sources/XCBuildSupport/PIF.swift b/Sources/XCBuildSupport/PIF.swift index d418da1f15c..70fb684d9c4 100644 --- a/Sources/XCBuildSupport/PIF.swift +++ b/Sources/XCBuildSupport/PIF.swift @@ -925,6 +925,7 @@ public enum PIF { case CLANG_COVERAGE_MAPPING_LINKER_ARGS case MACH_O_TYPE case MACOSX_DEPLOYMENT_TARGET + case MTL_COMPILER_PATH case MODULEMAP_FILE case MODULEMAP_FILE_CONTENTS case MODULEMAP_PATH diff --git a/Tests/BuildMetalTests/BuildMetalTests.swift b/Tests/BuildMetalTests/BuildMetalTests.swift new file mode 100644 index 00000000000..88368253175 --- /dev/null +++ b/Tests/BuildMetalTests/BuildMetalTests.swift @@ -0,0 +1,58 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the Swift open source project +// +// Copyright (c) 2025 Apple Inc. and the Swift project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See http://swift.org/LICENSE.txt for license information +// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors +// +//===----------------------------------------------------------------------===// + +import _InternalTestSupport +import Testing +import Basics + +@Suite +struct BuildMetalTests { + + @Test( + .requireHostOS(.macOS), + arguments: getBuildData(for: [.swiftbuild]), + ) + func simpleLibrary(data: BuildData) async throws { + let buildSystem = data.buildSystem + let configuration = data.config + + try await fixture(name: "Metal/SimpleLibrary") { fixturePath in + + // Build the package + let (_, _) = try await executeSwiftBuild( + fixturePath, + configuration: configuration, + buildSystem: buildSystem, + throwIfCommandFails: true + ) + + // Get the bin path + let (binPathOutput, _) = try await executeSwiftBuild( + fixturePath, + configuration: configuration, + extraArgs: ["--show-bin-path"], + buildSystem: buildSystem, + throwIfCommandFails: true + ) + + let binPath = try AbsolutePath(validating: binPathOutput.trimmingCharacters(in: .whitespacesAndNewlines)) + + // Check that default.metallib exists + let metallibPath = binPath.appending(components:["MyRenderer_MyRenderer.bundle", "Contents", "Resources", "default.metallib"]) + #expect( + localFileSystem.exists(metallibPath), + "Expected default.metallib to exist at \(metallibPath)" + ) + } + } + +} From 4b16b170c80f03fd78a9fa72b27b259e93f4e7c2 Mon Sep 17 00:00:00 2001 From: Robert Connell Date: Mon, 24 Nov 2025 14:50:53 -0500 Subject: [PATCH 2/5] Revert changes to Package.swift --- Package.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Package.swift b/Package.swift index 84a06043ec1..a1b09a03ae8 100644 --- a/Package.swift +++ b/Package.swift @@ -1170,7 +1170,7 @@ if !shouldUseSwiftBuildFramework { if ProcessInfo.processInfo.environment["SWIFTCI_USE_LOCAL_DEPS"] == nil { package.dependencies += [ - .package(path: "../swift-build"), + .package(url: "https://github.com/swiftlang/swift-build.git", branch: relatedDependenciesBranch), ] } else { package.dependencies += [ From aee3614dfd7c2e8921cd2754136e31e06bc53e4e Mon Sep 17 00:00:00 2001 From: Robert Connell Date: Mon, 24 Nov 2025 15:06:37 -0500 Subject: [PATCH 3/5] Remove incomplete test fixture --- .../Metal/SimpleCompileArgs/Package.swift | 32 -------- .../Plugins/MetalCompilerPlugin.swift | 74 ------------------- .../Sources/MyRenderer/Renderer.swift | 4 - .../Sources/MyRenderer/Shaders.metal | 12 --- .../MySharedTypes/include/SharedTypes.h | 14 ---- 5 files changed, 136 deletions(-) delete mode 100644 Fixtures/Metal/SimpleCompileArgs/Package.swift delete mode 100644 Fixtures/Metal/SimpleCompileArgs/Plugins/MetalCompilerPlugin.swift delete mode 100644 Fixtures/Metal/SimpleCompileArgs/Sources/MyRenderer/Renderer.swift delete mode 100644 Fixtures/Metal/SimpleCompileArgs/Sources/MyRenderer/Shaders.metal delete mode 100644 Fixtures/Metal/SimpleCompileArgs/Sources/MySharedTypes/include/SharedTypes.h diff --git a/Fixtures/Metal/SimpleCompileArgs/Package.swift b/Fixtures/Metal/SimpleCompileArgs/Package.swift deleted file mode 100644 index 9a6d3c0fc62..00000000000 --- a/Fixtures/Metal/SimpleCompileArgs/Package.swift +++ /dev/null @@ -1,32 +0,0 @@ -// swift-tools-version: 6.2 -// The swift-tools-version declares the minimum version of Swift required to build this package. - -import PackageDescription - -let package = Package( - name: "MyRenderer", - products: [ - .library( - name: "MyRenderer", - targets: ["MyRenderer"]), - .plugin( - name: "MetalCompilerPlugin", - targets: ["MetalCompilerPlugin"]), - ], - targets: [ - .target( - name: "MyRenderer", - dependencies: ["MySharedTypes"], - plugins: [ - .plugin(name: "MetalCompilerPlugin") - ]), - - .target(name: "MySharedTypes"), - - .plugin( - name: "MetalCompilerPlugin", - capability: .buildTool() - ), - ], - swiftLanguageModes: [.v6] -) diff --git a/Fixtures/Metal/SimpleCompileArgs/Plugins/MetalCompilerPlugin.swift b/Fixtures/Metal/SimpleCompileArgs/Plugins/MetalCompilerPlugin.swift deleted file mode 100644 index b124be2a091..00000000000 --- a/Fixtures/Metal/SimpleCompileArgs/Plugins/MetalCompilerPlugin.swift +++ /dev/null @@ -1,74 +0,0 @@ -import PackagePlugin -import struct Foundation.URL - -@main -struct MetalCompilerPlugin: BuildToolPlugin { - - func createBuildCommands(context: PluginContext, target: Target) async throws -> [Command] { - Diagnostics.remark("MetalCompilerPlugin: Starting plugin execution") - - guard let sourceFiles = target.sourceModule?.sourceFiles else { - Diagnostics.remark("MetalCompilerPlugin: No source files found") - return [] - } - - Diagnostics.remark("MetalCompilerPlugin: Found \(sourceFiles.count) source files") - for file in sourceFiles { - Diagnostics.remark(" - \(file.path.lastComponent)") - } - - let metalFiles = sourceFiles.filter { $0.path.extension == "metal" } - - Diagnostics.remark("MetalCompilerPlugin: Found \(metalFiles.count) .metal files") - - guard !metalFiles.isEmpty else { - Diagnostics.remark("MetalCompilerPlugin: No .metal files to compile") - return [] - } - - var commands: [Command] = [] - var airFiles: [URL] = [] - - // Compile each .metal file to .air - for metalFile in metalFiles { - let airFile = context.pluginWorkDirectoryURL.appendingPathComponent( - metalFile.path.stem + ".air" - ) - airFiles.append(airFile) - - commands.append(.buildCommand( - displayName: "Compiling Metal shader \(metalFile.path.lastComponent)", - executable: URL(fileURLWithPath: "/usr/bin/xcrun"), - arguments: [ - "metal", - "-c", - "-g", // Include debug symbols - metalFile.url.path, - "-o", - airFile.path - ], - inputFiles: [metalFile.url], - outputFiles: [airFile] - )) - } - - // Link all .air files into default.metallib - let metallibPath = context.pluginWorkDirectoryURL.appendingPathComponent("default.metallib") - - var metallibArgs = ["metallib", "-o", metallibPath.path] - metallibArgs.append(contentsOf: airFiles.map { $0.path }) - - commands.append(.buildCommand( - displayName: "Linking Metal library", - executable: URL(fileURLWithPath: "/usr/bin/xcrun"), - arguments: metallibArgs, - inputFiles: airFiles, - outputFiles: [metallibPath] - )) - - Diagnostics.remark("MetalCompilerPlugin: Will generate metallib at \(metallibPath.path)") - - return commands - } -} - diff --git a/Fixtures/Metal/SimpleCompileArgs/Sources/MyRenderer/Renderer.swift b/Fixtures/Metal/SimpleCompileArgs/Sources/MyRenderer/Renderer.swift deleted file mode 100644 index 816eb50119b..00000000000 --- a/Fixtures/Metal/SimpleCompileArgs/Sources/MyRenderer/Renderer.swift +++ /dev/null @@ -1,4 +0,0 @@ -import MySharedTypes - - -let vertex = AAPLVertex(position: .init(250, -250), color: .init(1, 0, 0, 1)) diff --git a/Fixtures/Metal/SimpleCompileArgs/Sources/MyRenderer/Shaders.metal b/Fixtures/Metal/SimpleCompileArgs/Sources/MyRenderer/Shaders.metal deleted file mode 100644 index 491edf63048..00000000000 --- a/Fixtures/Metal/SimpleCompileArgs/Sources/MyRenderer/Shaders.metal +++ /dev/null @@ -1,12 +0,0 @@ -// A relative path to SharedTypes.h. -#import "../MySharedTypes/include/SharedTypes.h" - -#include -using namespace metal; - -vertex float4 simpleVertexShader(const device AAPLVertex *vertices [[buffer(0)]], - uint vertexID [[vertex_id]]) { - AAPLVertex in = vertices[vertexID]; - return float4(in.position.x, in.position.y, 0.0, 1.0); -} - diff --git a/Fixtures/Metal/SimpleCompileArgs/Sources/MySharedTypes/include/SharedTypes.h b/Fixtures/Metal/SimpleCompileArgs/Sources/MySharedTypes/include/SharedTypes.h deleted file mode 100644 index ea51fd839d4..00000000000 --- a/Fixtures/Metal/SimpleCompileArgs/Sources/MySharedTypes/include/SharedTypes.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef SharedTypes_h -#define SharedTypes_h - - -#import - - -typedef struct { - vector_float2 position; - vector_float4 color; -} AAPLVertex; - - -#endif /* SharedTypes_h */ From db92134558c6faa3a908afb6257aba24c173be9d Mon Sep 17 00:00:00 2001 From: Robert Connell Date: Mon, 24 Nov 2025 15:14:09 -0500 Subject: [PATCH 4/5] Revert unnecessary change --- Sources/XCBuildSupport/PIF.swift | 1 - 1 file changed, 1 deletion(-) diff --git a/Sources/XCBuildSupport/PIF.swift b/Sources/XCBuildSupport/PIF.swift index 70fb684d9c4..d418da1f15c 100644 --- a/Sources/XCBuildSupport/PIF.swift +++ b/Sources/XCBuildSupport/PIF.swift @@ -925,7 +925,6 @@ public enum PIF { case CLANG_COVERAGE_MAPPING_LINKER_ARGS case MACH_O_TYPE case MACOSX_DEPLOYMENT_TARGET - case MTL_COMPILER_PATH case MODULEMAP_FILE case MODULEMAP_FILE_CONTENTS case MODULEMAP_PATH From f9a4ed98b1fe6309ad1df6002f08a7827dfceca4 Mon Sep 17 00:00:00 2001 From: Robert Connell Date: Tue, 25 Nov 2025 09:53:56 -0500 Subject: [PATCH 5/5] Verify we can load the metal library --- Tests/BuildMetalTests/BuildMetalTests.swift | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/Tests/BuildMetalTests/BuildMetalTests.swift b/Tests/BuildMetalTests/BuildMetalTests.swift index 88368253175..fe48acd6d7b 100644 --- a/Tests/BuildMetalTests/BuildMetalTests.swift +++ b/Tests/BuildMetalTests/BuildMetalTests.swift @@ -13,11 +13,16 @@ import _InternalTestSupport import Testing import Basics +import Foundation +import Metal @Suite struct BuildMetalTests { @Test( + .tags( + .TestSize.large + ), .requireHostOS(.macOS), arguments: getBuildData(for: [.swiftbuild]), ) @@ -52,6 +57,12 @@ struct BuildMetalTests { localFileSystem.exists(metallibPath), "Expected default.metallib to exist at \(metallibPath)" ) + + // Verify we can load the metal library + let device = MTLCreateSystemDefaultDevice()! + let library = try device.makeLibrary(URL: URL(fileURLWithPath: metallibPath.pathString)) + + #expect(library.functionNames.contains("simpleVertexShader")) } }