Inherited Properties and Property Sheets

In my last post, I talked at length about the various types of MSBuild elements – items, properties, imports, etc. One of the things that I said I would get around to in a later post was to explain what I meant by “inherited properties”, where they came from and how you can create your own. Well, I’m slow but I’m finally getting around to it!

What you are going to learn is how to take advantage of one of the most powerful – but lesser known – features of VC++ Projects: Property Sheets. And if that isn’t enough for you – you’ll also learn the foundations needed to understand my next post…What happened to VC Directories?!?!!?

The above image is straight out of a new Win32 Console application project property window. Notice how some of the property values (Debug Information Format and Warning Level) are bolded while others are not? What this means is that the values that are bold in value are defined in the .vcxproj (or associated .user file), while the other values are inherited from another file. How does that work? As I said in my previous post, an MSBuild file can import other files – just like a #include for a header file. In this case, if you open your .vcxproj file, you’ll see an import for Microsoft.Cpp.default.props and Microsoft.Cpp.props. Pretty much all of your inherited property values in a new VC++ project comes from these files – or their imports.

What this allows Microsoft to do is define the defaults in a set of files that all projects import – and therefore not have to replicate them in everyone’s project file. The trick is, you can do the exact same thing – it’s called Property Sheets.

A property sheet is simply an MSBuild file that you import into your project that defines some property values. But because it is a separate file, it can be shared among multiple projects, allowing you to centralize some settings and perform a central edit operation. Examples of where this is useful are

  • Setting build conventions for teams, such as warning levels, use of exceptions and optimization settings.
  • Setting system information, such as the include and library paths for an SDK you might consume.
  • Feature settings, such as the various properties to set when using Unicode or Ansi strings.

The system is open, so you can use it for pretty much whatever takes your fancy.

Of course, to make it really useful, we need to allow you to work with them inside the IDE. To see property sheets in action, bring up the Property Manager window. This may already be in your windows next to the solution explorer – or you can bring it up from the View->(Other Windows)->Property Manager (whether it is in Other Windows or not depends on what profile you selected when you first started Visual Studio).

What you’ll notice is that it is somewhat like the solution explorer – it lists out all of the VC++ projects in the solution. However, rather than source files, it shows property sheet “sources”, grouped by their configurations. In this case, you can see that there are four existing property sheets by default for a new Win32 console application project. For each of them, you can right-click and bring up the property window just as you did for the project earlier. Now, however, it shows the settings that are known about by the property sheet you have selected (Microsoft.Cpp.Win32.user is shown below).

Some things to notice about this window

  1. The Configuration and Platform selections are grayed out.
    This is because you select them automatically when you click on the property sheet in the Property Manager window. (Yes, I know this is inconsistent and a bit strange, but it’s the way it’s been since property sheets arrived – so until we do a larger UI overhaul, consider it a lovely quirk).
  2. Some properties are still not bolded.
    Editing a property sheet is like editing a project – it can have it’s own property sheets that are providing defaults.
  3. There are a lot more rules (left column of C/C++, Linker, etc).
    This is because in a project view, we only show rules that apply to the project as it is…if you have no .rc files, then we don’t show the Resources rule. Property Sheets, however, can be applied to multiple projects and therefore we don’t filter out any known rule.

Now, you may notice that if you selected one of the property sheets that has an icon that looks like a computer with a sheet in front of it, that everything was read-only. That is because these are System Property Sheets. Simply, a system property sheet is one that is provided by the build system automatically (part of the Microsoft.cpp.props for example) and therefore is not meant to be edited. That doesn’t mean you can’t override their values in a property sheet or project file – only that you can’t edit the system property sheet itself. It is displayed only so that you can see what those sheets contribute.

Okay, so let’s create our own property sheet to get the feel for it. First thing to do is to select a context in the property manager window – if you pick a project, the property sheet is applied to all config/platform settings. If you pick a specific config/platform, then obviously it would only apply for that one. Anyway – go ahead and right-click and select “Add New Project Property Sheet'” and follow the wizard. The only real thing to note here is that you have to say where the file should be located. Remember, the value of a property sheet is that it can be shared between multiple projects so a common directory near the top of your solution source is probably a good idea.

You should now have 5 property sheets – 3 system property sheets and two user property sheets. You might be wondering whether or not the order of them in the list has any importance (if not, go ahead and do it now, we’ll wait….Hey, did you know it rains a lot in Seattle? How about those Seahawks, eh?).

Ah, your back! Great – I can now cease your wondering by me saying that yes, indeed, the order matters. What the order is telling you is that the property sheet at the bottom is applied first, then the next and the next, so on up the list. This means that your newest property sheet will be applied last – just before the project itself is evaluated. If you want to change that ordering, just right-click on the property sheet and select either “Move Earlier in Evaluation” or “Move Later in Evaluation”.

An important note: Notice how “Move Earlier in Evaluation” is grayed out above? That is because not only are system property sheets read-only, they also are read-only when it comes to ordering.

Now here is another trick – try right clicking on a property sheet and selecting “Add New Project Property Sheet” (as also visible above). The result is a child property sheet. Again, you have control over the evaluation ordering, just remember that move earlier/later on children obviously only affect the group of children sheets. Similar to the main list, children are evaluated from the bottom up – and all the children of a parent are evaluated just before the parent itself is evaluated.

Just two more things to say about property sheets at this point.

  1. Notice how the right-click context menu above has a “Save” option? Yes – I’m afraid that property sheets are not owned by a project and therefore saving a project does not save property sheets – so they have their own save command. All I can say is (a) it was that way in VS 2008 and that (b) addressing some of the UI hiccups is high on my own priority list for the next release…back me up on this one!
  2. Microsoft.Cpp.Win32.user is a special – but optional – property sheet. This guy lives in your LocalAppData directory and is automatically part of any new or upgraded project. Therefore anything set in this property sheet, by default, applies to ALL projects. We’ll get more into him in a following post on “What the heck happened to the Tools->Options VC Directories?”

To complete the circle, set a property value in your new property sheet and then go back to the project properties window and you should see your value showing up – and not-bolded – proving the inheritance.

So there you have it, Property Sheets in a nut-shell. I’ll be honest with you – these aren’t the easiest things to understand when you first come across them – make sure to play around with them a bit to get a feel and post up any questions you have. Once you get the hang of them, you’ll wonder how you ever did anything without them.

Up next (from me anyway) – The prodigal VC Directories returns.