概述
在使用 Metal 开发过程中,为了实现功能,我们可能会自定义多个 .metal 文件。我们也可能输出 sdk 给使用方调用。
此时就会遇到如下的问题:
- 太多的 .metal 文件,导致 sdk 文件增多,不好管理。
- 暴露的 .metal 透露了一些算法逻辑之类的,而这些有可能我们不希望给使用者看到。
那有没有好的解决方式呢?答案是有的,我们可以将多个 .metal 文件打包一个 Metal 库(.metallib格式) 文件。
本文将介绍如何在不使用 Xcode 情况下, 通过命令行来编译 Metal Shading Language 源代码并生成 Metal 库。
运行命令构建库
Metal 命令参数
如下是 Metal 命令行的一些参数说明,在终端中敲 xcrun -sdk macosx metal -help
或者 xcrun -sdk iphoneos metal -help
来查看帮助信息。
生成中间产物
使用 xcrun -sdk macosx metal MyLibrary.metal -o MyLibrary.air
命令将单个 .metal 文件编译成 .air 文件。.air 文件存储的是 Metal Shading Language 源码编译后的中间代码。
对于多个 .air 文件,我们可以通过 metal-ar 工具来将多个 .air 文件压缩到一个 .metalar 文件中 (metal-ar 类似于 UNIX 下 的ar)。
生成库文件
直接通过 metallib 工具将多个 .air 文件或 .metalar文件合并成一个 .metallib文件。
.metalar 文件只是一个中间文件,最后都会合并到 .metallib 中。
可以通过如下命令来实现合并: xcrun -sdk macosx metallib MyLibrary.air -o MyLibrary.metallib
加载和使用库文件
使用 Metal 的命令行工具构建了一个库之后,需要将生成的 .metallib 文件添加到 Xcode 项目中。然后调用 makeLibrary(filepath:) 方法以作为 MTLLibrary 来加载刚才生成的库。 guard let libraryFile = Bundle.main.path(forResource: "MyLibrary", ofType: "metallib") else { return } do { let myLibrary = try device.makeLibrary(filepath: libraryFile) } catch let error { print("Library error: \(error.localizedDescription)") }
MTLLibrary 是 Metal 着色器函数的集合。加载预先编译的库,可以调用如下的方法: - makeDefaultLibrary() - makeLibrary(filepath:) - makeLibrary(data:) 加载运行时编译的库,可以调用如下的方法: - makeLibrary(source:options:completionHandler:) - makeLibrary(source:options:)
总结
本文介绍了如何在不使用 Xcode 情况下, 通过命令行来编译 Metal Shading Language 源代码并生成 Metal 库以及如何加载生成的库。