MSBuild:忽略不存在的目标 [英] MSBuild: Ignore targets that don't exist

查看:245
本文介绍了MSBuild:忽略不存在的目标的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Solution1.sln包含两个项目:

Solution1.sln contains two projects:

  • ProjectA.csproj
  • ProjectB.csproj

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

ProjectB has a custom target called "Foo". I want to run:

msbuild Solution1.sln/t:Foo

msbuild Solution1.sln /t:Foo

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

This will fail because ProjectA doesn't define the "Foo" target.

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

Is there a way to make the solution ignore the missing target? (E.g., do nothing if the target doesn't exist for a specific project) without modifying the SLN or project files?

推荐答案

如果您不想编辑解决方案或项目文件,并且很高兴可以通过MSBuild命令运行该解决方案,则可以分为两部分:行,但不是来自Visual Studio.

There is a two-part solution if you don't want to edit the solution or project files and you're happy for it to work from MSBuild command-line but not from Visual Studio.

首先,您在运行时遇到的错误:

Firstly, the error you get when you run:

MSBuild Solution1.sln /t:Foo

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

Is not that ProjectA does not contain a Foo target but that the solution itself does not contain a Foo target. As @Jaykul suggests, setting the MSBuildEmitSolution environment variable will reveal the default targets contained within the solution metaproj.

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

Using the metaproj as inspiration you can introduce a new file "before.Solution1.sln.targets" next to the solution file (the file name pattern is important) with contents like this:

<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>

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

The MSBuild element is mostly just copied from the solution metaproj's Publish target. Adjust the target name and any other details to suit your scenario.

有了此文件,您现在会得到错误,即ProjectA不包含Foo目标. ProjectB可能会或可能不会建立,这取决于项目间的依赖关系.

With this file in place, you'll now get the error that ProjectA does not contain the Foo target. ProjectB may or may not build anyway depending on inter-project dependencies.

因此,第二,要解决此问题,我们需要给每个项目一个空的Foo目标,然后将其覆盖在实际上已经包含一个目标的项目中.

So, secondly, to solve this problem we need to give every project an empty Foo target which is then overridden in projects that actually already contain one.

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

We do this by introducing another file, eg "EmptyFoo.targets" (name not important) that looks like this:

<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <Target Name="Foo" />
</Project>

然后,通过运行带有附加属性的MSBuild,我们将使每个项目自动导入此目标文件,例如:

And then we get every project to automatically import this targets file either by running MSBuild with an extra property, eg:

MSBuild Solution1.sln /t:Foo /p:CustomBeforeMicrosoftCommonTargets=c:\full_path_to\EmptyFoo.targets

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

Or include the CustomerBeforeMicrosoftCommonTargets property in the Properties attribute on the MSBuild element in the first targets file where you could optionally specify the full path relative to the $(SolutionDir) property.

但是,如果您愿意将Foo与任何默认解决方案目标(即Build,Rebuild,Clean或Publish)结合使用,则可以从MSBuild中的Web发布管道如何使用DeployOnBuild属性中获得启发.在包含其他不支持发布的项目类型的解决方案中,在Web项目上调用发布目标.

However, if you're willing to run Foo in conjunction with any of the default solution targets (ie Build, Rebuild, Clean, or Publish) you could take some inspiration for how the Web Publishing Pipeline in MSBuild uses the DeployOnBuild property to call the Publish target on Web projects in a solution containing other project types that don't support publishing.

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

More info on the before.Solution1.sln.targets file here: http://sedodream.com/2010/10/22/MSBuildExtendingTheSolutionBuild.aspx

这篇关于MSBuild:忽略不存在的目标的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