Skip to content

Commit

Permalink
[c# grpc] Skip compilation for --structs=false
Browse files Browse the repository at this point in the history
* The MSBuild codegen targets now detect --structs=false and skip
  automatic compilation of the non-existent `_types.cs` files.
* Added a gRPC example that show how to use a shared type assembly
  between a client and service.
  • Loading branch information
chwarr authored and lalo committed Oct 24, 2017
1 parent a120cd9 commit bab0f2b
Show file tree
Hide file tree
Showing 14 changed files with 463 additions and 20 deletions.
5 changes: 3 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,16 +64,17 @@ different versioning scheme, following the Haskell community's

* **Breaking change** The code generation MSBuild targets no longer support
Mono's xbuild: only MSBuild is supported. Mono has
[deprecated xbuild in favor MSBuild](http://www.mono-project.com/docs/about-mono/releases/5.0.0/#msbuild)
[deprecated xbuild in favor of MSBuild](http://www.mono-project.com/docs/about-mono/releases/5.0.0/#msbuild)
now that
[MSBuild is open source and cross-platform](https://github.com/Microsoft/msbuild).
These are the MSBuild targets that run `gbc` on `BondCodegen` items.
* **Breaking change** The code generation MSBuild targets now automatically
compile the generated `_grpc.cs` files if `--grpc` is passed to `gbc`.
Explicit `<Compile Include="$(IntermediateOutputPath)foo_grpc.cs" />`
lines in MSBuild projects will need to be removed to fix error MSB3105
about duplicate items. See commit TBD for an example of how to fix this.
[Issue #448](https://github.com/Microsoft/bond/issues/448)
* The code generation MSBuild targets will now skip compiling the
`_types.cs` files when `--structs=false` is passed to `gbc`.
* Added `Bond.Box.Create` helper method to create `Bond.Box<T>` instances.
* Reflection.IsBonded now recognizes custom IBonded implementations.
* Use Newtonsoft's JSON.NET BigInteger support -- when available -- to
Expand Down
50 changes: 35 additions & 15 deletions cs/build/nuget/Common.targets
Original file line number Diff line number Diff line change
Expand Up @@ -8,19 +8,20 @@
* $BOND_COMPILER_PATH : Path to directory containing gbc.exe
*
* User-Defines:
* @BondCodegen : A bond idl file (usually with a .bond extension) to compile
* @BondCodegen : A Bond IDL file (usually with a .bond extension) to compile
* %Options : Any gbc options unique to this file (prefer $BondOptions than per-file)
* @BondImportDirectory : Directory for other schemas imported within a .bond file
* $BondOutputDirectory : Output directory for the generated files, by default IntermediateOutputPath
* $BondOptions : Additional options to pass to the gbc generator
* $BondCodegenMode : Code generation mode for gbc.exe to use (default c#)
*
* These targets understand the structs/grpc switches that can be passed
* to gbc and adjust the files that are added to the Compile item as
* needed.
-->
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

<!-- A set of properties that users of these targets can use to control whether proxies, services,
and types are included in compilation. The default for all is false, as including them via
these targets breaks ReSharper. -->
<!-- Set sensible defaults. -->
<PropertyGroup>
<BondOptions Condition=" '$(BondOptions)' == '' "></BondOptions>
<BondOutputDirectory Condition=" '$(BondOutputDirectory)' == '' ">$(IntermediateOutputPath)</BondOutputDirectory>
Expand Down Expand Up @@ -72,7 +73,7 @@
BondCodegen item. -->
<Target Name="BondCodegenCs"
Inputs="$(_PreExistingBondExe);@(BondCodegen)"
Outputs="$(BondOutputDirectory)\bondcodegen.done;@(BondCodegen -> '$(BondOutputDirectory)\%(FileName)_types.cs')"
Outputs="$(BondOutputDirectory)\bondcodegen.done"
BeforeTargets="CoreCompile"
Condition="'@(BondCodegen)' != ''">

Expand Down Expand Up @@ -115,31 +116,50 @@

<!--
* BondCompileCs - whether or not we are rebuilding bond sources, we still need them compiled,
* so this target should always run.
* so this target should always run.
-->
<Target Name="BondCompileCs"
BeforeTargets="CoreCompile"
Condition="'@(BondCodegen)' != ''">

<ItemGroup>
<_BondGeneratedFiles Include="@(BondCodegen -> '$(BondOutputDirectory)\%(FileName)_types.cs')">
<_BondGen_Structs_BondOptions
Include="@(BondCodegen -> '$(BondOutputDirectory)\%(FileName)_types.cs')"
Condition="'%(BondCodegen.Options)' == ''
AND !$(BondOptions.Contains('--structs=false'))">
<AutoGen>true</AutoGen>
<DependentUpon>%(BondCodegen.Identity)</DependentUpon>
</_BondGeneratedFiles>
</_BondGen_Structs_BondOptions>

<_BondGeneratedFiles Include="@(_BondCodegenWithDefaultOptions -> '$(BondOutputDirectory)\%(FileName)_grpc.cs')"
Condition="$(BondOptions.Contains('--grpc')) AND !$(BondOptions.Contains('--grpc=false'))">
<_BondGen_Structs_Options
Include="@(BondCodegen -> '$(BondOutputDirectory)\%(FileName)_types.cs')"
Condition="'%(BondCodegen.Options)' != ''
AND !$([System.String]::new('%(BondCodegen.Options)').Contains('--structs=false'))">
<AutoGen>true</AutoGen>
<DependentUpon>%(BondCodegen.Identity)</DependentUpon>
</_BondGeneratedFiles>
</_BondGen_Structs_Options>

<_BondGeneratedFiles Include="@(BondCodegen -> '$(BondOutputDirectory)\%(FileName)_grpc.cs')"
Condition="$([System.String]::new('%(BondCodegen.Options)').Contains('--grpc')) AND !$([System.String]::new('%(BondCodegen.Options)').Contains('--grpc=false'))">
<_BondGen_Grpc_BondOptions
Include="@(_BondCodegenWithDefaultOptions -> '$(BondOutputDirectory)\%(FileName)_grpc.cs')"
Condition="$(BondOptions.Contains('--grpc'))
AND !$(BondOptions.Contains('--grpc=false'))">
<AutoGen>true</AutoGen>
<DependentUpon>%(BondCodegen.Identity)</DependentUpon>
</_BondGeneratedFiles>
</_BondGen_Grpc_BondOptions>

<_BondGeneratedFileNames Include="@(_BondGeneratedFiles)"/>
<_BondGen_Grpc_Options
Include="@(BondCodegen -> '$(BondOutputDirectory)\%(FileName)_grpc.cs')"
Condition="$([System.String]::new('%(BondCodegen.Options)').Contains('--grpc'))
AND !$([System.String]::new('%(BondCodegen.Options)').Contains('--grpc=false'))">
<AutoGen>true</AutoGen>
<DependentUpon>%(BondCodegen.Identity)</DependentUpon>
</_BondGen_Grpc_Options>

<_BondGeneratedFileNames
Include="@(_BondGen_Structs_BondOptions);
@(_BondGen_Structs_Options);
@(_BondGen_Grpc_BondOptions);
@(_BondGen_Grpc_Options)" />
<Compile Include="@(_BondGeneratedFileNames)" />

<!--
Expand Down
77 changes: 77 additions & 0 deletions cs/cs.sln
Original file line number Diff line number Diff line change
Expand Up @@ -313,6 +313,26 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "grpc_scalar", "..\examples\
{92915BD9-8AB1-4E4D-A2AC-95BBF4F82D89} = {92915BD9-8AB1-4E4D-A2AC-95BBF4F82D89}
EndProjectSection
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "grpc_sta-types", "..\examples\cs\grpc\shared-types-assembly\types\grpc_sta-types.csproj", "{723BAA6B-B309-48CF-B2A9-ECDDC91909D1}"
ProjectSection(ProjectDependencies) = postProject
{21E175D5-BBDD-4B63-8FB7-38899BF2F9D1} = {21E175D5-BBDD-4B63-8FB7-38899BF2F9D1}
{92915BD9-8AB1-4E4D-A2AC-95BBF4F82D89} = {92915BD9-8AB1-4E4D-A2AC-95BBF4F82D89}
EndProjectSection
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "grpc_sta-server", "..\examples\cs\grpc\shared-types-assembly\server\grpc_sta-server.csproj", "{A390B660-5F81-4CD3-B5EF-EB7C1C6B6AFE}"
ProjectSection(ProjectDependencies) = postProject
{43CBBA9B-C4BC-4E64-8733-7B72562D2E91} = {43CBBA9B-C4BC-4E64-8733-7B72562D2E91}
{21E175D5-BBDD-4B63-8FB7-38899BF2F9D1} = {21E175D5-BBDD-4B63-8FB7-38899BF2F9D1}
{92915BD9-8AB1-4E4D-A2AC-95BBF4F82D89} = {92915BD9-8AB1-4E4D-A2AC-95BBF4F82D89}
EndProjectSection
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "grpc_sta-client", "..\examples\cs\grpc\shared-types-assembly\client\grpc_sta-client.csproj", "{9DCEAD87-C61F-40D5-989E-0E44F56E01BE}"
ProjectSection(ProjectDependencies) = postProject
{43CBBA9B-C4BC-4E64-8733-7B72562D2E91} = {43CBBA9B-C4BC-4E64-8733-7B72562D2E91}
{21E175D5-BBDD-4B63-8FB7-38899BF2F9D1} = {21E175D5-BBDD-4B63-8FB7-38899BF2F9D1}
{92915BD9-8AB1-4E4D-A2AC-95BBF4F82D89} = {92915BD9-8AB1-4E4D-A2AC-95BBF4F82D89}
EndProjectSection
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -1181,6 +1201,60 @@ Global
{51F4135B-2CEF-436F-91CE-A6548B37E459}.Release|Mixed Platforms.Build.0 = Release|Any CPU
{51F4135B-2CEF-436F-91CE-A6548B37E459}.Release|Win32.ActiveCfg = Release|Any CPU
{51F4135B-2CEF-436F-91CE-A6548B37E459}.Release|Win32.Build.0 = Release|Any CPU
{723BAA6B-B309-48CF-B2A9-ECDDC91909D1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{723BAA6B-B309-48CF-B2A9-ECDDC91909D1}.Debug|Any CPU.Build.0 = Debug|Any CPU
{723BAA6B-B309-48CF-B2A9-ECDDC91909D1}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
{723BAA6B-B309-48CF-B2A9-ECDDC91909D1}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
{723BAA6B-B309-48CF-B2A9-ECDDC91909D1}.Debug|Win32.ActiveCfg = Debug|Any CPU
{723BAA6B-B309-48CF-B2A9-ECDDC91909D1}.Debug|Win32.Build.0 = Debug|Any CPU
{723BAA6B-B309-48CF-B2A9-ECDDC91909D1}.Fields|Any CPU.ActiveCfg = Debug|Any CPU
{723BAA6B-B309-48CF-B2A9-ECDDC91909D1}.Fields|Any CPU.Build.0 = Debug|Any CPU
{723BAA6B-B309-48CF-B2A9-ECDDC91909D1}.Fields|Mixed Platforms.ActiveCfg = Debug|Any CPU
{723BAA6B-B309-48CF-B2A9-ECDDC91909D1}.Fields|Mixed Platforms.Build.0 = Debug|Any CPU
{723BAA6B-B309-48CF-B2A9-ECDDC91909D1}.Fields|Win32.ActiveCfg = Debug|Any CPU
{723BAA6B-B309-48CF-B2A9-ECDDC91909D1}.Fields|Win32.Build.0 = Debug|Any CPU
{723BAA6B-B309-48CF-B2A9-ECDDC91909D1}.Release|Any CPU.ActiveCfg = Release|Any CPU
{723BAA6B-B309-48CF-B2A9-ECDDC91909D1}.Release|Any CPU.Build.0 = Release|Any CPU
{723BAA6B-B309-48CF-B2A9-ECDDC91909D1}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
{723BAA6B-B309-48CF-B2A9-ECDDC91909D1}.Release|Mixed Platforms.Build.0 = Release|Any CPU
{723BAA6B-B309-48CF-B2A9-ECDDC91909D1}.Release|Win32.ActiveCfg = Release|Any CPU
{723BAA6B-B309-48CF-B2A9-ECDDC91909D1}.Release|Win32.Build.0 = Release|Any CPU
{A390B660-5F81-4CD3-B5EF-EB7C1C6B6AFE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{A390B660-5F81-4CD3-B5EF-EB7C1C6B6AFE}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A390B660-5F81-4CD3-B5EF-EB7C1C6B6AFE}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
{A390B660-5F81-4CD3-B5EF-EB7C1C6B6AFE}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
{A390B660-5F81-4CD3-B5EF-EB7C1C6B6AFE}.Debug|Win32.ActiveCfg = Debug|Any CPU
{A390B660-5F81-4CD3-B5EF-EB7C1C6B6AFE}.Debug|Win32.Build.0 = Debug|Any CPU
{A390B660-5F81-4CD3-B5EF-EB7C1C6B6AFE}.Fields|Any CPU.ActiveCfg = Debug|Any CPU
{A390B660-5F81-4CD3-B5EF-EB7C1C6B6AFE}.Fields|Any CPU.Build.0 = Debug|Any CPU
{A390B660-5F81-4CD3-B5EF-EB7C1C6B6AFE}.Fields|Mixed Platforms.ActiveCfg = Debug|Any CPU
{A390B660-5F81-4CD3-B5EF-EB7C1C6B6AFE}.Fields|Mixed Platforms.Build.0 = Debug|Any CPU
{A390B660-5F81-4CD3-B5EF-EB7C1C6B6AFE}.Fields|Win32.ActiveCfg = Debug|Any CPU
{A390B660-5F81-4CD3-B5EF-EB7C1C6B6AFE}.Fields|Win32.Build.0 = Debug|Any CPU
{A390B660-5F81-4CD3-B5EF-EB7C1C6B6AFE}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A390B660-5F81-4CD3-B5EF-EB7C1C6B6AFE}.Release|Any CPU.Build.0 = Release|Any CPU
{A390B660-5F81-4CD3-B5EF-EB7C1C6B6AFE}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
{A390B660-5F81-4CD3-B5EF-EB7C1C6B6AFE}.Release|Mixed Platforms.Build.0 = Release|Any CPU
{A390B660-5F81-4CD3-B5EF-EB7C1C6B6AFE}.Release|Win32.ActiveCfg = Release|Any CPU
{A390B660-5F81-4CD3-B5EF-EB7C1C6B6AFE}.Release|Win32.Build.0 = Release|Any CPU
{9DCEAD87-C61F-40D5-989E-0E44F56E01BE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{9DCEAD87-C61F-40D5-989E-0E44F56E01BE}.Debug|Any CPU.Build.0 = Debug|Any CPU
{9DCEAD87-C61F-40D5-989E-0E44F56E01BE}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
{9DCEAD87-C61F-40D5-989E-0E44F56E01BE}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
{9DCEAD87-C61F-40D5-989E-0E44F56E01BE}.Debug|Win32.ActiveCfg = Debug|Any CPU
{9DCEAD87-C61F-40D5-989E-0E44F56E01BE}.Debug|Win32.Build.0 = Debug|Any CPU
{9DCEAD87-C61F-40D5-989E-0E44F56E01BE}.Fields|Any CPU.ActiveCfg = Debug|Any CPU
{9DCEAD87-C61F-40D5-989E-0E44F56E01BE}.Fields|Any CPU.Build.0 = Debug|Any CPU
{9DCEAD87-C61F-40D5-989E-0E44F56E01BE}.Fields|Mixed Platforms.ActiveCfg = Debug|Any CPU
{9DCEAD87-C61F-40D5-989E-0E44F56E01BE}.Fields|Mixed Platforms.Build.0 = Debug|Any CPU
{9DCEAD87-C61F-40D5-989E-0E44F56E01BE}.Fields|Win32.ActiveCfg = Debug|Any CPU
{9DCEAD87-C61F-40D5-989E-0E44F56E01BE}.Fields|Win32.Build.0 = Debug|Any CPU
{9DCEAD87-C61F-40D5-989E-0E44F56E01BE}.Release|Any CPU.ActiveCfg = Release|Any CPU
{9DCEAD87-C61F-40D5-989E-0E44F56E01BE}.Release|Any CPU.Build.0 = Release|Any CPU
{9DCEAD87-C61F-40D5-989E-0E44F56E01BE}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
{9DCEAD87-C61F-40D5-989E-0E44F56E01BE}.Release|Mixed Platforms.Build.0 = Release|Any CPU
{9DCEAD87-C61F-40D5-989E-0E44F56E01BE}.Release|Win32.ActiveCfg = Release|Any CPU
{9DCEAD87-C61F-40D5-989E-0E44F56E01BE}.Release|Win32.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down Expand Up @@ -1233,5 +1307,8 @@ Global
{A6D526FD-22B0-4151-9B3E-D20C3C05D81D} = {4268A1D3-AF40-4120-B021-D95A0F754221}
{8FC5BF4E-6932-48FC-AA57-3D5F43130699} = {4268A1D3-AF40-4120-B021-D95A0F754221}
{51F4135B-2CEF-436F-91CE-A6548B37E459} = {621A2166-EEE0-4A27-88AA-5BE5AC996452}
{723BAA6B-B309-48CF-B2A9-ECDDC91909D1} = {621A2166-EEE0-4A27-88AA-5BE5AC996452}
{A390B660-5F81-4CD3-B5EF-EB7C1C6B6AFE} = {621A2166-EEE0-4A27-88AA-5BE5AC996452}
{9DCEAD87-C61F-40D5-989E-0E44F56E01BE} = {621A2166-EEE0-4A27-88AA-5BE5AC996452}
EndGlobalSection
EndGlobal
5 changes: 2 additions & 3 deletions examples/cs/grpc/scalar/grpc_scalar.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
<RootNamespace>scalar</RootNamespace>
<AssemblyName>grpc-scalar</AssemblyName>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<BondOptions>--grpc</BondOptions>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
Expand Down Expand Up @@ -46,9 +47,7 @@
Due to the different layout of the Bond repository, we manually
specify it here. -->
<BondImportDirectory Include="..\..\..\..\idl" />
<BondCodegen Include="scalar.bond">
<Options>--grpc</Options>
</BondCodegen>
<BondCodegen Include="scalar.bond" />
<!-- Resharper Workaround -->
<Compile Include="$(IntermediateOutputPath)\scalar_types.cs" Condition="False" />
<Compile Include="$(IntermediateOutputPath)\scalar_grpc.cs" Condition="False" />
Expand Down
23 changes: 23 additions & 0 deletions examples/cs/grpc/shared-types-assembly/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Using a shared types assembly

Sometimes you want to compile the types from a .bond file separately from
the gRPC services and clients. This example shows how to split the types
into their own assembly.

The [`gbc`](https://microsoft.github.io/bond/manual/compiler.html) options
`--structs` and `--grpc` can be used to control whether codegen is performed
for structs and services.

In the `types` directory, codegen is performed without the `--grpc` switch,
so just types are generated and compiled.

In the `client` and `server` directories, however, codegen is performed with
the `--grpc` switch. Also, `--structs=false` is passed to disable the
default behavior of generating C# code for the types. If `--structs=false`
were not specified, there would be duplicate types in different assemblies,
resulting in a conflict that would need to be resolved via
[`extern alias`](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/extern-alias).

The `client` directory shows how to pass `--gprc` via per-item metadata with
`%(BondCodegen.Options)`, while the `server` directory shows how to do this
via the global `$(BondOptions)` property.
32 changes: 32 additions & 0 deletions examples/cs/grpc/shared-types-assembly/client/StaClient.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

namespace Examples.SharedTypes
{
using System;
using Grpc.Core;

public static class Client
{
const string Address = "127.0.0.1";
const int Port = 50051;

public static void Main()
{
var channel = new Channel(Address, Port, ChannelCredentials.Insecure);
var client = new Calc.CalcClient(channel);

var request = new Request
{
Num1 = 40,
Num2 = 2
};

var response = client.AddAsync(request).GetAwaiter().GetResult();

Console.WriteLine($"Addition result: {response.Payload.Deserialize().Result}");

channel.ShutdownAsync().GetAwaiter().GetResult();
}
}
}
Loading

0 comments on commit bab0f2b

Please sign in to comment.