【问题标题】:Preventing MSBuild from building a project in a .sln without using Solution Configurations防止 MSBuild 在不使用解决方案配置的情况下在 .sln 中构建项目
【发布时间】:2011-05-12 11:45:09
【问题描述】:

我想禁止在解决方案中构建某些项目(在 TeamCity 构建配置中,以便优化我的提交构建反馈的速度,如果您必须知道的话)。

我知道解决方案配置机制,但不希望强制大量 .sln 文件最终得到我希望能够关闭的所有事物的排列。我有基于约定的规则,我想说“如果我正在执行提交构建,我不想进行最终的安装程序打包”。 (而且我不想把它分解成一个单独的解决方案)。

我不希望在.sln 文件或通过[MsBuildEmitSolution][1] 创建的.proj 文件中使用涉及查找和替换的解决方案。我知道这里涉及out of the box solutionthis slightly related question 的问题。

我看到 MSBuild /v:diag 说:

 2>Target "Build" in file "Z.sln.metaproj" from project "Z.sln" (entry point):
   Using "MSBuild" task from assembly "Microsoft.Build.Tasks.v4.0, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a".
   Task "MSBuild"
     Global Properties:
       BuildingSolutionFile=true
         CurrentSolutionConfigurationContents=<SolutionConfiguration>
   <ProjectConfiguration Project="{C83D035D-169B-4023-9BEE-1790C9FE22AB}" AbsolutePath="X.csproj" BuildProjectInSolution="True">Debug|AnyCPU</ProjectConfiguration>
   <ProjectConfiguration Project="{15E7887D-F1DB-4D85-8454-E4EF5CBDE6D5}" AbsolutePath="Y.csproj" BuildProjectInSolution="True">Debug|AnyCPU</ProjectConfiguration>
 </SolutionConfiguration>

所以问题是:

我有没有一种简洁的方式来进行 XPath 替换或类似的更改以产生更改 BuildProjectInSolution="True" 的效果BuildProjectInSolution="False" 以上项目 Y

如果做不到这一点,我可以在.ccproj(一个 Azure 1.4 包)或.csproj(一个通用项目)文件中进行相对简单的编辑,以产生效果(包括触发依赖项目)在命令行中启用的项目msbuild Z.sln 解决方案构建被取消?

【问题讨论】:

  • 自定义 MSBuild 文件没有任何问题。我不确定为什么这不能算作一个简洁的解决方案。
  • @Ritch Melton:我已经有一个很棒的自定义 msbuild 文件来构建解决方案集(并行等,实现出色的吞吐量)。我 am 在产品中的子系统可以加载到 VS 并添加和删除项目之后 - 因此是 .sln 文件。我指出,如果我唯一能做的就是强制 MSBuild 发出一个等效的 .proj 文件,这很可悲,因为每当 MSBuild 5 改变游戏时(或者当 VS 团队最终获得 . sln 文件不是特殊情况对于实际项目来说有点重要!)
  • 我觉得你。 sln 文件问题很荒谬。有一些我不理解的 msbuild 问题及其与 Visual Studio 的集成。咆哮太长了,不能在这里发帖。
  • @Ritch Melton:我一般不会让长度等小问题阻止我发泄:D 感谢您的回复。

标签: msbuild teamcity solution azure-packaging


【解决方案1】:

您始终可以将要构建的特定项目作为参数传递给 MSBuild。

MSBuild 命令行如下所示:

MSBuild /t:<Project Name>:Rebuild;<Another Project Name>:Rebuild

在 TeamCity 中,您可以将 &lt;Project Name&gt;:&lt;Target Action&gt; 放在 MSBuild 运行程序的目标字段中。

