Visual Studio Custom Properties Guide

If you are a Visual Studio C/C++ veteran and want to push the IDE to it’s limits you might find configurable custom build properties useful. By the term “custom build properties” I understand MSBUILD variables that can be configured through the IDE as well as external files to build your project in a predetermined way. This guide is compatible with source control software like Git and SVN.

Quick demonstration is available by an example project.

Arguments for Custom Build Properties

  • disabling or enabling code/modules on demand
  • flexible adjustment of properties through the Visual Studio IDE
  • unit-testing all possible build configurations with simple steps
  • once set-up, future-proof and easy to extend

Prerequisites

  • Visual Studio 2017 or higher
  • basic understand of XML files
  • prepared XML file with IDE custom properties schema (ProjectSchemaDefinitions) named customprops.xml (example #1, example #2, example #3, example #4)
  • .vcxproj project file that we want to add custom build properties support for, preferably in our normal repository layout
  • (optional) special “_repoconfig” directory beside the project folder (in parent directory) for special build configurations

References

Step 1: customprops.xml

Put the customprops.xml file in the same folder like your .vcxproj file. Here is a skeleton file:

<?xml version="1.0" encoding="utf-8"?>
<ProjectSchemaDefinitions  xmlns="http://schemas.microsoft.com/build/2009/properties"
                           xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                           xmlns:sys="clr-namespace:System;assembly=mscorlib">

    <!-- https://docs.microsoft.com/en-us/dotnet/api/microsoft.build.framework.xamltypes.projectschemadefinitions?view=msbuild-16 !-->

    <!-- Adjust Name and DisplayName to your liking !-->
    <Rule Name="customtool_config" PageTemplate="generic" DisplayName="Custom Configuration">
        <Rule.Categories>
            <!-- Put your own categories here !-->
        </Rule.Categories>
        <Rule.DataSource>
            <DataSource Persistence="UserFile" ItemType="" />
        </Rule.DataSource>
        <!-- Put your own properties here. !-->
    </Rule>

</ProjectSchemaDefinitions>

Step 2: defaults.props

Create a defaults.props XML file with default custom build properties in the same folder. Here is a skeleton file:

<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <PropertyGroup>

  </PropertyGroup>
</Project>

Step 3

Open up your Visual Studio project and put both new files into your project file hierarchy. This enables easy editing inside of the IDE. If you do use the recommended repository template then manual editing of the .vcxproj file is recommended.

Step 4

Open up your .vcxproj file inside of your favourite text editor (like SciTE) that is not Visual Studio.

Step 5: DisableFastUpToDateCheck

DisableFastUpToDateCheck

Scroll down inside that file until your reach the PropertyGroup node with Label=”UserMacros”. Create a new PropertyGroup node underneath with a DisableFastUpToDateCheck sub-node set to true, like this:

<PropertyGroup>
    <DisableFastUpToDateCheck>true</DisableFastUpToDateCheck>
</PropertyGroup>

Step 6: adding defaults.props

defaults.props Location

Inside of the ImportGroup node with Label=”PropertySheets” put an Import node of the Project=”defaults.props”, like this:

<ImportGroup Label="PropertySheets">
    <Import Project="defaults.props" />
</ImportGroup>

NOTE: if the labelled ImportGroup does not exist then just create an empty ImportGroup and put the configuration into it.

Step 7: adding customprops.xml

ItemGroup Location

Just below the ImportGroup node create a new ItemGroup node with a child node called “PropertyPageSchema” and give it a Include=”customprops.xml” attribute, like this:

<ItemGroup>
    <PropertyPageSchema Include="customprops.xml" />
</ItemGroup>

Step 8

Think about custom properties that you want to include into your project. Those can be enums, strings or booleans. Edit your customprops.xml to fit your vision. See the referenced documentation and above examples for details.

Step 9: adding _repoconfig

Inside the .vcxproj file scroll past the IDE-managed build configurations and the source file inclusions until you read a node that looks like this:

MSFT C++ Targets Location

Above that Import node put a new ImportGroup node with the following content:

<ImportGroup>
    <Import Project="..\..\..\_repoconfig\$(ProjectName).props" Condition="Exists('..\..\..\_repoconfig\$(ProjectName).props')" />
</ImportGroup>

This will enable custom repository build configurations in the “_repoconfig” folder we mentioned earlier. It assumes that your project repository does follow our recommended repository layout (else adjust the paths accordingly or skip this step altogether).

Step 10: writing the build configuration

Scroll to the bottom of your .vcxproj file past the ImportGroup with Label=”ExtensionTargets”. Below that node the IDE has loaded all MSBUILD properties that we configured. As a result we can put (conditional) build configurations here! Append your own ItemDefinitionGroup and PropertyGroup nodes, maybe even with a specialized Condition attribute. Inside of the conditions use the properties that we configured, using the $(PropertyName) template.

You can take a look at the example to get some leads.

Step 11: editing defaults.props

Edit your defaults.props file to give default build configurations to your project. Simply list the nodes with their values inside the given PropertyGroup node of the skeleton.

Step 12

Save and close the .vcxproj and defaults.props files. Then open your Visual Studio project through the IDE.

Step 13: try and test

If you did configure the files properly, then the project does successfully load. Right click on your configured project and open it’s properties.

VS Project Properties

Troubleshooting

Problem: My VS project has loaded in the IDE but the property page in Step 13 is not listed

Solution: Open up the customprops.xml file in the IDE and check for errors. They should be highlighted in red.


Problem: When I try to open the .vcxproj file then the IDE does just error out.

Solution: Open up your .vcxproj file inside your text editor. Then debug the issue with the messages output by the IDE. When you saved the changes to your .vcxproj file simply close Visual Studio and reopen your project. Repeat this approach until all errors have been fixed.

Example project

For motivational purposes here you can download a preconfigured example project:

example.zip

It does contain the following features:

  • boolean property “ENABLE_OPTIMIZATIONS” to enable or disable a quicker code path
  • string property “TOOL_NAME” to adjust the console output
  • enum property “GREETING_TYPE” to choose the type of message for console output

Adding files to source control

The following files should be uploaded to any remote codebase:

  • defaults.props
  • customprops.xml

The IDE will generate a ProjectName.vcxproj.user file once you change the configurations inside of your IDE property pages. Please make sure that you add this .user file to ignored files. This will prevent clutter as well as confusion.