Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Incremental build support in Biztalk 2009 and 2010 .btproj projects?

While chasing incremental build time improvements, I found that .btproj files and thus all other projects that depend on these are rebuilt (partly) on each incremental build. Tracking this all the way to BizTalkCommon.targets, I found that it does a 2 pass compilation of the assembly - but only the first pass respects already built artifacts, thus breaking the incremental part of the dependency chain. The offending target can be seen in BizTalkCommon.targets (line 228):

<!-- Delete the assembly and rerun the build process -->
<Target Name="SecondPass"
        Condition="$(SecondBuild)!=true and $(TempAssemblyOnly)!=true">

    <Delete Files="@(IntermediateAssembly)" />
    <MSBuild Projects="$(MSBuildProjectFile)" Properties="SecondBuild=true"/>
</Target>

I realize that there's a reason for the 2 pass build, but simply cannot believe it wouldn't be possible to specify appropriate in- and outputs for the target to handle incremental builds correctly.

Does anyone know if there's a patch for the .targets file, or if there's another good reason that incremental builds aren't supported?

like image 696
RasmusKL Avatar asked Oct 12 '22 07:10

RasmusKL


1 Answers

You can enable incremental compilation of MSBuild BizTalk project with a couple of very simple changes. Basically, you need to override two targets that are defined in the BizTalkCommon.targets file.

Those targets can be overriden in your own .btproj files and do not require modifying the original .targets file that ships with BizTalk.

How To

First Create you own .targets file to host your customizations, for instance BizTalkCustom.targets :

<Import Project="$(MSBuildExtensionsPath)\Microsoft\BizTalk\BizTalkC.targets" />

<!-- Rerun the build process (second pass) -->
<Target Name="SecondPass" Condition="$(SecondBuild)!=true and $(TempAssemblyOnly)!=true and @(XLang)!=''">
    <MSBuild Projects="$(MSBuildProjectFile)" Properties="SecondBuild=true" />
</Target>

<!-- Compile XLang/s orchestration -->
<Target
    Name="CompileODX"
    Condition="$(SecondBuild)==true"
    Inputs="@(XLang);$(MSBuildAllProjects);$(ClrTypesAssembly)"
    Outputs="$(BuildDone)">

  <!-- Delete previously generated C# files from XLang compilation -->
  <Delete Files="@(IntermediateAssembly)" />
  <Delete Files="@(CSharpOutputFromXLang)" />

  <XLangTask XLangItems="@(XLang)"
             ProjectReferences="@(ReferencePath)"
             WarningLevel="$(WarningLevel)"
             BpelCompliance="$(BpelCompliance)"
             DefineConstants="$(DefineConstants)"
             TreatWarningsAsErrors="$(TreatWarningsAsErrors)"
             TempAssembly="$(ClrTypesAssembly)"
             OutputDirectory="$(XLangOutputPath)">
  </XLangTask>
</Target>

Then, replace the last Import statement in your .btproj file:

  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
  <Import Project="$(MyCustomExtensions)\BizTalkCustom.targets" />

How doe it work

BizTalk Server projects need somehow to be compiled in two passes. The first pass compiles schemas, maps and pipelines, whereas the second pass compiles orchestrations.

You'll notice that the overriden targets are very very similar than the original ones, defined inside the BizTalkCommon.targets file. In fact, I made two simple changes:

  1. The first change involves modifying the SecondPass Target and adding an extra test in the Conditionattribute. This test is usefull to prevent the second pass from occurring if your project does not even have Orchestrations.

  2. Unfortunately, if your project contains Orchestrations, the original SecondPass Target deletes the intermediate assemblies and then proceed to compile the Orchestrations. However, the CompileODX Target does not need to run if all files are already up to date. Therefore, the second change involves moving the Delete Task from the SecondPass Target to the CompiledODX Target.

That's all there is to it.

like image 96
Maxime Labelle Avatar answered Nov 01 '22 17:11

Maxime Labelle