【讨论】:

  • 您是说这(MSBuild 正在通过一组顶级项目)是原生的还是(正如@Ritch Melton [似乎] 所说)我可以制作一些东西来代替@ 987654323@ 文件。首先,即使将上述内容拆分也需要自定义任务(无论是编译的任务还是基于 PS 或 C# TaskFactory 的任务)。尽管我可能错过了你的观点,但我仍然全神贯注于我如何坐在 5 个 .sln 文件中获得 50 个 .csproj/.ccprojs,而其中没有名为 *.AzurePackage 的项目(或者可能没有 @ 987654327@s) 没有将 VS slns 分组
  • @Ruben Bartelink:我相信你可以在本地传递一组顶级项目。这将需要大量输入(将 50 个目标传递到 msbuild 命令行),但不需要您创建新目标或修改 sln/csproj 文件。
  • 我想看一个例子。就它是否解决我的问题而言,我仍然没有能力拥有一个 sln 文件,例如其中有 14 个项目,并让某人在给定配置中添加一个新项目并禁用另一个项目,并将其反映在我运行构建时发生的情况中
【解决方案2】:

不确定它是否符合整洁,但您可以将CustomAfterMicrosoftCommonTargets 设置为导入msbuild 文件以覆盖BuildDependsOn 属性,将其指向您自己的自定义构建任务。基本上,通过设置CustomAfterMicrosoftCommonTargets,您可以让 msbuild 导入包含以下内容的 msbuild 文件:

<PropertyGroup>
    <OldBuildDependsOn>$(BuildDependsOn)</OldBuildDependsOn>
    <BuildDependsOn>MyBuild</BuildDependsOn>
</PropertyGroup>

<Target Name="OldBuild" DependsOnTargets="$(OldBuildDependsOn)" />

<Target Name="MyBuild">
    <CallTarget Targets="OldBuild" Condition="<IfIWantThis>" /> 
</Target>

编辑

您可以使用以下MyBuild 目标来包含/排除基于作为IncludeInBuildExcludeFromBuild 属性传入的正则表达式的项目。 (如果你想要复杂的正则表达式,你可能会遇到 MSBuild 特殊字符转义,但这对于简单匹配来说已经足够好了)

> msbuild /p:ExcludeFromBuild="Tests|Install|Azure"

<Target Name="MyBuild">
    <CallTarget Targets="OldBuild" Condition="('$(IncludeInBuild)'=='' OR
    '$([System.Text.RegularExpressions.Regex]::IsMatch($(MSBuildProjectFullPath),
    $(IncludeInBuild), 
    System.Text.RegularExpressions.RegexOptions.IgnoreCase))'=='True') AND 
    ('$(ExcludeFromBuild)'=='' OR 
    '$([System.Text.RegularExpressions.Regex]::IsMatch($(MSBuildProjectFullPath), 
    $(ExcludeFromBuild),  
    System.Text.RegularExpressions.RegexOptions.IgnoreCase))'=='False')" /> 
</Target>

【讨论】:

  • +1 有趣的技术。看不出它是如何特别适合作为一种基于某些声明性规则有选择地影响解决方案中项目子集的构建或不构建的方式 - 我必须动态生成 CustomAfterMicrosoftTargets 才能实现这一点使用这种攻角...
  • 我不确定这是不是真的。我使用的方法是拥有一个静态 msbuild 文件ShouldBuild。这个文件包含一个UsingTask(所以我可以使用c# inline,因为我讨厌msbuild),它根据一些输入属性返回真或假。目前我只使用$(MSBuildProjectFullPath),如果它是安装程序或路径中有prototype,则返回false。但我可以获取多个属性,包括正则表达式字符串、XPath 字符串或任何我可以用来确定是否构建项目的属性。
  • 我的意思是,我省略了定义&lt;IfIWantThis&gt;的逻辑。我只是使用String.Contains,它相当粗略,但您可以根据需要将其设置为简单或复杂。
  • 是的,现在您已经提供了缺失的链接(如果这是我的首要考虑,我应该想到的)并且可以用作一般方法的基础(一个可以使用String.Split,然后进行批处理进行匹配等)。感谢您的解决方案!
【解决方案3】:

我在Parameters下添加了一个系统参数

  • 姓名:system.ExcludeFromBuild
  • 种类:系统属性 (system.)
  • 值:您的 csproj 的路径

【讨论】:

  • 您是建议将其作为在the other answer 中应用该方案的一种方式,还是建议这是默认项目系统的固有功能?
猜你喜欢
  • 2016-03-04
  • 2013-07-04
  • 2015-03-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-04-16
  • 1970-01-01
  • 2017-12-23
相关资源
最近更新 更多