MSbuild:编译项目然后迭代[反射,生成代码,重新编译]直到它收敛

时间:2012-04-06 09:14:56

标签: .net-3.5 msbuild compact-framework code-generation tail-recursion

我有一个自定义.targets文件,用于支持编译后代码生成。我重写了一些目标,目的是让AfterBuild任务运行代码生成器,再次调用CoreBuild,然后尾递归,直到结果收敛到定点或过多的迭代是必要的。 (我认为我从未见过它需要超过3次汇编才能收敛,但我使用5作为限制。)

在某些方面这是一个笨拙的黑客,特别是通过使用CycleDepth来打破无限循环并阻止MSBuild跳过重复的任务,因为属性没有改变,但它适用于其主要用途case:生成代码以实现对象序列化方法并通过部分类机制将它们合并,作为优化以避免在运行时基于反射的序列化。我遇到了一个崩溃的情况:如果使用/m(并行)选项对解决方案调用MSBuild,则构建可怕地死掉:它看起来好像应该是什么迭代是同时被调用。

有没有办法在不破坏并行MSBuild的情况下实现这种递归?

由于需要同时针对标准和Compact Framework,我在某种程度上被修订锁定为3.5;优化对于在慢速Compact Framework设备上实现足够的速度是必要的。

  <Target Name="BeforeCompile" Condition="Exists('$(ProjectDir)CodeGenerationPostBuild.xml')">
    <PropertyGroup>
      <AssemblyTimestampBeforeCompile>%(IntermediateAssembly.ModifiedTime)</AssemblyTimestampBeforeCompile>
    </PropertyGroup>
  </Target>

  <Target Name="AfterCompile" Condition="Exists('$(ProjectDir)CodeGenerationPostBuild.xml')">
    <PropertyGroup>
      <AssemblyTimestampAfterCompile>%(IntermediateAssembly.ModifiedTime)</AssemblyTimestampAfterCompile>
    </PropertyGroup>
  </Target>

  <Target Name="AfterBuild" Condition="Exists('$(ProjectDir)CodeGenerationPostBuild.xml') and ('$(AssemblyTimestampBeforeCompile)'!='$(AssemblyTimestampAfterCompile)')">
    <Exec WorkingDirectory="$(ProjectDir)" Command="&quot;$(SolutionDir)..\CodeGen\CodeGeneration.Engine\bin\$(ConfigurationName)\CodeGeneration.Engine.exe&quot; &quot;$(ProjectDir)CodeGenerationPostBuild.xml&quot;  Command=Build ConfigurationName=$(ConfigurationName)" IgnoreExitCode="true">
      <Output TaskParameter="ExitCode" PropertyName="PostBuildExitCode" />
    </Exec>
    <Error Condition="$(PostBuildExitCode) == 2" Code="BS0002" Text="Read-only generated code file found; did it get checked in again?" />
    <Error Condition="$(PostBuildExitCode) == 99" Code="BS0099" Text="Error in code generation; see detailed build output." />
    <Error Condition="'$(CycleDepth)' == 'xxxxx' And $(PostBuildExitCode) != 0" Code="BS1000" Text="Compilation taking too many iterations to converge.  Do you have [AssemblyVersion(&quot;1.0.*&quot;)] in your AssemblyInfo.cs?" />
    <MSBuild Condition="'$(CycleDepth)' != 'xxxxx' And $(PostBuildExitCode) == 1" Projects="$(ProjectPath)" Targets="CoreBuild; AfterBuild" Properties="CycleDepth=$(CycleDepth)x" />
  </Target>

0 个答案:

没有答案