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 thor
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" />
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>
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 ...
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.
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>
Here's another way to do it:
<!-- 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>
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>