5

我正在开发一个项目,该项目使用代码生成来使用命令行工具从基于文本的描述中生成 C# 类。我们也将开始将这些描述用于 javascript。

目前这些类是生成然后签入的,但是,我希望能够使代码自动生成,以便将任何更改传播到两个版本。

手动运行的步骤是:

servicegen.exe -i:MyService.txt -o:MyService.cs

当我构建时,我希望 MSBuild/VS 首先生成 CS 文件然后编译它。可以通过修改csproj, 或者使用带有Exec, DependentUpon&的 MSBuild 任务来做到这一点AutoGen

4

2 回答 2

6

通常我会建议将预构建命令放在预构建事件中,但由于您的命令行工具将创建编译所需的 C# 类,因此应该在 .csproj 文件的 BeforeBuild 目标中完成。之所以会这样,是因为MSBuild在整个过程中,在调用BeforeBuild和调用PreBuildEvent之间寻找需要编译的文件(可以在MSBuild使用的Microsoft.Common.targets文件中看到这个流程) .

从 BeforeBuild 目标中调用 Exec 任务以生成文件:

<Target Name="BeforeBuild">
  <Exec Command="servicegen.exe -i:MyService.txt -o:MyService.cs" />
</Target>

有关为 Exec 任务指定不同选项的更多详细信息,请参阅Exec 任务MSDN 文档。

于 2013-03-28T17:09:40.303 回答
3

Antlr 有一个流程示例,可用于将生成的代码添加到项目中。这具有显示嵌套在源文件下的文件的优点,尽管添加起来更复杂。

您需要使用要生成的文件添加一个项目组,例如:

<ItemGroup>
  <ServiceDescription Include="MyService.txt"/>
</ItemGroup>

然后将要生成的cs文件添加到包含其余源代码的ItemGroup中。

<ItemGroup>
  ...
  <Compile Include="Program.cs" />
  <Compile Include="Properties\AssemblyInfo.cs" />
  ...etc..
  <Compile Include="MyService.txt.cs">
    <AutoGen>True</AutoGen>
    <DesignTime>True</DesignTime>
    <DependentUpon>MyService.txt</DependentUpon>  <!--note: this should be the file name of the source file, not the path-->      
  </Compile>
</ItemGroup>      

然后最后添加构建目标以执行代码生成(使用 % 对 ItemGroup 中的每个项目执行命令)。这可以放入一个单独的文件中,以便可以从许多项目中包含它。

<Target Name="GenerateService">
  <Exec Command="servicegen.exe -i:%(ServiceDescription.Identity) -o:%(ServiceDescription.Identity).cs" />
</Target>
<PropertyGroup>
  <BuildDependsOn>GenerateService;$(BuildDependsOn)</BuildDependsOn>
</PropertyGroup>
于 2013-04-01T22:49:00.893 回答