使目标在MSBuild中的解决方案级别运行一次

时间:2010-03-16 13:30:46

标签: msbuild

我需要一组需要为整个解决方案执行一次的任务。这将运行将修改每个项目的任务,以便为每个项目运行一组单独的任务。我们之前已经使用一个单独的项目来完成这个解决方案,该解决方案具有解决方案级别的任务,但我们希望摆脱这一点。有没有人这样做过,或者有人对如何实现这个有任何建议吗?

2 个答案:

答案 0 :(得分:7)

由于解决方案文件不是MSBuild格式,因此无法轻松扩展或自定义。如果您想要更多地控制构建过程,则必须创建一个“驱动程序”msbuild文件,该文件将替换您的解决方案文件。在此驱动程序文件中,您将构建所需的所有项目并执行一些其他任务。您可以使用MSBuild task执行此操作。这是一个展示如何构建多个项目的示例。

<Project ...>
    <ItemGroup>
        <Projects Include="proj01.csproj"/>
        <Projects Include="proj02.csproj"/>
        <Projects Include="proj03.csproj"/>
    </ItemGroup>

    <Target Name="BuildAll">
        <MSBuild Projects="@(Projects)" BuildInParallel="true" />
    </Target>

</Project>

因此,在您的情况下,您只需在构建项目之前执行任务。另请注意,我为BuildInParallel指定了值true,表示MSBuild可以尝试同时构建多个项目。

答案 1 :(得分:1)

另一种解决方案是使单个目标分发到MSBuild调用的目标,并删除尽可能多的Global属性。我的团队在Directory.Build.props导入的props文件的InitialTargets中有一个目标-类似于:

<Target Name="Prebuild">
  <MSBuild Projects="$(MSBuildThisFileFullPath)"
           Targets="PrebuildWorker"
           RemoveProperties="Configuration;Platform;TargetFramework;BuildProjectReferences" />
</Target>

由于MSBuild似乎在{project file, global properties, target}集合上同步并行生成,因此通过删除所有属性,您可以同步生成并为正在生成的所有项目运行一次。缺点:您必须维护RemoveProperties属性-MSBuild无法删除所有全局属性。如果构建中的某些问题发出了一个新的MSBuild任务,并指定了一个自定义属性,那么您将获得另一个Target实例的调用。

而且-当然-您的构建将与此目标同步。您可以尝试通过设置CompileDependsOn依赖于Prebuild目标来挂钩目标,以允许独立进行构建。但是,最好使用InitialTargets尽早运行目标,这似乎是更好的选择。