MSBuild 或 Roslyn 编译项目时均支持差量编译,毕竟为了性能。我在 每次都要重新编译?太慢!让跨平台的 MSBuild/dotnet build 的 Target 支持差量编译 一文中介绍了如何使一个 Target 支持差量编译。在那篇文章中我说到差量编译会导致 Target 不执行;也就是说,如果一个 Target 对后续的编译会产生影响,那么一定不能设置为差量编译。

不过,真的会写出一些非常耗时的 Target,但是它会对后续的编译产生影响。这些 Target 如果要做差量编译,那么就不能直接使用原生的差量编译方案了。本文将介绍如何处理这样的情况。


我们遇到的问题

SourceFusion 是一个预编译框架,它在你编译期间对你的代码做一些改变。dotnet-campus/SourceFusion: SourceFusion is a pre-compile framework based on Roslyn. It helps you to build high-performance .NET code.

这意味着,这个耗时的 Target 是会改变后续的编译的,典型的是 —— 它会在编译期间增加和删除几个源代码文件。如果完全使用 Target 原生的差量编译,那么一旦这个 Target 跳过,那么也就不会增加和删除任何源代码文件了。

解决方案

解决方案是,我们写一个前置的 Target,这个 Target 支持差量编译。于是我们可以利用它的差量编译特性得知当前是否处于差量编译的状态。

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

上面的 Target 中,_WalterlvDemoRebuildingTest 是我给这个差量编译测试 Target 取的名字,WalterlvDemoCoreTarget 是那个耗时的 Target。

根据我在 每次都要重新编译?太慢!让跨平台的 MSBuild/dotnet build 的 Target 支持差量编译 一文中的差量编译的做法,我使用 $(MSBuildProjectFullPath) 也就是 csproj 文件的改变来决定差量检测的输入,用一个临时的文件 RebuildingTest.txt 来决定差量编译的输出。

在这里,我们一定需要一个文件来输出,这样 MSBuild 或者 Roslyn 检测差量的时候才能正确完成。这样,为了得到这个文件,我们实际上需要通过这个 Target 真的写一个文件出来,所以我们用了 WriteLinesToFile

实际上,我们真正需要的是 WalterlvDemoRebuildRequired 这个属性。我们可以通过这个属性判断为 true 来得知当前并非差量状态,而是需要重新编译。

后续使用

对于我们真实的耗时的 Target,则需要检测这个 WalterlvDemoRebuildRequired 的值,进行不同的处理。

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

我们在核心的 Target 里面判断 WalterlvDemoRebuildRequired 的值,如果没有被设置,说明前面的 Target 没有执行,也就是“被差量”了,我们就可以将之指定为 false。

这样,核心的 Target 里面,也就是 WalterlvDemo.exe 执行参数中,就可以拿到正确的差量状态了。true 表示正在重新编译,而 false 表示正在差量编译。

