From 27771aa60436b64e789cbb477708bd06a762e8c1 Mon Sep 17 00:00:00 2001 From: kkm Date: Wed, 13 Jun 2018 21:44:34 -0700 Subject: [PATCH] Document .NET build integration with Grpc.Tools --- src/csharp/INTEGRATION.md | 357 ++++++++++++++++++ src/csharp/README.md | 1 + .../doc/integration.md-fig.1-classic.png | Bin 0 -> 15266 bytes src/csharp/doc/integration.md-fig.2-sdk.png | Bin 0 -> 15863 bytes 4 files changed, 358 insertions(+) create mode 100644 src/csharp/INTEGRATION.md create mode 100644 src/csharp/doc/integration.md-fig.1-classic.png create mode 100644 src/csharp/doc/integration.md-fig.2-sdk.png diff --git a/src/csharp/INTEGRATION.md b/src/csharp/INTEGRATION.md new file mode 100644 index 00000000000..11b2c10f116 --- /dev/null +++ b/src/csharp/INTEGRATION.md @@ -0,0 +1,357 @@ +Protocol Buffers/gRPC Integration Into .NET Build +================================================= + +With Grpc.Tools package version 1.17 we made it easier to compile .proto files +in your project using the `dotnet build` command, Visual Studio, or command-line +MSBuild. You need to configure the .csproj project according to the way you want +to integrate Protocol Buffer files into your build. If you are upgrading an +existing project, read through this list of common scenarios and decide if any +one of them matches your approach. The protoc command line migration is +explained near the end of this document; this migration may be the quickest but +not the long-term solution. + +There is also a Reference section at the end of the file. + +Reporting issues +---------------- + +First thing first, if you found a bug in this new build system, or have a +scenario that is not easily covered, please open an [issue in the gRPC +repository](https://github.com/grpc/grpc/issues), and **tag the user @kkm000** +somewhere in the text (for example, include `/cc @kkm000` at end of the issue +text) to seize his immediate attention. + +Common scenarios +---------------- + +### I just want to compile .proto files into my library + +This is the approach taken by the examples in the `csharp/examples` directory. +Protoc output files (for example, `Hello.cs` and `HelloGrps.cs` compiled from +`hello.proto`) are placed among *object* and other temporary files of your +project, and automatically provided as inputs to the C# compiler. As with other +automatically generated .cs files, they are included in the source and symbols +NuGet package, if you build one. + +Simply reference your .proto files in a `` item group. The following +example will add all .proto files in a project and all its subdirectories +(excluding special directories such as `bin` and `obj`): + +```xml + + ` item. This will be the +display name of the file. In the `Include` attribute, specify the complete path +to file. A relative path is based off the project directory. + +Or, if using Visual Studio, add files _as links_ from outside directory. In the +Add Files dialog, there is a little [down arrow near the Open +button](https://stackoverflow.com/a/9770061). Click on it, and choose "Add as +link". If you do not select this option, Visual Studio will copy files to the +project directory instead. + +### I just want to generate proto and gRPC C# sources from my .proto files (no C# compile) + +Suppose you want to place generated files right beside each respective source +.proto file. Create a .csproj library file in the common root of your .proto +tree, and add a reference to Grpc.Tools package (this works in Windows too, `$` +below stands for a command prompt in either platform): + +``` +/myproject/myprotofiles$ dotnet new classlib + . . . + Restoring packages for /myproject/myprotofiles/myprotofiles.csproj... + . . . +/myproject/myprotofiles$ rm *.cs <-- remove all *.cs files from template; +C:\myproject\myprotofiles> del *.cs /y <-- on Windows, use the del command instead. +/myproject/myprotofiles$ dotnet add package Grpc.Tools +``` + +(the latter command also accepts an optional `--version X.Y` switch for a +specific version of package, should you need one). Next open the generated +.csproj file in a text editor. + +Since you are not building a package, you may not worry about adding +`PrivateAssets="All"` attribute, but it will not hurt, in case you are +repurposing the project at some time later. The important part is (1) tell the +gRPC tools to select the whole directory of files; (2) order placement of each +output besides its source, and (3) not compile the generated .cs files. Add the +following stanza under the `` xml node: + +```xml + + + +``` + +The `Include` tells the build system to recursively examine project directory +and its subdirectories (`**`) include all files matching the wildcard `*.proto`. +You can instead selectively include your files or selectively exclude files from +the glob pattern; [MSBuild documentation explains +that](https://docs.microsoft.com/visualstudio/msbuild/msbuild-items). The +`OutputDir="%(RelativePath)"` orders the output directory for each .cs file be +same as the corresponding .proto directory. Finally, `CompileOutputs="false"` +prevents compiling the generated files into an assembly. + +Note that an empty assembly is still generated, but you should ignore it. As +with any build system, it is used to detect out-of-date dependencies and +recompile them. + +#### I am getting a warning about a missing expected file! + +When we are preparing compile, there is no way to know whether a given proto +file will produce a *Grpc.cs output or not. If the proto file has a `service` +clause, it will; otherwise, it won't, but the build script cannot know that in +advance. When we are treating generated .cs files as temporary, this is ok, but +when generating them for you, creating empty files is probably not. You need to +tell the compiler which files should be compiled with gRPC services, and which +only contain protobuffer message definitions. + +One option is just ignore the warning. Another is quench it by setting the +property `Protobuf_NoWarnMissingExpected` to `true`: + +```xml + + true + +``` + +For a small to medium projects this is sufficient. But because of a missing +output dependency, the corresponding .proto file will be recompiled on every +build. If your project is large, or if other large builds depend on generated +files, and are also needlessly recompiled, you'll want to prevent these rebuilds +when files have not in fact changed, as follows: + +##### Explicitly tell protoc for which files it should use the gRPC plugin + +You need to set the `Protobuf` item property `GrpcServices` to `None` for those +.proto inputs which do not have a `service` declared (or, optionally, those +which do but you do not want a service/client stub for). The default value for +the `GrpcServices` is `Both` (both client and server stub are generated). This +is easy enough to do with glob patterns if your files are laid out in +directories according to their service use, for example: + +```xml + + + + +``` + +In this sample, all .proto files are compiled with `GrpcServices="None"`, except +for .proto files in subdirectories on any tree level named `hello/` and `bye`, +which will take `GrpcServices="Both"` Note the use of the `Update` attribute +instead of `Include`. If you write `Include` by mistake, the files will be added +to compile *twice*, once with, and once without GrpcServices. Pay attention not +to do that! + +Another example would be the use of globbing if your service .proto files are +named according to a pattern, for example `*_services.proto`. In this case, The +`Update` attribute can be written as `Update="**/*_service.proto"`, to set the +attribute `GrpcServices="Both"` only on these files. + +But what if no patterns work, and you cannot sort a large set of .proto file +into those containing a service and those not? As a last resort, + +##### Force creating empty .cs files for missing outputs. + +Naturally, this results in a dirtier compiler output tree, but you may clean it +using other ways (for example, by not copying zero-length .cs files to their +final destination). Remember, though, that the files are still important to keep +in their output locations to prevent needless recompilation. You may force +generating empty files by setting the property `Protobuf_TouchMissingExpected` +to `true`: + +```xml + + true + +``` + +#### But I do not use gRPC at all, I need only protobuffer messages compiled + +Set `GrpcServices="None"` on all proto files: + +```xml + + + +``` + +#### That's good so far, but I do not want the `bin` and `obj` directories in my tree + +You may create the project in a subdirectory of the root of your files, such as, +for example, `.build`. In this case, you want to refer to the proto files +relative to that `.build/` directory as + +```xml + + + +``` + +Pay attention to the `ProtoRoot` property. It needs to be set to the directory +where `import` declarations in the .proto files are looking for files, since the +project root is no longer the same as the proto root. + +Alternatively, you may place the project in a directory *above* your proto root, +and refer to the files with a subdirectory name: + +```xml + + + +``` + +### Alas, this all is nice, but my scenario is more complex, -OR- +### I'll investigate that when I have time. I just want to run protoc as I did before. + +One option is examine our [.targets and .props files](Grpc.Tools/build/) and see +if you can create your own build sequence from the provided targets so that it +fits your needs. Also please open an issue (and tag @kkm000 in it!) with your +scenario. We'll try to support it if it appears general enough. + +But if you just want to run `protoc` using MsBuild `` task, as you +probably did before the version 1.14 of Grpc.Tools, we have a few build +variables that point to resolved names of tools and common protoc imports. +You'll have to roll your own dependency checking (or go with a full +recompilation each time, if that works for you), but at the very least each +version of the Tools package will point to the correct location of the files, +and resolve the compiler and plugin executables appropriate for the host system. +These property variables are: + +* `Protobuf_ProtocFullPath` points to the full path and filename of protoc executable, e. g., + "C:\Users\kkm\.nuget\packages\grpc.tools\1.14.0\build\native\bin\windows\protoc.exe". + +* `gRPC_PluginFullPath` points to the full path and filename of gRPC plugin, such as + "C:\Users\kkm\.nuget\packages\grpc.tools\1.14.0\build\native\bin\windows\grpc_csharp_plugin.exe" + +* `Protobuf_StandardImportsPath` points to the standard proto import directory, for example, + "C:\Users\kkm\.nuget\packages\grpc.tools\1.14.0\build\native\include". This is + the directory where a declaration such as `import "google/protobuf/wrappers.proto";` + in a proto file would find its target. + +Use MSBuild property expansion syntax $(VariableName) in your protoc command +line to substitute these variables, for instance, + +```xml + + + $(Protobuf_ProtocFullPath) --plugin=protoc-gen-grpc=$(gRPC_PluginFullPath) -I $(Protobuf_StandardImportsPath) ....rest of your command.... + + + + +``` + +Also make sure *not* to include any file names to the `Protobuf` item +collection, otherwise they will be compiled by default. If, by any chance, you +used that name for your build scripting, you must rename it. + +### What about C++ projects? + +This is in the works. Currently, the same variables as above are set to point to +the protoc binary, C++ gRPC plugin and the standard imports, but nothing else. +Do not use the `Protobuf` item collection name so that your project remains +future-proof. We'll use it for C++ projects too. + +Reference +--------- + +### Protobuf item metadata reference + +The following metadata are recognized on the `` items. + +| Name | Default | Value | Synopsis | +|----------------|-----------|----------------------|----------------------------------| +| Access | `public` | `public`, `internal` | Generated class access | +| ProtoCompile | `true` | `true`, `false` | Pass files to protoc? | +| ProtoRoot | See notes | A directory | Common root for set of files | +| CompileOutputs | `true` | `true`, `false` | C#-compile generated files? | +| OutputDir | See notes | A directory | Directory for generated C# files | +| GrpcOutputDir | See notes | A directory | Directory for generated stubs | +| GrpcServices | `both` | `none`, `client`, | Generated gRPC stubs | +| | | `server`, `both` | | + +__Notes__ + +* __ProtoRoot__ +For files _inside_ the project cone, `ProtoRoot` is set by default to the +project directory. For every file _outside_ of the project directory, the value +is set to this file's containing directory name, individually per file. If you +include a subtree of proto files that lies outside of the project directory, you +need to set this metadatum. There is an example in this file above. The path in +this variable is relative to the project directory. + +* __OutputDir__ +The default value for this metadatum is the value of the property +`Protobuf_OutputPath`. This property, in turn, unless you set it in your +project, will be set to the value of the standard MSBuild property +`IntermediateOutputPath`, which points to the location of compilation object +outputs, such as "obj/Release/netstandard1.5/". The path in this property is +considered relative to the project directory. + +* __GrpcOutputDir__ +Unless explicitly set, will follow `OutputDir` for any given file. + +* __Access__ +Sets generated class access on _both_ generated message and gRPC stub classes. + +-=- End of INTEGRATION.md -=- \ No newline at end of file diff --git a/src/csharp/README.md b/src/csharp/README.md index d8aed94988f..7ed17c30fd3 100644 --- a/src/csharp/README.md +++ b/src/csharp/README.md @@ -87,6 +87,7 @@ $ python tools/run_tests/run_tests.py -l csharp -c dbg DOCUMENTATION ------------- +- [.NET Build Integration](INTEGRATION.md) - [API Reference][] - [Helloworld Example][] - [RouteGuide Tutorial][] diff --git a/src/csharp/doc/integration.md-fig.1-classic.png b/src/csharp/doc/integration.md-fig.1-classic.png new file mode 100644 index 0000000000000000000000000000000000000000..80c57261ad00d1892656e0f6b8c891d54fbe27a3 GIT binary patch literal 15266 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