如何从MSbuild设置PlatformToolset属性? [英] How to set PlatformToolset property from MSbuild?

查看:176
本文介绍了如何从MSbuild设置PlatformToolset属性?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们正在遇到AppVeyor x64构建失败,并尝试建议

We are experiencing AppVeyor x64 build failures, and trying a suggestion to set PlatformToolset to DefaultPlatformToolset. The property value is undocumented, so we want to thoroughly test it.

我们将DefaultPlatformToolset连接到 AppVeyor配置文件 :

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失败.以下是我们认为一切正确的日志:构建1.0.129 :

The value DefaultPlatformToolset is causing AppVeyor failures. Here's from the log where we believe everything is correct: 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?

How do we set PlatformToolset on the command line when using MSbuild to build the project?

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

None of these work. They produce similar errors as above.

> 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报价时,这是另一个错误:

Here's another error when trying to do that silly MS XML quoting:

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


关于错误消息的建议 ...或右键单击解决方案,然后选择重新定位解决方案" ,我们不能.这是远程的,仅命令行.我们正在尝试找出如何从如何在Appveyor构建之前运行VCUpgrade的命令行运行VCUpgrade?


Regarding the error message's suggestion ... or right-click the solution, and then selecting "Retarget solution", we can't. This is remote, command line only. We are trying to figure out how to run VCUpgrade from the command line at How to run VCUpgrade before Appveyor build?

推荐答案

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

DefaultPlatformToolset is an MSBuild property which gets set in one of the platform .props files imported by the main project. At one point in a C++ project file there should be the line

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

例如,对于VS2017,

最终又导入了<msbuild installation>\Microsoft.Cpp\v4.0\V140\Microsoft.Cpp.Default.props,从而使用设置了属性

which for instance for VS2017 ends up importing <msbuild installation>\Microsoft.Cpp\v4.0\V140\Microsoft.Cpp.Default.props in turn, which sets the property using

<DefaultPlatformToolset>v140</DefaultPlatformToolset>

由于这是msbuild属性,因此Appveyor或cmd都不知道它,因此您不能直接在appveyor.yml中引用它.即使已知,您也不能使用$(DefaultPlatformToolset)引用它,这是msbuild属性扩展语法,而cmd的格式为%ABC%.您收到的所有错误都是因为PlatformToolset属性被设置为例如字符串"DefaultPlatformToolset",而需要将其设置为实际可用平台的名称,例如v110或v140或v120_xp或...

Since this is an msbuild property it is not known by Appveyor nor by cmd and as such you cannot reference it directly from within appveyor.yml. And even if it were known, you cannot refer to it using $(DefaultPlatformToolset) which is msbuild property expansion syntax whereas cmd's is of the form %ABC%. The errors you get are all because the PlatformToolset property gets set to e.g. the string 'DefaultPlatformToolset' whereas it needs to be set to the name of an actual available platform like v110 or v140 or v120_xp or ...

如果要使用DefaultPlatformToolset,最简单的方法是将其输入到项目文件中.如果需要,仍可以从命令行覆盖它.替代方法是运行msbuild并打印其值,然后使用/p:PlatformToolset =传递该值.但这对于Visual Studio中的本地开发版本来说不是很好.

If you want to use DefaultPlatformToolset the easiest way is entering it in the project file. It can still be overriden from the commandline if needed. The alternative would be running msbuild and have it print it's value, then pass that using /p:PlatformToolset=. But that's not so nice for local development builds in Visual Studio.

要更改项目文件,请找到定义PlatformToolset的部分,并将其更改为$(DefaultPlatformToolset)-在Microsoft.Cpp.Default.props导入之后该属性可能尚未定义.为了防止您在出于某种原因未定义DefaultPlatformToolset(某些自定义版本,或可能是旧VS版本)的平台上构建的情况,请先将其设置为明智的默认值,然后设置为 . Microsoft.Cpp.Default.props.示例:

For changing the project file, find the section(s) where the PlatformToolset is defined and change it to $(DefaultPlatformToolset) - this should come after the Microsoft.Cpp.Default.props import else the property might not yet be defined. To guard against the case where you're building for a platform which for some reason does not define DefaultPlatformToolset (something custom, or possibly old VS versions) set it to a sensible default first, before the Microsoft.Cpp.Default.props. Example:

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

It is also very important to ensure the Global property group elements are set before Microsoft.Cpp.Default.props is imported. If they are not set, then MSbuild assumes an Application is being built, and it ignores the ConfigurationType that comes later:

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

这篇关于如何从MSbuild设置PlatformToolset属性?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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