【问题标题】:How to set PlatformToolset property from MSbuild?如何从 MSbuild 设置 PlatformToolset 属性?
【发布时间】:2017-08-02 05:26:44
【问题描述】:

我们是experiencing AppVeyor x64 build failures,正在尝试向set PlatformToolset to DefaultPlatformToolset 提出建议。该属性值未记录在案,因此我们希望对其进行彻底测试。

我们将DefaultPlatformToolset 连接到我们的AppVeyor 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.

关于错误信息的建议...或者右键单击解决方案,然后选择“Retarget solution”,我们不能。这是远程的,仅限命令行。我们正在尝试弄清楚如何从How to run VCUpgrade before Appveyor build?的命令行运行VCUpgrade

【问题讨论】:

    标签: visual-studio msbuild appveyor


    【解决方案1】:

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

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

    例如对于 VS2017 最终会依次导入 &lt;msbuild installation&gt;\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 导入之后 else该属性可能尚未定义。为了防止您正在构建的平台由于某种原因没有定义 DefaultPlatformToolset(自定义的,或者可能是旧的 VS 版本),首先将其设置为合理的默认值,before 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>
    

    【讨论】:

    • 不知道,我不确定这与主动拒绝有什么关系,也许只是缺乏时间/兴趣来记录内部情况
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-08
    • 2012-01-22
    • 2017-01-06
    • 2013-03-01
    • 2011-01-18
    • 2013-02-14
    相关资源
    最近更新 更多