Platform Extensibility - Part 1

Have you ever wanted to write a custom tool (like a custom parser or a compiler) and add it to the VC++ project system? Until now, we had three disparate ways of doing it, viz. Build Events, Custom Build Step and Custom Build Rule. These three methods were introduced in different releases of VS in the past in attempts to provide such customization. As if that were not enough, the tools shipped by Microsoft are integrated into the system in a completely different way - by hard coding them in! In VS 2010, we have come up with a new way of adding tools to the system that is the way every tool will be added, including Microsoft shipped tools.

 

In this blog post, I'll give an overview of some aspects of this new approach of integrating tools into the system. In particular, I'll concentrate on the way the tool properties get exposed in the property page UI.

 

In VS 2010, we have a completely data-driven approach to the property page UI. Nothing is hard-coded or known innately to the system. The properties that are listed by the UI as well as some aspects of how they are rendered are based off of a richly described XML file. Let me explain this in a top-down manner. First, let us open the property pages for a project (right click on the project node in the solution explorer and choose Properties). The UI is shown below.

Property page UI

 

 Each node under Configuration Properties represent a tool or some other artifact. E.g. the C/C++ node represents the compiler tool and properties related to it, the Linker node represents the linker tool. Similarly, the Debugging node houses properties related to the debuggers. We will call each such top level node under Configuration Properties as a Rule. A Rule, in many cases, represents a tool like the compiler, but in some cases (such as debugger/code analysis) does not. We use the term Rule as an abstract term for something that has properties, executes and may produce some output.

 

Going back to the UI, we see that each Rule has a bunch of properties organized into categories. Each sub node under a Rule represents a category. E.g. the Optimization node under C/C++ houses all the optimization related properties of the compiler tool. The properties and their values themselves are rendered in a grid format on the right pane.

 

Where does the system get the list of these properties from? The answer is an information-rich XML file whose location is made available to the project. Use your Windows explorer to go %ProgramFiles%\MSBuild\Microsoft.Cpp\v4.0 (see snapshot below) . There you will find the cl.xml file. Its location is listed in Microsoft.CppBuild.targets  which is imported into the project file indirectly through a long list of target file imports starting with Microsoft.Cpp.targets (found at the end of your .vcxproj file).

Windows explorer in $(VCTargetsPath)

Open the file cl.xml in notepad or any XML editor (see snapshot below). While you may not understand everything in it, you must be able to see in this file the contours of what the UI has displayed under the C/C++ node. You will see a root node called Rule that has the same list of properties defined under it as is displayed in the UI. The rule and every property has metadata describing it further.

First few lines of cl.xml

Go ahead and play with this file. In fact, this XML file is loaded at run-time, so you can even make some modifications and re-start VS and see your changes (be sure to make a backup copy of the XML file if you do plan to do that). E.g. copy an existing property and change its name to Foo or something like that. See if you can find it in the property page UI after restarting VS.

There is one XML file corresponding to every node under Configuration Properties in the property pages UI. You can add (remove) Rules in the UI by including (removing) locations to corresponding XML files in the project (using a special item type of PropertyPageSchema; see how Microsoft.CppBuild.targets includes cl.xml).

Note that the XML file describes only the schema of the properties - their types, display names, some aspects of how they are rendered (such as standard grid vs. a different format) and other such metadata. The actual values themselves are written to and read from the project file or other files that the project imports. The XML file only mentions the file in which the property values must be stored.

It should be clear why this data driven approach equalizes the field for 3rd party tools. The system doesn't care who authors the XML file - it could be Microsoft or someone else - it just gleans information from it and displays it.

In future blog posts, I'll delve deeper into the XML file contents. I'll also describe how you can integrate your tool in the build process (what I described above allows only design time integration).