|
|
@@ -0,0 +1,139 @@
|
|
|
+# Using the Swift Package Manager plugin
|
|
|
+
|
|
|
+The Swift Package Manager introduced new plugin capabilities in Swift 5.6, enabling the extension of
|
|
|
+the build process with custom build tools. Learn how to use the `GRPCSwiftPlugin` plugin for the
|
|
|
+Swift Package Manager.
|
|
|
+
|
|
|
+## Overview
|
|
|
+
|
|
|
+> Warning: Due to limitations of binary executable discovery with Xcode we only recommend using the Swift Package Manager
|
|
|
+plugin in leaf packages. For more information, read the `Defining the path to the protoc binary` section of
|
|
|
+this article.
|
|
|
+
|
|
|
+The plugin works by running the system installed `protoc` compiler with the `protoc-gen-grpc-swift` plugin
|
|
|
+for specified `.proto` files in your targets source folder. Furthermore, the plugin allows defining a
|
|
|
+configuration file which will be used to customize the invocation of `protoc`.
|
|
|
+
|
|
|
+### Installing the protoc compiler
|
|
|
+
|
|
|
+First, you must ensure that you have the `protoc` compiler installed.
|
|
|
+There are multiple ways to do this. Some of the easiest are:
|
|
|
+
|
|
|
+1. If you are on macOS, installing it via `brew install protoc`
|
|
|
+2. Download the binary from [Google's github repository](https://github.com/protocolbuffers/protobuf).
|
|
|
+
|
|
|
+### Adding the proto files to your target
|
|
|
+
|
|
|
+Next, you need to add the `.proto` files for which you want to generate your Swift types to your target's
|
|
|
+source directory. You should also commit these files to your git repository since the generated types
|
|
|
+are now generated on demand.
|
|
|
+
|
|
|
+> Note: imports on your `.proto` files will have to include the relative path from the target source to the `.proto` file you wish to import.
|
|
|
+
|
|
|
+### Adding the plugin to your manifest
|
|
|
+
|
|
|
+After adding the `.proto` files you can now add the plugin to the target inside your `Package.swift` manifest.
|
|
|
+First, you need to add a dependency on `grpc-swift`. Afterwards, you can declare the usage of the plugin
|
|
|
+for your target. Here is an example snippet of a `Package.swift` manifest:
|
|
|
+
|
|
|
+```swift
|
|
|
+let package = Package(
|
|
|
+ name: "YourPackage",
|
|
|
+ products: [...],
|
|
|
+ dependencies: [
|
|
|
+ ...
|
|
|
+ .package(url: "https://github.com/grpc/grpc-swift", from: "1.10.0"),
|
|
|
+ ...
|
|
|
+ ],
|
|
|
+ targets: [
|
|
|
+ ...
|
|
|
+ .executableTarget(
|
|
|
+ name: "YourTarget",
|
|
|
+ plugins: [
|
|
|
+ .plugin(name: "GRPCSwiftPlugin", package: "grpc-swift")
|
|
|
+ ]
|
|
|
+ ),
|
|
|
+ ...
|
|
|
+)
|
|
|
+
|
|
|
+```
|
|
|
+
|
|
|
+### Configuring the plugin
|
|
|
+
|
|
|
+Lastly, after you have added the `.proto` files and modified your `Package.swift` manifest, you can now
|
|
|
+configure the plugin to invoke the `protoc` compiler. This is done by adding a `grpc-swift-config.json`
|
|
|
+to the root of your target's source folder. An example configuration file looks like this:
|
|
|
+
|
|
|
+```json
|
|
|
+{
|
|
|
+ "invocations": [
|
|
|
+ {
|
|
|
+ "protoFiles": [
|
|
|
+ "Path/To/Foo.proto",
|
|
|
+ ],
|
|
|
+ "visibility": "internal",
|
|
|
+ "server": false
|
|
|
+ },
|
|
|
+ {
|
|
|
+ "protoFiles": [
|
|
|
+ "Bar.proto"
|
|
|
+ ],
|
|
|
+ "visibility": "public",
|
|
|
+ "client": false,
|
|
|
+ "keepMethodCasing": false
|
|
|
+ }
|
|
|
+ ]
|
|
|
+}
|
|
|
+```
|
|
|
+
|
|
|
+> Note: paths to your `.proto` files will have to include the relative path from the target source to the `.proto` file location.
|
|
|
+
|
|
|
+In the above configuration, you declared two invocations to the `protoc` compiler. The first invocation
|
|
|
+is generating Swift types for the `Foo.proto` file with `internal` visibility. Notice the relative path to the `.proto` file.
|
|
|
+We have also specified the `server` option and set it to false: this means that server code won't be generated for this proto.
|
|
|
+The second invocation is generating Swift types for the `Bar.proto` file with the `public` visibility.
|
|
|
+Notice the `client` option: it's been set to false, so no client code will be generated for this proto. We have also set
|
|
|
+the `keepMethodCasing` option to false, which means that the casing of the autogenerated captions won't be kept.
|
|
|
+
|
|
|
+> Note: You can find more information about supported options in the protoc Swift plugin documentation. Be aware that
|
|
|
+`server`, `client` and `keepMethodCasing` are currently the only three options supported in the Swift Package Manager plugin.
|
|
|
+
|
|
|
+### Defining the path to the protoc binary
|
|
|
+
|
|
|
+The plugin needs to be able to invoke the `protoc` binary to generate the Swift types. There are several ways to achieve this.
|
|
|
+
|
|
|
+First, by default, the package manager looks into the `$PATH` to find binaries named `protoc`.
|
|
|
+This works immediately if you use `swift build` to build your package and `protoc` is installed
|
|
|
+in the `$PATH` (`brew` is adding it to your `$PATH` automatically).
|
|
|
+However, this doesn't work if you want to compile from Xcode since Xcode is not passed the `$PATH`.
|
|
|
+
|
|
|
+If compiling from Xcode, you have **three options** to set the path of `protoc` that the plugin is going to use:
|
|
|
+
|
|
|
+* Set an environment variable `PROTOC_PATH` that gets picked up by the plugin. Here are two examples of how you can achieve this:
|
|
|
+
|
|
|
+```shell
|
|
|
+# swift build
|
|
|
+env PROTOC_PATH=/opt/homebrew/bin/protoc swift build
|
|
|
+
|
|
|
+# To start Xcode (Xcode MUST NOT be running before invoking this)
|
|
|
+env PROTOC_PATH=/opt/homebrew/bin/protoc xed .
|
|
|
+
|
|
|
+# xcodebuild
|
|
|
+env PROTOC_PATH=/opt/homebrew/bin/protoc xcodebuild <Here goes your command>
|
|
|
+```
|
|
|
+
|
|
|
+* Point the plugin to the concrete location of the `protoc` compiler is by changing the configuration file like this:
|
|
|
+
|
|
|
+```json
|
|
|
+{
|
|
|
+ "protocPath": "/path/to/protoc",
|
|
|
+ "invocations": [...]
|
|
|
+}
|
|
|
+```
|
|
|
+
|
|
|
+> Warning: The configuration file option only solves the problem for leaf packages that are using the Swift package manager
|
|
|
+plugin since there you can point the package manager to the right binary. The environment variable
|
|
|
+does solve the problem for transitive packages as well; however, it requires your users to set
|
|
|
+the variable now. In general we advise against adopting the plugin as a non-leaf package!
|
|
|
+
|
|
|
+* You can start Xcode by running `$ xed .` from the command line from the directory your project is located - this should make `$PATH` visible to Xcode.
|