使用 Metal 命令行来构建库

1,558 阅读2分钟

「这是我参与11月更文挑战的第8天,活动详情查看:2021最后一次更文挑战

概述

在使用 Metal 开发过程中,为了实现功能,我们可能会自定义多个 .metal 文件。我们也可能输出 sdk 给使用方调用。

此时就会遇到如下的问题:

  1. 太多的 .metal 文件,导致 sdk 文件增多,不好管理。
  2. 暴露的 .metal 透露了一些算法逻辑之类的,而这些有可能我们不希望给使用者看到。

那有没有好的解决方式呢?答案是有的,我们可以将多个 .metal 文件打包一个 Metal 库(.metallib格式) 文件。

本文将介绍如何在不使用 Xcode 情况下, 通过命令行来编译 Metal Shading Language 源代码并生成 Metal 库。

运行命令构建库

Metal 命令参数

如下是 Metal 命令行的一些参数说明,在终端中敲

xcrun -sdk macosx metal -help 

或者

xcrun -sdk iphoneos metal -help 

来查看帮助信息。

image.png

生成中间产物

使用

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

image.png

加载和使用库文件

使用 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 着色器函数的集合。加载预先编译的库,可以调用如下的方法:

总结

本文介绍了如何在不使用 Xcode 情况下, 通过命令行来编译 Metal Shading Language 源代码并生成 Metal 库以及如何加载生成的库。