编写 Target 检测 MSBuild / dotnet build 此次编译是否是差量编译的更多相关文章

  1. 每次都要重新编译?太慢!让跨平台的 MSBuild/dotnet build 的 Target 支持差量编译

    如果你干预到了项目的编译过程,可能就需要考虑到差量编译了.不然--当你的项目大起来的时候,就会感受到每次都重新编译时,每次重复调试的过程都要进行漫长等待时的绝望和无奈. 如果你正遭遇差量编译失效,每次 ...

  2. How to output the target message in dotnet build command line

    How can I output my target message when I using dotnet build in command line. I use command line to ...

  3. 使用 MSBuild 响应文件 (rsp) 来指定 dotnet build 命令行编译时的大量参数

    在为开源项目 easiwin/MSTestEnhancer 进行持续集成编译时,需要在编译命令中传入较多的参数.这对于新接手此项目的人来说,成本还是高了一点儿.本文将介绍 MSBuild 响应文件 ( ...

  4. .NET Core的“dotnet restore”、“dotnet build”和“dotnet run”命令都是用来干什么的?

    dotnet restore 源代码:https://github.com/dotnet/cli/tree/rel/1.0.0/src/dotnet/commands/dotnet-restore 入 ...

  5. The `XXXX` target overrides the `HEADER_SEARCH_PATHS` build setting defined in `Pods/Target Support Files/Pods-game-desktop/Pods-game-desktop.release.xcconfig'. This can lead to prob

    The `game-desktop [Release]` target overrides the `HEADER_SEARCH_PATHS` build setting defined in `Po ...

  6. 使用dotnet build时复制引用dll到生成目录

    默认配置下dotnet build只会输出项目代码的dll,依赖用的是dotnet缓存中的dll,只有dotnet publish才会把依赖的dll一起输出到生成目录. 在项目csproj文件中添加以 ...

  7. linux编写脚本检测本机链接指定IP段是否畅通

    linux编写脚本检测本机链接指定IP段是否畅通,通过ping命令检测指定IP,检测命令执行结果,若为0表示畅通,若为1表示不通,以此判断网络是否畅通,但是指定机器禁用ping命令除外.代码如下: # ...

  8. 【lombok】使用lombok注解,在代码编写过程中可以调用到get/set方法,但是在编译的时候无法通过,提示找不到get/set方法

    错误如题:使用lombok注解,在代码编写过程中可以调用到get/set方法,但是在编译的时候无法通过,提示找不到get/set方法 报错如下: 解决方法: 1.首先查看你的lombok插件是否下载安 ...

  9. 【转】Android 4.3源码的下载和编译环境的安装及编译

    原文网址:http://jingyan.baidu.com/article/c85b7a641200e0003bac95a3.html  告诉windows用户一个不好的消息,windows环境下没法 ...

随机推荐

  1. Could not load file or assembly 'Microsoft.Practices.EnterpriseLibrary.Common, Version=5.0.414.0, ...

    使用oracle数据库一个多月依赖这问题一直都得不到解决,最近任务不是很忙了,所以决定把这问题解决掉.写一篇文章做记录. 以上错误主要是net程序oracle数据库使用了Microsoft Enter ...

  2. C# 多线程编程第二步——线程同步与线程安全

    上一篇博客学习了如何简单的使用多线程.其实普通的多线程确实很简单,但是一个安全的高效的多线程却不那么简单.所以很多时候不正确的使用多线程反倒会影响程序的性能. 下面先看一个例子 : class Pro ...

  3. Action<>和Func<> 区别

    其实他们两个都是委托[代理]的简写形式. 一.[action<>]指定那些只有输入参数,没有返回值的委托 Delegate的代码: public delegate void myDeleg ...

  4. ACM-ICPC 2018 沈阳赛区网络预赛 Solution

    A. Gudako and Ritsuka 留坑. B. Call of Accepted 题意:定义了一种新的运算符$x d y$ 然后给出中缀表达式,求值 思路:先中缀转后缀,然后考虑如何最大如何 ...

  5. 20145202马超 2016-2017-2 《Java程序设计》第7周学习总结

    学号 2016-2017-2 <Java程序设计>第X周学习总结 教材学习内容总结 Arrays:用于操作数组的工具类. 里面都是静态方法. asList:将数组变成list集合. 把数组 ...

  6. Putty出现 Network error:Software caused connection abort

    使用centos7.5 用Putty连接使用没多久就会出现 Network error:Software caused connection abort #修改sshd配置文件.修改3项配置即可 vi ...

  7. Java 时间格式处理

    jdk里面的日期格式处理使用SimpleDateFormat,这个类其实也是在内部调用的Calendar Calendar概念比较负责,涉及到时区和本地化 看一些简单的demo: package co ...

  8. Nginx负载均衡之健康检查

    负载均衡实例 http{ upstream myserver { server 10.10.10.1 weight=3 max_fails=3 fail_timeout=20s; server 10. ...

  9. [BZOJ4069][Apio2015]巴厘岛的雕塑

    题目大意 分成 \(x\) 堆,是的每堆的和的异或值最小 分析 这是一道非常简单的数位 \(DP\) 题 基于贪心思想,我们要尽量让最高位的 \(1\) 最小, 因此我们考虑从高位向低位进行枚举,看是 ...

  10. NOI导刊2009 提高一

    zzh大佬给我说导刊的题全是普及难度,然而我..觉得有两道题是提高的 LocalMaxima 题目解析 对于\(i\)这个数,它要想成为LocalMaxima,比它大的要全部放到最后去,比它小的想怎么 ...