• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1<?xml version="1.0"?>
2<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
3  <PropertyGroup>
4    <MSBuildAllProjects>$(MSBuildAllProjects);$(MSBuildThisFileFullPath)</MSBuildAllProjects>
5    <!-- We allow a non-C# generator be set by the user, but skip adding outputs to Compile in this case. -->
6    <Protobuf_Generator Condition=" '$(Protobuf_Generator)' == '' and '$(Language)' == 'C#' ">CSharp</Protobuf_Generator>
7    <!-- Configuration is passing the smoke test. -->
8    <Protobuf_ProjectSupported Condition=" '$(Protobuf_Generator)' != '' ">true</Protobuf_ProjectSupported>
9    <_Protobuf_MsBuildAssembly Condition=" '$(MSBuildRuntimeType)' == 'Core' ">netstandard1.3\Protobuf.MSBuild.dll</_Protobuf_MsBuildAssembly>
10    <_Protobuf_MsBuildAssembly Condition=" '$(MSBuildRuntimeType)' != 'Core' ">net45\Protobuf.MSBuild.dll</_Protobuf_MsBuildAssembly>
11  </PropertyGroup>
12
13  <UsingTask AssemblyFile="$(_Protobuf_MsBuildAssembly)" TaskName="Grpc.Tools.ProtoToolsPlatform" />
14  <UsingTask AssemblyFile="$(_Protobuf_MsBuildAssembly)" TaskName="Grpc.Tools.ProtoCompilerOutputs" />
15  <UsingTask AssemblyFile="$(_Protobuf_MsBuildAssembly)" TaskName="Grpc.Tools.ProtoReadDependencies" />
16  <UsingTask AssemblyFile="$(_Protobuf_MsBuildAssembly)" TaskName="Grpc.Tools.ProtoCompile" />
17
18  <PropertyGroup Condition=" '$(Protobuf_ProjectSupported)' == 'true' ">
19    <Protobuf_IntermediatePath Condition=" '$(Protobuf_IntermediatePath)' == '' ">$(IntermediateOutputPath)</Protobuf_IntermediatePath>
20    <Protobuf_OutputPath Condition=" '$(Protobuf_OutputPath)' == '' ">$(Protobuf_IntermediatePath)</Protobuf_OutputPath>
21    <Protobuf_DepFilesPath Condition=" '$(Protobuf_DepFilesPath)' == '' ">$(Protobuf_IntermediatePath)</Protobuf_DepFilesPath>
22  </PropertyGroup>
23
24  <ItemDefinitionGroup Condition=" '$(Protobuf_ProjectSupported)' == 'true' and '$(Language)' == 'C#' ">
25    <Protobuf>
26      <Access Condition="'%(Protobuf.Access)' == '' ">Public</Access>
27      <ProtoCompile Condition="'%(Protobuf.ProtoCompile)' == '' ">True</ProtoCompile>
28      <ProtoRoot Condition="'%(Protobuf.ProtoRoot)' == '' " />
29      <CompileOutputs Condition="'%(Protobuf.CompileOutputs)' == ''">True</CompileOutputs>
30      <OutputDir Condition="'%(Protobuf.OutputDir)' == '' ">$(Protobuf_OutputPath)</OutputDir>
31      <Generator Condition="'%(Protobuf.Generator)' == '' and '$(DisableProtobufDesignTimeBuild)' != 'true' " >MSBuild:Compile</Generator>
32    </Protobuf>
33  </ItemDefinitionGroup>
34
35  <ItemGroup Condition=" '$(Protobuf_ProjectSupported)' == 'true' and '$(Language)' == 'C#' ">
36    <PropertyPageSchema Include="$(MSBuildThisFileDirectory)Protobuf.CSharp.xml">
37      <Context>File;BrowseObject</Context>
38    </PropertyPageSchema>
39    <AvailableItemName Include="Protobuf" />
40  </ItemGroup>
41
42  <PropertyGroup>
43    <!-- NET SDK: by default, do not include proto files in the directory.
44         Current Microsoft's recommendation is against globbing:
45         https://docs.microsoft.com/en-us/dotnet/core/tools/csproj#recommendation -->
46    <EnableDefaultProtobufItems Condition=" '$(EnableDefaultProtobufItems)' == '' ">false</EnableDefaultProtobufItems>
47  </PropertyGroup>
48
49  <!-- Check configuration sanity before build. -->
50  <Target Name="_Protobuf_SanityCheck" BeforeTargets="PrepareForBuild">
51    <Error
52      Condition=" '$(Protobuf_ProjectSupported)' != 'true' "
53      Text="Google.Protobuf.Tools proto compilation is only supported by default in a C# project (extension .csproj)" />
54  </Target>
55
56  <!--================================================================================
57                                     Tool path resolution
58   =================================================================================-->
59
60  <!-- Extension point for plugin packages: use Protobuf_ToolsOs and Protobuf_ToolsCpu
61       to resolve executable. Either or both may be blank, however, if resolution
62       fails; do check them before using. -->
63  <Target Name="Protobuf_ResolvePlatform">
64    <ProtoToolsPlatform>
65      <Output TaskParameter="Os" PropertyName="_Protobuf_ToolsOs"/>
66      <Output TaskParameter="Cpu" PropertyName="_Protobuf_ToolsCpu"/>
67    </ProtoToolsPlatform>
68
69    <PropertyGroup>
70      <!-- First try environment variable. -->
71      <Protobuf_ToolsOs Condition=" '$(Protobuf_ToolsOs)' == '' ">$(PROTOBUF_TOOLS_OS)</Protobuf_ToolsOs>
72      <Protobuf_ToolsCpu Condition=" '$(Protobuf_ToolsCpu)' == '' ">$(PROTOBUF_TOOLS_CPU)</Protobuf_ToolsCpu>
73      <Protobuf_ProtocFullPath Condition=" '$(Protobuf_ProtocFullPath)' == '' ">$(PROTOBUF_PROTOC)</Protobuf_ProtocFullPath>
74
75      <!-- Next try OS and CPU resolved by ProtoToolsPlatform. -->
76      <Protobuf_ToolsOs Condition=" '$(Protobuf_ToolsOs)' == '' ">$(_Protobuf_ToolsOs)</Protobuf_ToolsOs>
77      <Protobuf_ToolsCpu Condition=" '$(Protobuf_ToolsCpu)' == '' ">$(_Protobuf_ToolsCpu)</Protobuf_ToolsCpu>
78      <Protobuf_ProtocFullPath Condition=" '$(Protobuf_ProtocFullPath)' == '' and '$(Protobuf_ToolsOs)' == 'windows' "
79           >$(Protobuf_PackagedToolsPath)\$(Protobuf_ToolsOs)_$(Protobuf_ToolsCpu)\protoc.exe</Protobuf_ProtocFullPath>
80      <Protobuf_ProtocFullPath Condition=" '$(Protobuf_ProtocFullPath)' == '' "
81           >$(Protobuf_PackagedToolsPath)/$(Protobuf_ToolsOs)_$(Protobuf_ToolsCpu)/protoc</Protobuf_ProtocFullPath>
82    </PropertyGroup>
83
84    <Error Condition=" '$(DisableProtobufDesignTimeBuild)' != 'true' and '$(PROTOBUF_PROTOC)' == ''
85                        and ( '$(Protobuf_ToolsOs)' == '' or '$(Protobuf_ToolsCpu)' == '' ) "
86      Text="Google.Protobuf.Tools cannot determine host OS and CPU.&#10;Use environment variables PROTOBUF_TOOLS_OS={linux|macosx|windows} and PROTOBUF_TOOLS_CPU={x86|x64} to try the closest match to your system.&#10;You may also set PROTOBUF_PROTOC to specify full path to the host-provided compiler (v3.5+ is required)." />
87  </Target>
88
89  <!--================================================================================
90                                     Proto compilation
91   =================================================================================-->
92
93  <!-- Extension points. -->
94  <Target Name="Protobuf_BeforeCompile" />
95  <Target Name="Protobuf_AfterCompile" />
96
97  <!-- Main compile sequence. Certain steps are gated by the value $(DisableProtobufDesignTimeBuild),
98       so the sequence is good for either design time or build time. -->
99  <Target Name="Protobuf_Compile"
100          Condition=" '@(Protobuf)' != '' "
101          DependsOnTargets=" Protobuf_BeforeCompile;
102                             Protobuf_ResolvePlatform;
103                             _Protobuf_SelectFiles;
104                             Protobuf_PrepareCompile;
105                             _Protobuf_AugmentLanguageCompile;
106                             _Protobuf_CoreCompile;
107                             Protobuf_ReconcileOutputs;
108                             Protobuf_AfterCompile" />
109
110  <!-- Do proto compilation by default in a C# project. In other types, the user invoke
111       Protobuf_Compile directly where required. -->
112  <!-- TODO(kkm): Do shared compile in outer multitarget project? -->
113  <Target Name="_Protobuf_Compile_BeforeCsCompile"
114          BeforeTargets="BeforeCompile"
115          DependsOnTargets="Protobuf_Compile"
116          Condition=" '$(Language)' == 'C#' " />
117
118  <Target Name="_Protobuf_SetProtoRoot">
119    <!-- Guess .proto root for the files. Whenever the root is set for a file explicitly,
120         leave it as is. Otherwise, for files under the project directory, set the root
121         to "." for the project's directory, as it is the current when compiling; for the
122         files outside of project directory, use each .proto file's directory as the root. -->
123    <FindUnderPath Path="$(MSBuildProjectDirectory)"
124                   Files="@(Protobuf->WithMetadataValue('ProtoRoot',''))">
125      <Output TaskParameter="InPath" ItemName="_Protobuf_NoRootInProject"/>
126      <Output TaskParameter="OutOfPath" ItemName="_Protobuf_NoRootElsewhere"/>
127    </FindUnderPath>
128    <ItemGroup>
129      <!-- Files with explicit metadata. -->
130      <Protobuf_Rooted Include="@(Protobuf->HasMetadata('ProtoRoot'))" />
131      <!-- In-project files will have ProtoRoot='.'. -->
132      <Protobuf_Rooted Include="@(_Protobuf_NoRootInProject)">
133        <ProtoRoot>.</ProtoRoot>
134      </Protobuf_Rooted>
135      <!-- Out-of-project files will have respective ProtoRoot='%(RelativeDir)'. -->
136      <Protobuf_Rooted Include="@(_Protobuf_NoRootElsewhere)">
137        <ProtoRoot>%(RelativeDir)</ProtoRoot>
138        <ProtoRoot Condition=" '$(Protobuf_ProtoRoot)' != '' ">$(Protobuf_ProtoRoot)</ProtoRoot>
139      </Protobuf_Rooted>
140    </ItemGroup>
141  </Target>
142
143  <!-- Select files that should be compiled. -->
144  <Target Name="_Protobuf_SelectFiles"
145          DependsOnTargets=" _Protobuf_SetProtoRoot">
146    <ItemGroup>
147      <!-- Files with explicit metadata. -->
148      <Protobuf_Compile Include="@(Protobuf_Rooted)" />
149      <!-- Remove files not for compile. -->
150      <Protobuf_Compile Remove="@(Protobuf_Compile)" Condition=" '%(ProtoCompile)' != 'true' " />
151      <!-- Ensure invariant Source=%(Identity). -->
152      <Protobuf_Compile>
153        <Source>%(Identity)</Source>
154      </Protobuf_Compile>
155    </ItemGroup>
156  </Target>
157
158  <!-- Extension point for non-C# project. Protobuf_Generator should be supported
159       by the ProtoCompile task, but we skip inferring expected outputs. All proto
160       files will be always recompiled with a warning, unless you add expectations
161       to the Protobuf_ExpectedOutputs collection.
162
163       All inferred ExpectedOutputs will be added to code compile (C#) in a C# project
164       by default. This is controlled per-proto by the CompileOutputs metadata. -->
165  <Target Name="Protobuf_PrepareCompile" Condition=" '@(Protobuf_Compile)' != '' ">
166    <!-- Predict expected names. -->
167    <ProtoCompilerOutputs Condition=" '$(Language)' == 'C#' "
168                          Protobuf="@(Protobuf_Compile)"
169                          Generator="$(Protobuf_Generator)">
170      <Output TaskParameter="PossibleOutputs" ItemName="Protobuf_ExpectedOutputs" />
171      <Output TaskParameter="PatchedProtobuf" ItemName="_PatchedProtobuf" />
172    </ProtoCompilerOutputs>
173    <!-- Replace Protobuf_Compile with PatchedProtobuf. -->
174    <ItemGroup>
175       <Protobuf_Compile Remove="@(_PatchedProtobuf)"/>
176       <Protobuf_Compile Include ="@(_PatchedProtobuf)"/>
177    </ItemGroup>
178    <!-- Read any dependency files from previous compiles. -->
179    <ProtoReadDependencies Condition=" '$(Protobuf_DepFilesPath)' != '' and '$(DisableProtobufDesignTimeBuild)' != 'true' "
180                           Protobuf="@(Protobuf_Compile)"
181                           ProtoDepDir="$(Protobuf_DepFilesPath)" >
182      <Output TaskParameter="Dependencies" ItemName="Protobuf_Dependencies" />
183    </ProtoReadDependencies>
184  </Target>
185
186  <!-- Add all expected outputs, and only these, to language compile.  -->
187  <Target Name="_Protobuf_AugmentLanguageCompile"
188          DependsOnTargets="_Protobuf_EnforceInvariants"
189          Condition=" '$(Language)' == 'C#' ">
190    <ItemGroup>
191      <_Protobuf_CodeCompile Include="@(Protobuf_ExpectedOutputs->Distinct())"
192         Condition=" '%(Source)' != '' and '@(Protobuf_Compile->WithMetadataValue('CompileOutputs', 'true'))' != '' " />
193      <Compile Include="@(_Protobuf_CodeCompile)" />
194    </ItemGroup>
195  </Target>
196
197  <!-- These invariants must be kept for compile up-to-date check to work. -->
198  <Target Name="_Protobuf_EnforceInvariants">
199    <!-- Enforce Source=Identity on proto files. The 'Source' metadata is used as a common
200         key to match dependencies/expected outputs in the lists for up-to-date checks. -->
201    <ItemGroup>
202      <Protobuf_Compile>
203        <Source>%(Identity)</Source>
204      </Protobuf_Compile>
205    </ItemGroup>
206
207    <!-- Remove possible output and dependency declarations that have no Source set, or those
208         not matching any proto marked for compilation. -->
209    <ItemGroup>
210      <Protobuf_ExpectedOutputs Remove="@(Protobuf_ExpectedOutputs)" Condition=" '%(Protobuf_ExpectedOutputs.Source)' == '' " />
211      <Protobuf_ExpectedOutputs Remove="@(Protobuf_ExpectedOutputs)" Condition=" '%(Source)' != '' and '@(Protobuf_Compile)' == '' " />
212      <Protobuf_Dependencies Remove="@(Protobuf_Dependencies)" Condition=" '%(Protobuf_Dependencies.Source)' == '' " />
213      <Protobuf_Dependencies Remove="@(Protobuf_Dependencies)" Condition=" '%(Source)' != '' and '@(Protobuf_Compile)' == '' " />
214    </ItemGroup>
215  </Target>
216
217  <!-- Gather files with and without known outputs, separately. -->
218  <Target Name="_Protobuf_GatherStaleFiles"
219          Condition=" '@(Protobuf_Compile)' != '' "
220          DependsOnTargets="_Protobuf_EnforceInvariants; _Protobuf_GatherStaleSimple; _Protobuf_GatherStaleBatched">
221    <ItemGroup>
222      <!-- Drop outputs from MSBuild inference (they won't have the '_Exec' metadata).  -->
223      <_Protobuf_OutOfDateProto Remove="@(_Protobuf_OutOfDateProto->WithMetadataValue('_Exec',''))" />
224    </ItemGroup>
225  </Target>
226
227  <Target Name="_Protobuf_GatherStaleSimple">
228    <!-- Simple selection: always compile files that have no declared outputs (but warn below). -->
229    <ItemGroup>
230      <_Protobuf_OutOfDateProto Include="@(Protobuf_Compile)"
231                                Condition = " '%(Source)' != '' and '@(Protobuf_ExpectedOutputs)' == '' ">
232        <_Exec>true</_Exec>
233      </_Protobuf_OutOfDateProto>
234    </ItemGroup>
235
236    <!-- You are seeing this warning because there was no Protobuf_ExpectedOutputs items with
237         their Source attribute pointing to the proto files listed in the warning. Such files
238         will be recompiled on every build, as there is nothing to run up-to-date check against.
239         Set Protobuf_NoOrphanWarning to 'true' to suppress if this is what you want. -->
240    <Warning Condition=" '@(_Protobuf_OutOfDateProto)' != '' and '$(Protobuf_NoOrphanWarning)' != 'true' "
241             Text="The following files have no known outputs, and will be always recompiled as if out-of-date:&#10;@(_Protobuf_Orphans->'&#10;    %(Identity)', '')" />
242  </Target>
243
244  <Target Name="_Protobuf_GatherStaleBatched"
245          Inputs="@(Protobuf_Compile);%(Source);@(Protobuf_Dependencies);$(MSBuildAllProjects)"
246          Outputs="@(Protobuf_ExpectedOutputs)" >
247    <!-- The '_Exec' metadatum is set to distinguish really executed items from those MSBuild so
248         "helpfully" infers in a bucketed task. For the same reason, cannot use the intrinsic
249         ItemGroup task here. -->
250    <CreateItem Include="@(Protobuf_Compile)" AdditionalMetadata="_Exec=true">
251      <Output TaskParameter="Include" ItemName="_Protobuf_OutOfDateProto"/>
252    </CreateItem>
253  </Target>
254
255  <!-- Extension point: Plugins massage metadata into recognized metadata
256       values passed to the ProtoCompile task. -->
257  <Target Name="Protobuf_PrepareCompileOptions" Condition=" '@(Protobuf_Compile)' != '' ">
258    <ItemGroup>
259      <Protobuf_Compile>
260        <_OutputOptions Condition=" '%(Protobuf_Compile.Access)' == 'Internal' ">%(Protobuf_Compile._OutputOptions);internal_access</_OutputOptions>
261      </Protobuf_Compile>
262    </ItemGroup>
263  </Target>
264
265  <Target Name="_Protobuf_CoreCompile"
266          Condition=" '$(DisableProtobufDesignTimeBuild)' != 'true' "
267          DependsOnTargets="Protobuf_PrepareCompileOptions;_Protobuf_GatherStaleFiles">
268    <!-- Ensure output directories. -->
269    <MakeDir Directories="%(_Protobuf_OutOfDateProto.OutputDir)" />
270    <MakeDir Directories="%(_Protobuf_OutOfDateProto.GrpcOutputDir)" />
271    <MakeDir Directories="$(Protobuf_DepFilesPath)" />
272
273    <!-- Force output to the current directory if the user has set it to empty. -->
274    <ItemGroup>
275      <_Protobuf_OutOfDateProto>
276        <OutputDir Condition=" '%(OutputDir)' == '' ">.</OutputDir>
277      </_Protobuf_OutOfDateProto>
278    </ItemGroup>
279
280    <ProtoCompile Condition=" '@(_Protobuf_OutOfDateProto)' != '' "
281      ToolExe="$(Protobuf_ProtocFullPath)"
282      Generator="$(Protobuf_Generator)"
283      Protobuf="%(_Protobuf_OutOfDateProto.Source)"
284      ProtoPath="%(_Protobuf_OutOfDateProto.AdditionalImportDirs);$(Protobuf_StandardImportsPath);%(_Protobuf_OutOfDateProto.ProtoRoot)"
285      ProtoDepDir="$(Protobuf_DepFilesPath)"
286      OutputDir="%(_Protobuf_OutOfDateProto.OutputDir)"
287      OutputOptions="%(_Protobuf_OutOfDateProto._OutputOptions)"
288      GrpcPluginExe="%(_Protobuf_OutOfDateProto.GrpcPluginExe)"
289      GrpcOutputDir="%(_Protobuf_OutOfDateProto.GrpcOutputDir)"
290      GrpcOutputOptions="%(_Protobuf_OutOfDateProto._GrpcOutputOptions)"
291    >
292      <Output TaskParameter="GeneratedFiles" ItemName="_Protobuf_GeneratedFiles"/>
293    </ProtoCompile>
294
295    <!-- Compute files expected but not in fact produced by protoc. -->
296    <ItemGroup Condition=" '@(_Protobuf_OutOfDateProto)' != '' ">
297      <Protobuf_ExpectedNotGenerated Include="@(Protobuf_ExpectedOutputs)"
298                                     Condition=" '%(Source)' != '' and '@(_Protobuf_OutOfDateProto)' != '' " />
299      <Protobuf_ExpectedNotGenerated Remove="@(_Protobuf_GeneratedFiles)" />
300    </ItemGroup>
301  </Target>
302
303  <!-- Extension point. Plugins and/or unsupported projects may take special care of the
304       Protobuf_ExpectedNotGenerated list in BeforeTargets. We just silently create the
305       missing outputs so that out-of-date checks work (we do not add them to language
306       compile though). You can empty this collection in your Before targets to do nothing.
307       The target is not executed if the proto compiler is not executed. -->
308  <Target Name="Protobuf_ReconcileOutputs"
309          Condition=" '$(DisableProtobufDesignTimeBuild)' != 'true' ">
310    <!-- Warn about unexpected/missing files outside object file directory only.
311         This should have happened because build was incorrectly customized. -->
312    <FindUnderPath Path="$(BaseIntermediateOutputPath)" Files="@(Protobuf_ExpectedNotGenerated)">
313      <Output TaskParameter="InPath" ItemName="_Protobuf_ExpectedNotGeneratedInTemp"/>
314      <Output TaskParameter="OutOfPath" ItemName="_Protobuf_ExpectedNotGeneratedElsewhere"/>
315    </FindUnderPath>
316
317    <!-- Prevent unnecessary recompilation by silently creating empty files. This probably
318         has happened because a proto file with an rpc service was processed by the gRPC
319         plugin, and the user did not set GrpcOutput to None. When we treat outputs as
320         transient, we can do it permissively. -->
321    <Touch Files="@(_Protobuf_ExpectedNotGeneratedInTemp)" AlwaysCreate="true" />
322
323    <!-- Also create empty files outside of the intermediate directory, if the user wants so. -->
324    <Touch Files="@(_Protobuf_ExpectedNotGeneratedElsewhere)" AlwaysCreate="true"
325           Condition=" '$(Protobuf_TouchMissingExpected)' == 'true' "/>
326
327    <!-- You are seeing this warning because there were some Protobuf_ExpectedOutputs items
328         (outside of the transient directory under obj/) not in fact produced by protoc. -->
329    <Warning Condition=" '@(_Protobuf_ExpectedNotGeneratedElsewhere)' != '' and $(Protobuf_NoWarnMissingExpected) != 'true' "
330             Text="Some expected protoc outputs were not generated.&#10;@(_Protobuf_ExpectedNotGeneratedElsewhere->'&#10;    %(Identity)', '')" />
331  </Target>
332
333  <!--================================================================================
334                                   Proto cleanup
335   =================================================================================-->
336
337  <!-- We fully support cleanup only in a C# project. If extending the build for other
338       generators/plugins, then mostly roll your own. -->
339
340  <!-- Extension points. -->
341  <Target Name="Protobuf_BeforeClean" />
342  <Target Name="Protobuf_AfterClean" />
343
344  <!-- Main cleanup sequence. -->
345  <Target Name="Protobuf_Clean"
346          Condition=" '@(Protobuf)' != '' "
347          DependsOnTargets=" Protobuf_BeforeClean;
348                             _Protobuf_SetProtoRoot;
349                             Protobuf_PrepareClean;
350                             _Protobuf_CoreClean;
351                             Protobuf_AfterClean" />
352
353  <!-- Do proto cleanup by default in a C# project. In other types, the user should
354       invoke Protobuf_Clean directly if required. -->
355  <Target Name="_Protobuf_Clean_AfterCsClean"
356          AfterTargets="CoreClean"
357          DependsOnTargets="Protobuf_Clean"
358          Condition=" '$(Protobuf_ProjectSupported)' == 'true' and '$(Language)' == 'C#' " />
359
360  <!-- Extension point for non-C# project. ProtoCompilerOutputs is not invoked for
361       non-C# projects, since inferring protoc outputs is required, so this is a
362       no-op in other project types. In your extension target populate the
363       Protobuf_ExpectedOutputs with all possible output. An option is to include
364       all existing outputs using Include with a wildcard, if you know where to look.
365
366       Note this is like Protobuf_PrepareCompile, but uses @(Protobuf_Rooted) regardless
367       of the Compile metadata, to remove all possible outputs. Plugins should err
368       on the side of overextending the Protobuf_ExpectedOutputs here.
369
370       All ExpectedOutputs will be removed. -->
371  <Target Name="Protobuf_PrepareClean" Condition=" '@(Protobuf_Rooted)' != '' ">
372    <!-- Predict expected names. -->
373    <ProtoCompilerOutputs Condition=" '$(Language)' == 'C#' "
374                          Protobuf="@(Protobuf_Rooted)"
375                          Generator="$(Protobuf_Generator)">
376      <Output TaskParameter="PossibleOutputs" ItemName="Protobuf_ExpectedOutputs" />
377    </ProtoCompilerOutputs>
378  </Target>
379
380  <Target Name="_Protobuf_CoreClean">
381    <ItemGroup>
382      <_Protobuf_Protodep Include="$(Protobuf_DepFilesPath)*.protodep" />
383    </ItemGroup>
384    <Delete Files="@(Protobuf_ExpectedOutputs);@(_Protobuf_Protodep)" TreatErrorsAsWarnings="true" />
385  </Target>
386
387  <!--================================================================================
388                                  Design-time support
389   =================================================================================-->
390
391  <!-- Add all .proto files to the SourceFilesProjectOutputGroupOutput, so that:
392       * Visual Studio triggers a build when any of them changed;
393       * The Pack target includes .proto files into the source package.  -->
394  <Target Name="_Protobuf_SourceFilesProjectOutputGroup"
395          BeforeTargets="SourceFilesProjectOutputGroup"
396          Condition=" '@(Protobuf)' != '' " >
397    <ItemGroup>
398      <SourceFilesProjectOutputGroupOutput Include="@(Protobuf->'%(FullPath)')" />
399    </ItemGroup>
400  </Target>
401</Project>
402