MSBuild:忽略不存在的目标

Pau*_*ell 8 msbuild

Solution1.sln包含两个项目:

  • ProjectA.csproj
  • ProjectB.csproj

ProjectB有一个名为"Foo"的自定义目标.我想跑:

msbuild Solution1.sln/t:Foo

这将失败,因为ProjectA没有定义"Foo"目标.

有没有办法让解决方案忽略丢失的目标?(例如,如果特定项目不存在目标,则不执行任何操作)而不修改SLN或项目文件?

Jas*_*ome 8

如果您不想编辑解决方案或项目文件,则可以使用两部分解决方案,并且您很高兴它可以从MSBuild命令行工作,但不能从Visual Studio工作.

首先,运行时出现的错误:

MSBuild Solution1.sln /t:Foo
Run Code Online (Sandbox Code Playgroud)

不是ProjectA不包含Foo目标,而是解决方案本身不包含Foo目标.正如@Jaykul所建议的那样,设置MSBuildEmitSolution环境变量将揭示解决方案metaproj中包含的默认目标.

使用metaproj作为灵感,您可以在解决方案文件旁边引入一个新文件"before.Solution1.sln.targets"(文件名模式很重要),内容如下:

<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <Target Name="Foo">
    <MSBuild Projects="@(ProjectReference)" Targets="Foo" BuildInParallel="True" Properties="CurrentSolutionConfigurationContents=$(CurrentSolutionConfigurationContents); SolutionDir=$(SolutionDir); SolutionExt=$(SolutionExt); SolutionFileName=$(SolutionFileName); SolutionName=$(SolutionName); SolutionPath=$(SolutionPath)" SkipNonexistentProjects="%(ProjectReference.SkipNonexistentProjects)" />
  </Target>
</Project>
Run Code Online (Sandbox Code Playgroud)

MSBuild元素大多只是从解决方案metaproj的Publish目标中复制而来.调整目标名称和任何其他详细信息以适合您的方案.

有了这个文件,你现在将得到ProjectA不包含Foo目标的错误.无论如何,ProjectB可能会也可能不会构建,具体取决于项目间的依赖关系.

因此,其次,为了解决这个问题,我们需要为每个项目提供一个空的Foo目标,然后在实际已经包含一个的项目中覆盖它.

我们通过引入另一个文件来实现这一点,例如"EmptyFoo.targets"(名称并不重要),如下所示:

<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <Target Name="Foo" />
</Project>
Run Code Online (Sandbox Code Playgroud)

然后我们通过运行带有额外属性的MSBuild来让每个项目自动导入此目标文件,例如:

MSBuild Solution1.sln /t:Foo /p:CustomBeforeMicrosoftCommonTargets=c:\full_path_to\EmptyFoo.targets
Run Code Online (Sandbox Code Playgroud)

或者在第一个目标文件中的MSBuild元素的Properties属性中包含CustomerBeforeMicrosoftCommonTargets属性,您可以在其中选择性地指定相对于$(SolutionDir)属性的完整路径.

但是,如果您愿意将Foo与任何默认解决方案目标(即构建,重建,清理或发布)一起运行,您可以获得一些灵感,了解MSBuild中的Web发布管道如何使用DeployOnBuild属性来调用在包含不支持发布的其他项目类型的解决方案中发布Web项目的目标.


有关before.Solution1.sln.targets文件的更多信息,请访问:http://sedodream.com/2010/10/22/MSBuildExtendingTheSolutionBuild.aspx