.vcxproj
files and wildcards
The Visual Studio IDE doesn't support certain constructs in project items in .vcxproj
files. These unsupported constructs include wildcards, semi-colon delimited lists, or MSBuild macros that expand to multiple files. The .vcxproj
project system for C++ builds is more restrictive than MSBuild. Each project item is required to have its own MSBuild item. For more information on the .vcxproj
file format, see .vcxproj
and .props
file structure.
These construct examples aren't supported by the IDE:
<ItemGroup>
<None Include="*.txt">
<ClCompile Include="a.cpp;b.cpp"/>
<ClCompile Include="@(SomeItems)" />
</ItemGroup>
If a .vcxproj
project file that includes these constructs gets loaded in the IDE, the project may seem to work at first. However, issues are likely as soon as the project is modified by Visual Studio and then saved on disk. You may experience random crashes and undefined behavior.
In Visual Studio 2019 version 16.7, when Visual Studio loads a .vcxproj
project file, it automatically detects unsupported entries in project items. You'll see warnings in the Output window during solution load.
Visual Studio 2019 version 16.7 also adds read-only project support. Read-only support allows the IDE to use manually authored projects that don't have the additional limitations of IDE-editable projects.
If you have a .vcxproj
file that uses one or more of the unsupported constructs, you can make it load without warnings in the IDE by using one of these options:
- List all items explicitly
- Mark your project as read-only
- Move wildcard items to a target body
List all items explicitly
Currently, there's no way to make wildcard expansion items visible in the Solution Explorer window in a non-read-only project. Solution Explorer expects projects to list all items explicitly.
To make .vcxproj
projects automatically expand wildcards in Visual Studio 2019 version 16.7 or later, set the ReplaceWildcardsInProjectItems
property to true
. We recommend you create a Directory.Build.props
file in a root directory, and use this content:
<Project>
<PropertyGroup>
<ReplaceWildcardsInProjectItems>true</ReplaceWildcardsInProjectItems>
</PropertyGroup>
</Project>
Mark your project as read-only
In Visual Studio 2019 version 16.7 and later, you can mark projects as read-only. To mark your project read-only, add the following property to your .vcxproj
file, or to any of the files it imports:
<PropertyGroup>
<ReadOnlyProject>true</ReadOnlyProject>
</PropertyGroup>
The <ReadOnlyProject>
setting prevents Visual Studio from editing and saving the project, so you can use any MSBuild constructs in it, including wildcards.
It's important to know that the project cache isn't available if Visual Studio detects wildcards in project items in the .vcxproj
file or any of its imports. Solution load times in the IDE are much longer if you have lots of projects that use wildcards.
Move wildcard items to a target body
You may want to use wildcards to gather resources, add generated sources, and so on. If you don't need them listed in the Solution Explorer window, you can use this procedure instead:
Change the name of the item group to add wildcards. For instance, instead of:
<Image Include="*.bmp" /> <ClCompile Include="*.cpp" />
change it to:
<_WildCardImage Include="*.bmp" /> <_WildCardClCompile Include="*.cpp" />
Add this content to your
.vcxproj
file. Or, add it to aDirectory.Build.targets
file in a root directory, to affect all projects under that root:<Target Name="AddWildCardItems" AfterTargets="BuildGenerateSources"> <ItemGroup> <Image Include="@(_WildCardImage)" /> <ClCompile Include="@(_WildCardClCompile)" /> </ItemGroup> </Target>
This change makes the build see the items as they're defined in the
.vcxproj
file. However, now they aren't visible in the Solution Explorer window, and they won't cause problems in the IDE.To show correct IntelliSense for
_WildCardClCompile
items when you open those files in the editor, add the following content:<PropertyGroup> <ComputeCompileInputsTargets> AddWildCardItems $(ComputeCompileInputsTargets) </ComputeCompileInputsTargets> </PropertyGroup>
Effectively, you can use wildcards for any items inside a target body. You can also use wildcards in an ItemGroup
that isn't defined as a project item by a ProjectSchemaDefinition
.
Note
If you move wildcard includes from a .vcxproj
file to an imported file, they won't be visible in the Solution Explorer window. This change also allows your project to load in the IDE without modification. However, we don't recommend this approach, because it disables the project cache.
See also
Set C++ compiler and build properties in Visual Studio
Property Page XML Files