建立一个解决方案,包括仅在解决方案中的项目子集中存在的目标



我有一个大型解决方案,该解决方案由50多个类库和〜10个SharePoint WSP项目组成。我正在尝试优化构建时间,因为默认情况下,在一个不错的服务器硬件上需要5分钟以上。

当前,构建过程如下(伪代码):

MSBuild.exe MySolution.sln /T:Clean
MSBuild.exe MySolution.sln /T:Build
foreach (Project.csproj in *.csproj where is WSP project)
{
    MSBuild.exe Project.csproj /T:CleanPackage
    MSBuild.exe Project.csproj /T:Package
}

我要实现的是使用单个MSBuild.exe调用来完成所有这些,以便在包装WSP项目时可以并行化构建过程并避免重复处理。

我可以轻松地为一个WSP项目做到这一点:

MSBuild.exe Project.csproj /T:Clean;CleanPackage;Build;Package

但是,当我为整个解决方案做同样的事情时:

MSBuild.exe MySolution.sln /T:Clean;CleanPackage;Build;Package

MSBUILD在解决方案文件中发现一个不包含CleanPackage目标的项目后立即失败并报告错误:

d: mysolution class.library.prohard.project class.library.project.csproj:错误msb4057:项目中不存在目标" cleanpackage"。

因此,问题是,如何克服此问题并实现单一命令构建调用而无需a)对所有csproj文件(维护噩梦)进行手动更改,b)编写自定义复杂的构建脚本?我正在考虑定义一个将包含单个自定义Target的主构建文件。但是,我不确定如何在未经手动列举两个组中的所有单个项目(类,WSP项目)中表达正确对解决方案文件的正确依赖性。


注意:虽然我的问题与这个问题相似,但我决定保持打开状态并自我求助以涵盖性能结果。

正如评论中指出的那样,此答案为实现我所需的东西提供了一种很好的方法。但是,我的问题的范围更广泛一些,专注于构建性能。因此,此答案还包括其他发现和结果。

我的补充构建脚本看起来像这样:

<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <!-- Enforce "Copy Local = false" on all references -->
  <ItemDefinitionGroup>
    <Reference>
      <Private>False</Private>
    </Reference>
  </ItemDefinitionGroup>
  <!-- substitute empty CleanPackage and Package targets to each project in case there is no actual implementation -->
  <Target Name="CleanPackage" />
  <Target Name="Package" />
</Project>

我还包括一个替代,以强制执行"复制本地"到false,以便避免复制参考的SharePoint组件。仅此单个设置消除了在构建过程中的DLL和相关文件的3.2 GB(!)的复制。我认为这仍然是实验性的,需要进行一些微调,因为我预计某些调试和单元测试方案可能会停止工作。

最后, MSBuild的单命令调用起作用。需要一个额外的参数才能通过对补充构建脚本的引用。

MSBuild.exe MySolution.sln /T:Clean;CleanPackage;Build;Package  /p:CustomBeforeMicrosoftCommonTargets=D:MySolutionpackage.targets

我能够将构建时间从301秒降低到平均40.5秒,改进86.5%。我使用的构建序列是:

Build sequence without packaging           Avg [sec]  Improvement
----------------------------------------  ----------  --------------
sequential 1xClean, 1xBuild (no package)       124.3
parallel 1xClean, 1xBuild                       58.0  -74.1 (-59.6%)
Build sequence with packaging              Avg [sec]  Improvement
----------------------------------------  ----------  --------------
sequential 1xClean, 1xBuild, NxPackage         301.0  
parallel 1xClean+Build, 1xCleanP+Package       111.0  -190.0 (-63.1%)
parallel 1xClean+Build+CleanP+Package           83.0  -218.0 (-72.4%)
parallel optimized (Copy Local=false)           40.5  -260.5 (-86.5%)

注意:

  • parallel表示应用/m开关
  • CleanP的缩写是CleanPackage
  • "复制本地"是true,除了最快的构建

硬件:带有16 GB RAM的WS2016 VM,在双Xeon E5-2695 V2 Hyper-V服务器上运行的24个VCPU。

最新更新