You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何避免MSBuild重复构建已完成项目?自定义.proj配置问题

解决MSBuild分组构建时重复构建前置依赖项目的问题

问题背景

通过customBuild.proj编排MSBuild并行构建,按BuildGroup1→FixedDelay→BuildRemaining的顺序分组,其中BuildGroup1是所有项目的前置依赖,RemainingProjects计划包含解决方案中除BuildGroup1外的其他项目。但执行时BuildRemaining仍会重复构建BuildGroup1内的项目,即使配置了排除规则。

核心原因

原配置中BuildGroup1是Target节点而非ItemGroup集合,导致@(BuildGroup1)在RemainingProjects的排除规则中为空,无法过滤掉已构建的前置项目,最终RemainingProjects仍包含解决方案中所有项目。

解决方案

方法1:将BuildGroup1定义为ItemGroup,确保排除规则生效

修改customBuild.proj,先把BuildGroup1的项目定义为ItemGroup,再在Target中引用该集合,同时用这个集合过滤RemainingProjects:

<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
    <!-- 定义BuildGroup1的项目集合 -->
    <ItemGroup>
        <BuildGroup1 Include="
        ../CoreProject1.csproj;
        ../CoreProject2.vcxproj;
        ../CoreProject3.vcxproj;
        ../CoreLibrary1.vcxproj;
        ../CoreLibrary2.csproj;
        ../CoreLibrary3.csproj;
        ../CoreLibrary4.vcxproj;
        "/>
    </ItemGroup>

    <!-- 获取解决方案中所有项目,并排除BuildGroup1的项目 -->
    <ItemGroup>
        <SolutionProjects Include="$(MSBuildProjectDirectory)/MyApp.sln">
            <GetSolutionProjects/>
        </SolutionProjects>
        <RemainingProjects Include="@(SolutionProjects)" Exclude="@(BuildGroup1)"/>
    </ItemGroup>

    <!-- 构建BuildGroup1,开启并行构建 -->
    <Target Name="BuildGroup1">
        <MSBuild Projects="@(BuildGroup1)" BuildInParallel="true"/>
    </Target>

    <Target Name="FixedDelay" DependsOnTargets="BuildGroup1">
        <Exec Command="PowerShell -Command Start-Sleep -Seconds 3"/>
        <Message Text="Delay Complete. Starting BuildRemaining..." Importance="high"/>
    </Target>

    <!-- 构建剩余项目,开启并行构建 -->
    <Target Name="BuildRemaining" DependsOnTargets="FixedDelay">
        <MSBuild Projects="@(RemainingProjects)" BuildInParallel="true"/>
    </Target>

    <Target Name="BuildAll" DependsOnTargets="BuildGroup1;FixedDelay;BuildRemaining"/>
</Project>

方法2:利用MSBuild增量构建特性(兜底方案)

即使不小心包含了已构建项目,MSBuild的增量构建会检查项目输出文件的时间戳,若输入文件未变更且输出文件已存在,会跳过构建。大部分.NET/VC项目默认已配置Build目标的Inputs和Outputs属性,也可在CLI中添加/p:BuildIncrementally=true强化该特性。

方法3:直接在BuildRemaining任务中指定排除参数

无需修改ItemGroup,直接在BuildRemaining的MSBuild任务中通过/p:ExcludeProjects参数排除BuildGroup1的项目:

<Target Name="BuildRemaining" DependsOnTargets="FixedDelay">
    <MSBuild Projects="$(MSBuildProjectDirectory)/MyApp.sln" 
             Properties="ExcludeProjects=../CoreProject1.csproj;../CoreProject2.vcxproj;../CoreProject3.vcxproj;../CoreLibrary1.vcxproj;../CoreLibrary2.csproj;../CoreLibrary3.csproj;../CoreLibrary4.vcxproj"
             BuildInParallel="true"/>
</Target>

验证命令

保持原CLI命令不变,执行构建:

msbuild customBuild.proj /t:BuildAll /m /p:Configuration=Release /p:Platform=x64 /p:BuildInParallel=true

内容的提问来源于stack exchange,提问作者col-A

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 11:43:18