Skip to content

Instantly share code, notes, and snippets.

@0x1306a94
Last active March 28, 2024 12:35
Show Gist options
  • Star 11 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save 0x1306a94/09674ddc71459ffa00a625f01b5f49cc to your computer and use it in GitHub Desktop.
Save 0x1306a94/09674ddc71459ffa00a625f01b5f49cc to your computer and use it in GitHub Desktop.
Swift Macro does not use SPM integration

Swift Macro 不使用 Swift Package Manager如何集成

  • Swift Macro分为两部分,一部分为宏的具体实现(编译器插件),一部分为Macro Lib用于导出宏定义以及所需要的附属代码,这里说的不使用SPM指的是编译器插件这部分
  • 仔细观察Xcode使用SPM集成Macro时,在编译命令中通过-load-plugin-executable参数指定了对应宏实现的插件可执行文件路径
  • 同时在swift源码中也找到了相关参数TypeCheckMacros.cpp TypeCheckMacros.cpp
  • swift源码中可得知,宏实现插件即可以是动态库(dylib)也可以是可执行文件
  • 系统内置的宏实现是通过 -plugin-path <dylib path> 加载
  • 内置的宏实现动态库在Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/Lib/swift/host/plugins
具体步骤
  • 编写宏实现代码,这一步可以通过SPM也可以直接通过Xcode创建命令行程序项目,完成宏实现代码编写
  • unixzii/EnhancedMirror为例,编译生成宏实现可执行文件
git clone https://github.com/unixzii/EnhancedMirror
cd EnhancedMirror
swift build
  • 新建一个测试项目,并将EnhancedMirror/Sources/EnhancedMirror下源文件拖动到测试项目中,只是方便测试,也可将其单独编译出framework或者xcframework
  • Xcode Build Settings中搜索OTHER_SWIFT_FLAGS,并添加如下参数
-Xfrontend -load-plugin-executable -Xfrontend xxx/EnhancedMirror/.build/arm64-applemacosx/debug/EnhancedMirrorMacros#EnhancedMirrorMacros
  • 然后正常编译
  • 以动态库的方式就是将宏实现部分代码编译成 dylib,之后同样通过OTHER_SWIFT_FLAGS添加参数
#1 or #2
#1
-Xfrontend -load-plugin-library -Xfrontend xx/libEnhancedMirrorMacros.dylib
#2
-Xfrontend -external-plugin-path -Xfrontend <dylib path>
  • 不能直接OTHER_SWIFT_FLAGS=-load-plugin-executable path/EnhancedMirrorMacros#EnhancedMirrorMacros,因为OTHER_SWIFT_FLAGS的参数会交给swiftc,但是最终完成swift源码编译的是swift-frontend,因此需要通过-Xfrontend xxx方式,之后swiftc会将-Xfrontend的参数传递给swift-frontend

使用CocoaPods集成

  • 先将宏实现代码编译成可执行文件或者dylib
  • 然后在podspec中添加上面所示的编译参数
Pod::Spec.new do |spec|
  spec.pod_target_xcconfig = {
    "OTHER_SWIFT_FLAGS" => "-Xfrontend -load-plugin-executable -Xfrontend path/EnhancedMirrorMacros#EnhancedMirrorMacros"
  }
  
  spec.user_target_xcconfig = {
    "OTHER_SWIFT_FLAGS" => "-Xfrontend -load-plugin-executable -Xfrontend path/EnhancedMirrorMacros#EnhancedMirrorMacros"
  }
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment