如何从MSbuild设置PlatformToolset属性?

时间:2017-08-02 05:26:44

标签: visual-studio msbuild appveyor

我们experiencing AppVeyor x64 build failures,并尝试向set PlatformToolset to DefaultPlatformToolset提出建议。属性值没有记录,所以我们想彻底测试它。

我们将DefaultPlatformToolsetAppVeyor configuration file

联系起来
test_script:

- cmd: >-
    msbuild /t:Build /p:PlatformToolset=DefaultPlatformToolset cryptlib.vcxproj
    msbuild /t:Build /p:PlatformToolset=DefaultPlatformToolset cryptest.vcxproj
    msbuild /t:CopyCryptestToRoot /p:PlatformToolset=DefaultPlatformToolset cryptest.vcxproj
    cryptest.exe v
    cryptest.exe tv all

DefaultPlatformToolset导致AppVeyor失败。这是我们认为一切正确的日志:Build 1.0.129

msbuild /t:Build /p:PlatformToolset=DefaultPlatformToolset cryptlib.vcxproj
Microsoft (R) Build Engine version 14.0.25420.1
Copyright (C) Microsoft Corporation. All rights reserved.
Build started 8/2/2017 5:14:24 AM.
The target "_ConvertPdbFiles" listed in a BeforeTargets attribute at "C:\Program Files (x86)\MSBuild\14.0\Microsoft.Common.targets\ImportAfter\Xamarin.Common.targets (45,37)" does not exist in the project, and will be ignored.
The target "_CollectPdbFiles" listed in an AfterTargets attribute at "C:\Program Files (x86)\MSBuild\14.0\Microsoft.Common.targets\ImportAfter\Xamarin.Common.targets (45,70)" does not exist in the project, and will be ignored.
The target "_CollectMdbFiles" listed in a BeforeTargets attribute at "C:\Program Files (x86)\MSBuild\14.0\Microsoft.Common.targets\ImportAfter\Xamarin.Common.targets (52,38)" does not exist in the project, and will be ignored.
The target "_CopyMdbFiles" listed in an AfterTargets attribute at "C:\Program Files (x86)\MSBuild\14.0\Microsoft.Common.targets\ImportAfter\Xamarin.Common.targets (52,71)" does not exist in the project, and will be ignored.
Project "C:\projects\cryptopp\cryptlib.vcxproj" on node 1 (Build target(s)).
C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\V140\Microsoft.Cpp.Platform.targets(57,5): error MSB8020: The build tools for DefaultPlatformToolset (Platform Toolset = 'DefaultPlatformToolset') cannot be found. To build using the DefaultPlatformToolset build tools, please install DefaultPlatformToolset build tools.  Alternatively, you may upgrade to the current Visual Studio tools by selecting the Project menu or right-click the solution, and then selecting "Retarget solution". [C:\projects\cryptopp\cryptlib.vcxproj]
Done Building Project "C:\projects\cryptopp\cryptlib.vcxproj" (Build target(s)) -- FAILED.
Build FAILED.

在使用MSbuild构建项目时,如何在命令行上设置PlatformToolset

这些都不起作用。它们会产生与上述类似的错误。

> msbuild /t:Build /p:PlatformToolset=DefaultPlatformToolset cryptlib.vcxproj

> msbuild /t:Build /p:PlatformToolset=$(DefaultPlatformToolset) cryptlib.vcxproj

> msbuild /t:Build /p:PlatformToolset="$(DefaultPlatformToolset)" cryptlib.vcxproj

> msbuild /t:Build /p:PlatformToolset='$(DefaultPlatformToolset)' cryptlib.vcxproj

在尝试执行这种愚蠢的MS XML引用时出现了另一个错误:

>msbuild /t:Build /p:PlatformToolset="$(DefaultPlatformToolset)" cryptlib.vcxproj
Microsoft (R) Build Engine version 4.6.1087.0
[Microsoft .NET Framework, version 4.0.30319.42000]
Copyright (C) Microsoft Corporation. All rights reserved.

MSBUILD : error MSB1011: Specify which project or solution file to use because t
his folder contains more than one project or solution file.
'#34' is not recognized as an internal or external command,
operable program or batch file.
'#34' is not recognized as an internal or external command,
operable program or batch file.

然后就是这个:

> msbuild /t:Build /p:PlatformToolset=""$(DefaultPlatformToolset)"" cryptlib.vcxproj
Microsoft (R) Build Engine version 4.6.1087.0
[Microsoft .NET Framework, version 4.0.30319.42000]
Copyright (C) Microsoft Corporation. All rights reserved.

Build started 8/2/2017 2:19:15 AM.
Project "c:\Users\Test\cryptlib.vcxproj" on node 1 (Build target(s)).
C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\V110\Microsoft.Cpp.Platform.p
rops(15,24): error MSB4115: The "exists" function only accepts a scalar value,
but its argument "$(VCTargetsPath)\Platforms\$(Platform)\PlatformToolsets\$(Pla
tformToolset)\Microsoft.Cpp.$(Platform).$(PlatformToolset).props" evaluates to
"C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\V110\\Platforms\x64\Platform
Toolsets\"$(DefaultPlatformToolset)"\Microsoft.Cpp.x64."$(DefaultPl
atformToolset)".props" which is not a scalar value.

关于错误消息的建议 ...或右键单击解决方案,然后选择"重新定位解决方案" ,我们无法做到。这只是远程命令行。我们试图弄清楚如何从命令行How to run VCUpgrade before Appveyor build?

运行VCUpgrade

1 个答案:

答案 0 :(得分:2)

DefaultPlatformToolset是一个MSBuild属性,它在主项目导入的平台.props文件中设置。在C ++项目文件中的某一点应该有一行

<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />

例如VS2017最终依次导入<msbuild installation>\Microsoft.Cpp\v4.0\V140\Microsoft.Cpp.Default.props,使用

设置属性
<DefaultPlatformToolset>v140</DefaultPlatformToolset>

由于这是一个msbuild属性,因此Appveyor或cmd都不知道,因此您无法直接从appveyor.yml中引用它。即使它已知,也不能使用$(DefaultPlatformToolset)来引用它,这是msbuild属性扩展语法,而cmd的形式为%ABC%。您获得的错误都是因为PlatformToolset属性设置为例如字符串'DefaultPlatformToolset',但需要将其设置为实际可用平台的名称,如v110或v140或v120_xp或...

如果要使用DefaultPlatformToolset,最简单的方法是在项目文件中输入它。如果需要,它仍然可以从命令行覆盖。另一种方法是运行msbuild并打印它的值,然后使用/ p:PlatformToolset =传递它。但是对于Visual Studio中的本地开发构建来说,这并不是那么好。

要更改项目文件,请找到定义PlatformToolset的部分并将其更改为$(DefaultPlatformToolset) - 这应该在之后 Microsoft.Cpp.Default.props导入其他文件该物业可能尚未定义。为了防止您为某个平台构建的情况,该平台由于某种原因未定义DefaultPlatformToolset(自定义或可能是旧的VS版本),首先将其设置为合理的默认值,之前 Microsoft.Cpp.Default.props。例如:

<PropertyGroup Label="Globals">
  <PlatformToolset>v100</PlatformToolset>
</PropertyGroup>
....
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
....
<PropertyGroup>
  <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
</PropertyGroup>

这是另一种方法:

<!-- Use DefaultPlatformToolset after Microsoft.Cpp.Default.props -->
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<!-- Set DefaultPlatformToolset to v100 (VS2010) if not defined -->
<PropertyGroup Label="EmptyDefaultPlatformToolset">
    <DefaultPlatformToolset Condition=" '$(DefaultPlatformToolset)' == '' ">v100</DefaultPlatformToolset>
  </PropertyGroup>
<PropertyGroup Label="PlatformToolset">
    <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
</PropertyGroup>

确保在导入Microsoft.Cpp.Default.props之前设置全局属性组元素也非常重要。如果未设置,则MSbuild会假定正在构建Application,并且它会忽略稍后出现的ConfigurationType

<PropertyGroup Label="Globals">
    <ProjectGuid>{016d3861-ccd6-4a50-83b4-fe4e93bea333}</ProjectGuid>
    <RootNamespace>mylib</RootNamespace>
    <ConfigurationType>StaticLibrary</ConfigurationType>
</PropertyGroup>
...
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
...
<PropertyGroup>
    <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
</PropertyGroup>