【问题标题】:MSBuild Inheriting Platform ToolsetMSBuild 继承平台工具集
【发布时间】:2014-07-29 23:49:35
【问题描述】:

我正在尝试彻底检查我的项目的构建过程。我们有大约 330 个 Visual C++ 项目,我们在去年从 Visual Studio 2005 升级到了 Visual Studio 2013。我想利用 MSBuild 来改进我们现在拥有的非常串行的构建脚本的构建时间。我已经完成了粗略的第一次通过,并将发布版本的构建时间从约 2 小时减少到约 20 分钟。在执行此操作的过程中,我将很多常见的项目设置合并到一个.props file 中。在这样做的过程中,我遇到了一个绊脚石。

我希望将平台工具集从一个 VSProps 文件继承到包含它的所有项目。在我创建的新 .props 文件的顶部,我放了以下内容:

<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ImportGroup Label="PropertySheets" />
<PropertyGroup Label="Configuration">
   <PlatformToolSet>v120</PlatformToolSet>
</PropertyGroup>
<PropertyGroup Label="UserMacros" />

然后我从各个项目文件中删除了相应的&lt;PlatformToolSet&gt;v120&lt;/PlatformToolset&gt;

唉,事情已经开始走下坡路了。项目(在 Visual Studio 2013 中)现在在解决方案资源管理器中显示类似 CoreGeometry (Visual Studio 2010) 的内容,并且项目本身似乎想要引用 v100 平台工具集。当我构建时,它会向我抱怨:

C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\V120\Microsoft.CppBuild.targets(362,5): warning MSB8003: Could not find WindowsSDKDir variable from the registry. TargetFrameworkVersion or PlatformToolset may be set to an invalid version number.

1&gt;C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\V120\Microsoft.CppCommon.targets(341,5): error MSB6006: "CL.exe" exited with code -1073741515.

我能够解决这个问题的唯一方法是在 .vcxproj 上手动设置 PlatformToolset,这并不可怕,我只是有点恼火,其他所有属性似乎都继承了,但 PlatformToolset 没有.

我的问题是: 我可以使用 .props 文件将通用 PlatformToolSet 继承到未指定平台工具集的 .vcxproj 中吗?

第二个问题:我是否应该以这种方式搞乱平台工具集,还是让自己面临以后维护噩梦的风险?

【问题讨论】:

  • 对于 VS2017,如果我将 PlatformToolset 放在 *.vcxproj 文件旁边的 "Directory.Build.props" 文件中,它似乎对我有用。这是因为“Directory.Build.props”在导入层次结构的早期被隐式导入(在“Microsoft.Cpp.Default.props”中导入的“Microsoft.Common.props”中)。请注意,某些设置在此文件中不起作用,例如。 G。 IncludePath.

标签: visual-studio build msbuild


【解决方案1】:

从所有项目中提取通用设置到单独的 .props 文件和&lt;Import&gt; 是非常好的做法。我对我的项目做同样的事情,包括在 .props 文件中配置PlatformToolset 属性,并且以这种方式构建它没有问题。

与此相关的几点:

  1. PlatformToolset 属性或任何其他属性没有什么特别之处。在 .props 文件中配置属性与直接在 .vcxproj 文件中设置属性相同(但是请参阅下面关于排序的观点)。当然,也有一些内置属性,您根本无法配置,但它们始终是只读属性。
  2. 唯一无法覆盖属性的情况,如果属性值直接从命令行传递以进行构建(例如,msbuild mysolution.sln /p:Platform=x86 将使用平台属性设置为 x86 并覆盖在项目中不会生效)。
  3. 解释项目的 msbuild 引擎与显示项目设置的 Visual Studio 之间存在差异。在某些情况下,您可能会发现在重构 .vcxproj 文件后,一些标准项目配置对话框未显示您在 .props 文件中配置的信息。为了缓解这种情况,通过设置 .props 文件的绝对路径,确保 .props 文件的 &lt;Import&gt; 命令始终能够找到 .props 文件。其次,确保在配置文件中为 &lt;PropertyGroup&gt; 元素指定 Label 属性,就像在 .vcxproj 文件中指定的一样。
  4. 最后,确保您的&lt;Import&gt; 元素位于正确的位置。通常你希望它是第一个导入,在你导入标准 .targets 和 .props 之前,比如 Microsoft.Cpp.defaults.props 等。原因是 msbuild 通过对语句执行顺序扫描来工作,所以指令的顺序很重要.

为了使 #3 和 #4 更容易,这里有一个技巧来指定 .props 文件的绝对路径。假设您的解决方案名称为 MySolution.sln,自定义 props 文件为 MyCustomProps.props,放置在解决方案所在的同一目录中:

<PropertyGroup>
       <RootFolder>$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory),MySolution.sln))</RootFolder>
</PropertyGroup>
<Import Project="$(RootFolder)\MyCustomProps.props" />

【讨论】:

  • Seva,感谢您的意见!看来第 4 点(&lt;Import&gt; 位置)是我的问题。当通过 Visual Studio 添加时,PropertySheets 通过名为 "PropertySheets"ImportGroup 导入,该 "PropertySheets" 出现在 PropertyGroup "Configuration" 下方。非常感谢您的路径技巧,但我们在多个解决方案之间共享项目,这些解决方案并不总是一致的。随着我们迁移源代码控制提供程序,这种情况可能会发生变化,因此我会提出一些一致性要求。
  • @KevinKennedy,您用来定位 RootFolder 的文件不必是 .sln 文件,它可以是任何其他文件,只要它始终存在即可。
猜你喜欢
  • 2012-05-04
  • 2016-01-14
  • 1970-01-01
  • 2013-05-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-12-26
  • 1970-01-01
相关资源
最近更新 更多