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. Cocos2d-JS实现的贪吃蛇

    一.前言 相信贪吃蛇大家都玩儿过,我对贪吃蛇的印象就是在电子词典上,一只像素蛇在屏幕游走,饥渴难耐,看着豆子就要去吃,吃到豆子就会长一节,当蛇的身体越来越长的时候,它才发现这个世界变了,每走一步,都是 ...

  2. 分布式存储之MogileFS分布式文件系统简单应用

    一.分布式存储原理: 分布式存储系统,是将数据分散存储在多台独立的设备上.传统的网络存储系统采用集中的存储服务器存放所有数据,存储服务器成为系统性能的瓶颈,也是可靠性和安全性的焦点,不能满足大规模存储 ...

  3. INNODB索引与算法

    在之前的博文中简单提到了索引的分类与索引的可选择性查看:Click HERE 这片博客主要包含内容:索引组织表,索引算法B+树简单介绍 索引组织表 在innodb存储引擎中,表都是根据主键顺序组织存放 ...

  4. mybatis的namespace

    Mybatis的namespace是用来绑定Dao接口的,使用了namespace之后就可以不用写接口实现类,dao接口的方法对应mapper.xml中的sql语句. 详情见:https://blog ...

  5. 20155201 2016-2017-2 《Java程序设计》第一周学习总结

    20155201 2016-2017-2 <Java程序设计>第一周学习总结 教材学习内容总结 每一章的问题: 第一章 Java ME都有哪些成功的平台? 第二章 哪些情况可以使用impo ...

  6. Firefox管理已经保存的账号和密码

    https://support.mozilla.org/en-US/kb/password-manager-remember-delete-change-and-import You can easi ...

  7. Redis之Python 使用 Redis

    Python 使用 Redis 参考文档: http://redis.cn/clients.html#python https://github.com/andymccurdy/redis-py 安装 ...

  8. Cache与主存地址映像计算例题

    一.全相连映像 主存中任何一个块均可以映像装入到Cache中的任何一个块的位置上.主存地址分为块号和块内地址两部分,Cache地址也分为块号和块内地址.Cache的块内地址部分直接取自主存地址的块内地 ...

  9. Android多个Module统一配置相同jar或库的版本号

    Android Studio多个Module依赖相同的库时对版本号进行统一配置 在Android项目中,一个项目经常会依赖其他的一个甚至多个库文件,在这种依赖的时候最常见的一个错误就是 jar包版本不 ...

  10. EVEREST Ultimate Edition 5.50 正式版 序列号

    EVEREST Ultimate Edition 5.50 正式版 序列号 EVEREST 5.5 Final 序列号 注册码 搜集到的EVEREST最新的5.5版本的序列号 序列号: C4J1IPH ...