Thursday, August 27, 2009

A short introduction to VSProps files in Visual Studio

Until recently, from the moment I created a second project in my solution, I started muttering against Visual Studio because I had to change the same information in several places to update the configuration of my projects. Maybe this is over now...

Suppose you have a Visual Studio solution with several projects : two libraries, a DLL build from them, a few EXE projects to test the DLL. Suppose the two libraries and the DLL use a third-party library, and you'd like to be able to change the version of this library easily. Suppose also that you'd like to add pre-compiler definititions to all the projects.

Visual Studio offers a feature to solve this issue, the Visual Studio Property Sheets, or VSProps. These files are more or less equivalent to the configuration/properties part of the Project files. You can assign Property Sheets to Projects, and Property Sheets can inherit from other Property Sheets. Such a tool can greatly ease the management of project configurations in Visual Studio.

With suitable property sheets, each configuration data appears once: changing the version of the library, or which values are defined, does not require you to change them in each project.


Creating a Property Sheet

To create a Property Sheet, choose 'View' -> 'Property Manager'. Right-click on the project into which you want to add the Sheet, choose 'Add new project property sheet...', and specify a name and a path.

The new sheet appears as a sub-node in each of the existing configurations. Right-click one one of those sub-nodes, choose 'Properties', and you are presented with the full dialog that you already know from the properties of a project.

The values you enter here will be used by any project that uses this property sheet (the first such project being the project into which the sheet was created).

Inheriting the values of Property Sheet

If you look at the 'General' tab of the project's properties, you will notice the 'Inherited Project Property Sheets' property now has the name of the Property Sheet you just created. This means that this project uses all the values defined in the property sheet.

A project may use several property sheets, listed in this field. The values in the ones listed on the top override, when applicable, those that come from sheets listed below.

Note that Property Sheets themselves can inherit values from other property sheets. You can thus build hierarchies of sheets to separate concerns (e.g. one sheet to configure the libraries used in the project, and one other to configure the compiler settings).


Example: choosing a library version

Suppose several projects in your solution use a third-party library that's available in two different versions that you wish to support. Build two separate sheets, one for version X and one for version Y of the third-party library. In each sheet, specify the include path to add and the lib to link with. Name them libX.xml and libY.xml. Then you build a single property sheet lib.xml that has no configuration value but inherits either from libX.xml or libY.xml. Let all your projects inherit from lib.xml. The effect is that changing the version of the library only entails changing which sheet lib.xml inherits from. One change, for the whole solution...

3 comments:

  1. I finally implemented property sheets for my project at work... Better late than never.

    It is actually much easier to do it than describe how it must be done. So go ahead and try!

    ReplyDelete
  2. One issue though (at least with MSVC10)...
    It seems that whenever you change a value in a property sheet, all the projects that depend on this sheet will be rebuilt from scratch. This is not the case when you change a property in a project file: the behavior depends on which property was changed...
    As an example, adding a library to link does not trigger a recompilation if done in the project file itself, but does if added in a property sheet... :(

    ReplyDelete
  3. Hey Xavier,

    great work! Thank you for sharing this useful and concise tutorial, it is exactly what I was looking for.

    Best regards,
    Douba

    ReplyDelete