Write a MSBuild Target to detect whether the project is rebuilding or not

吕毅 2020/1/23 12:49:21

MSBuild or the dotnet build command both supports Incremental Building for compiling performance. You can read How to: Build Incrementally - Visual Studio - Microsoft Docs to lean more about incremental building. When a target supports increment building and the project is rebuilding for the moment, the Target will not execute. So if it affects followed other Targets, it cannot be set to incremental building.

But how can I detect a incremental building behavior and do something different things if my Target affects followed other Targets? In this post, I’ll talk about that.


The Problem

SourceFusion is a pre-compile framework and allows you to change you code during the compiling. You can visit dotnet-campus/SourceFusion: SourceFusion is a pre-compile framework based on Roslyn. It helps you to build high-performance .NET code. to view the open-source project.

The Target in the SourceFusion takes long time and affects followed Targets such as the CoreCompile Target. If it use a completely incremental building, the Target will be skipped when building and no more source code will be added or removed before the CoreCompile Target. So nothing will happen during a incremental building and the SourceFusion changes nothing.

The Solution

We can write another Target helps us to detect rebuilding behavior. We can define a property to tell us whether it is a incremental building or not.

<Target Name="_WalterlvDemoRebuildingTest" BeforeTargets="WalterlvDemoCoreTarget"
        Inputs="$(MSBuildProjectFullPath)" Outputs="$(WalterlvDemoFolder)RebuildingTest.txt">
  <ItemGroup>
    <RebuildingTestLine Include="true" />
  </ItemGroup>
  <CallTarget Targets="_WalterlvDemoRebuildingTestInitialize" />
  <WriteLinesToFile File="$(WalterlvDemoFolder)RebuildingTest.txt" Lines="@(RebuildingTestLine)" Overwrite="True" />
</Target>

<Target Name="_WalterlvDemoRebuildingTestInitialize">
  <PropertyGroup>
    <WalterlvDemoRebuildRequired>true</SourceFusionRebuildRequired>
  </PropertyGroup>
</Target>

In this code, I write two Targets and the second one doesn’t define any BeforeTargets or AfterTargets attributes. So this Target will not be executed automatically unless you call it explicitly. I define a property named SourceFusionRebuildRequired in it to flag the rebuilding status.

I call this separated Target in the first target which defines Inputs and Outputs attributes. We can know that if a Target want to support incremental building the two attributes are important. So this Target supports that.

These are the three mentioned Targets:

  • _WalterlvDemoRebuildingTest The Target that supports the incremental building
  • _WalterlvDemoRebuildingTestInitialize The Target to assign a value to property SourceFusionRebuildRequired
  • WalterlvDemoCoreTarget The long-time Target that will use the incremental building test value

I use a csproj file as a input file and another temp file as a output file. Then if a project file changed and a rebuilding will happen. To generate a temp output file I should use WriteLinesToFile Task to write one.

I need WalterlvDemoRebuildRequired property to detect the rebuilding behavior. If the project is rebuilding the property will be assigned because the _WalterlvDemoRebuildingTestInitialize is called and if the project is incremental building the property will not be assigned.

Then we can check the value of WalterlvDemoRebuildRequired to detect a rebuilding or incremental building.

How to use this property

For the long-time Target WalterlvDemoCoreTarget, it should detect the property and do something different.

<Target Name="WalterlvDemoCoreTarget" BeforeTargets="CoreCompile">
  <PropertyGroup>
    <WalterlvDemoRebuildRequired Condition="'$(WalterlvDemoRebuildRequired)' == ''">false</WalterlvDemoRebuildRequired>
  </PropertyGroup>
  <Exec ConsoleToMSBuild="True" Command="WalterlvDemo.exe -r $(WalterlvDemoRebuildRequired)" />
</Target>

We define the same property only if it is not been assigned. But we assign it as a false value which is different to the _WalterlvDemoRebuildingTestInitialize Target.

Then pass the property value to the core Task, and the Task will know whether it is completely rebuilding or incremental building.


References

blog footer

随时随地学软件编程-关注百度小程序和微信小程序
关于找一找教程网

本站文章仅代表作者观点,不代表本站立场,所有文章非营利性免费分享。
本站提供了软件编程、网站开发技术、服务器运维、人工智能等等IT技术文章,希望广大程序员努力学习,让我们用科技改变世界。
[Write a MSBuild Target to detect whether the project is rebuilding or not]http://www.zyiz.net/tech/detail-100474.html

上一篇:只需 5 秒钟,你就能取到 WPF 程序的超高分辨率超高清截图

下一篇:编写 Target 检测 MSBuild / dotnet build 此次编译是否是差量编译

赞(0)
关注微信小程序
程序员编程王-随时随地学编程

扫描二维码或查找【程序员编程王】

可以随时随地学编程啦!

技术文章导航 更多>
扫一扫关注最新编程教程