Skip to content

Commit 1ea49e8

Browse files
author
mikeblome
committed
additional edits on new file
1 parent 4c8eccd commit 1ea49e8

File tree

1 file changed

+28
-17
lines changed

1 file changed

+28
-17
lines changed

docs/ide/vcxproj-file-structure.md

Lines changed: 28 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,22 @@
1+
# .vcxproj and .props file structure
2+
MSBuild is the default project system in Visual Studio; when you choose **File | New Project** in Visual C++ you are creating an MSBuild project whose settings are stored in an XML project file that has the extension `.vcxproj`. The project file may also import .props files and .targets files where settings can be stored. In most cases, you never need to manually edit the project file, and in fact you should not edit it manually unless you have a good understanding of MSBuild. Whenever possible you should use the Visual Studio property pages to modify project settings. However, in some cases you may need to modify a project file manually or programmatically. For those scenarios, this article contains basic information about the structure of the file.
3+
4+
## .vcxproj file elements
15
You can inspect the contents of a .vcxproj file by using any text or XML editor. You can view it in Visual Studio by right-clicking on the project in Solution Explorer, choosing **Unload project** and then choosing **Edit Foo.vcxproj**.
2-
When you inspect a .vcxproj file, you see that the various top-level MSBuild elements are laid out in a particular order. For example:
6+
7+
The first thing to notice is that the top-level elements appear in a particular order. For example:
38
- most of the property groups and item definition groups occur after the import for Microsoft.Cpp.Default.props.
49
- all targets are imported at the end of the file.
510
- there are multiple property groups, each with a unique label, and they occur in a particular order.
611

7-
The order of elements in the project file is very important, because MSBuild is based on a sequential evaluation model. If your project file, including all the imported .props and .targets files, consists of multiple definitions of a property, the last definition overrides the preceding ones. In the following example, the value “xyz” will be used during build time.
12+
The order of elements in the project file is very important, because MSBuild is based on a sequential evaluation model. If your project file, including all the imported .props and .targets files, consists of multiple definitions of a property, the last definition overrides the preceding ones. In the following example, the value “xyz” will be set during compilation because the MSBUild engine encounters it last during its evaluation.
813

914
```xaml
1015
<MyProperty>abc</MyProperty>
1116
<MyProperty>xyz</MyProperty>
1217
```
1318

14-
The following minimal .vcxproj file demonstrates the layout succinctly. Any .vcxproj file generated by VS will contain these top-level MSBuild elements and they will appear in this order (although they may contain multiple copies of each such top-level element). Note that Label attributes are arbitrary tags that are only used by Visual Studio and as signposts for editing; they have no other function.
19+
The following snippet shows a minimal .vcxproj file. Any .vcxproj file generated by VS will contain these top-level MSBuild elements and they will appear in this order (although they may contain multiple copies of each such top-level element). Note that Label attributes are arbitrary tags that are only used by Visual Studio as signposts for editing; they have no other function.
1520

1621
```xaml
1722
<Project DefaultTargets=“Build“ ToolsVersion=“4.0“ xmlns=‘http://schemas.microsoft.com/developer/msbuild/2003‘>
@@ -41,55 +46,55 @@ The following minimal .vcxproj file demonstrates the layout succinctly. Any .vcx
4146
```xaml
4247
<ItemGroup Label=“ProjectConfigurations“ />
4348
```
44-
This contains the project configurations known to the project (such as Debug|Win32 and Release|Win32).
49+
This contains the project configurations which specify a debug or release build and the platform. Examples are Debug|Win32, Release|Win32, Debug|ARM and so on. Many project settings are specific to a given configuration. For example, you will probably want to set optimization properties for a release build but not a debug build.
4550

4651
```xaml
4752
<PropertyGroup Label=“Globals“ />
4853
```
49-
This contains project level settings such as ProjectGuid, RootNamespace, etc. These properties are not typically overridden elsewhere in the project file. This group is not configuration-dependent and therefore typically only one Globals group exists in the project file.
54+
This contains project level settings such as ProjectGuid, RootNamespace, etc. These properties are typically not overridden elsewhere in the project file. This group is not configuration-dependent and therefore typically only one Globals group exists in the project file.
5055

5156
```xaml
5257
<Import Project=“$(VCTargetsPath)\Microsoft.Cpp.default.props“ />
5358
```
5459

55-
This property sheet contains the default settings for a Visual C++ project. It contains definitions of all the project settings such as Platform, PlatformToolset, OutputPath, TargetName, UseOfAtl, etc. It also contains all the item definition group defaults for each known item group. In general, properties in this file are not tool-specific.
60+
This property sheet comes with Visual Studio and cannot be modified. It contains the default settings for a Visual C++ project. It contains definitions of all the project settings such as Platform, PlatformToolset, OutputPath, TargetName, UseOfAtl, etc. It also contains all the item definition group defaults for each known item group. In general, properties in this file are not tool-specific.
5661

5762
```xaml
5863
<PropertyGroup Label=“Configuration“ />
5964
```
6065
This property group has an attached configuration condition (such as `Condition=”‘$(Configuration)|$(Platform)’==’Debug|Win32′”`)
61-
and comes in multiple copies, one per configuration. This property group hosts configuration-wide properties. These properties control the inclusion of system property sheets in Microsoft.Cpp.props. For example, if we define the property `<CharacterSet>Unicode</CharacterSet>`, then the system property sheet microsoft.Cpp.unicodesupport.props will be included (as can be seen in the Property Manager). IF you inspect Microsoft.Cpp.props, you will see the line:
66+
and comes in multiple copies, one per configuration. This property group hosts the properties that are set for a specific configuration. These properties control the inclusion of system property sheets in Microsoft.Cpp.props. For example, if we define the property `<CharacterSet>Unicode</CharacterSet>`, then the system property sheet microsoft.Cpp.unicodesupport.props will be included. If you inspect Microsoft.Cpp.props, you will see the line:
6267
`<Import Condition=”‘$(CharacterSet)’ == ‘Unicode'” Project=”$(VCTargetsPath)\microsoft.Cpp.unicodesupport.props”/>`.
6368

6469
```xaml
6570
<Import Project=“$(VCTargetsPath)\Microsoft.Cpp.props“ />
6671
```
67-
This property sheet (directly or via imports) defines the default values for many tool-specific properties such as the compiler’s Optimization, WarningLevel properties, the MIDL tool’s TypeLibraryName property, and so on. It also imports various system property sheets based on which configuration properties are defined in the property group immediately above.
72+
This property sheet (directly or via imports) defines the default values for many tool-specific properties such as the compiler’s Optimization and Warning Level properties, the MIDL tool’s TypeLibraryName property, and so on. It also imports various system property sheets based on which configuration properties are defined in the property group immediately above.
6873

6974
```xaml
7075
<ImportGroup Label=“ExtensionSettings“ />
7176
```
72-
This group contains imports for the property sheets that are part of Build Customizations. A Build Customization is defined by up to three files: a .targets file, a .props file and and .xml file. This import group contains the imports for the .props file.
77+
This group contains imports for the property sheets that are part of Build Customizations. A Build Customization is defined by up to three files: a .targets file, a .props file and an .xml file. This import group contains the imports for the .props file.
7378

7479
```xaml
7580
<ImportGroup Label=“PropertySheets“ />
7681
```
77-
This group contains the imports for user property sheets. These are the property sheets that you add through the Property Manager view in Visual Studio. The order in which these imports are listed is relevant and is reflected in the Property Manager. The project file normally contains multiple instances of this kind of import group, one for each project configuration.
82+
This group contains the imports for user property sheets. These are the property sheets that you add through the Property Manager view in Visual Studio. The order in which these imports are listed is important and is reflected in the Property Manager. The project file normally contains multiple instances of this kind of import group, one for each project configuration.
7883

7984
```xaml
8085
<PropertyGroup Label=“UserMacros“ />
8186
```
82-
`UserMacros` are as variables that are used to customize your build process. For example, you can define a user macro to define your custom output path as $(CustomOutpuPath) and use it to define other variables. This property group houses such properties. Note that in VS2010, this group is not populated by the IDE since we do not support user macros for configurations (we do for property sheets though).
87+
`UserMacros` are as variables that are used to customize your build process. For example, you can define a user macro to define your custom output path as $(CustomOutputPath) and use it to define other variables. This property group houses such properties. Note that in Visual Studio, this group is not populated in the project file because Visual C++ does not support user macros for configurations. User macros are supported in property sheets.
8388

8489
```xaml
8590
<PropertyGroup />
8691
```
87-
This property group normally comes with a configuration condition attached. You will also see multiple instances of the property group, one per configuration. Unlike the property groups above, this one does not have a label. This group contains project configuration-level settings. These settings apply to all files that are part of the specified item group. Build Customization item definition metadata also gets initialized here.
92+
This property group normally comes with a configuration condition attached. You will also see multiple instances of the property group, one per configuration. Unlike the property groups above, this one does not have a label. This group contains project configuration-level settings. These settings apply to all files that are part of the specified item group. Build Customization item definition metadata is initialized here.
8893

8994
```xaml
9095
<ItemDefinitionGroup />
9196
```
92-
Similar to the property group immediately above, but it contains item definitions and item definition metadata instead of properties.
97+
An item is a file that is processed during the build; it might be a .h or .cpp file, an image, a data file, an IDL file or any other kind of file that you include in the project. The ItemDefinitionGroup contains item definitions and item definition metadata instead of properties.
9398

9499
```xaml
95100
<ItemGroup />
@@ -99,20 +104,26 @@ Contains the items (source files, etc.) in the project. You will generally have
99104
```xaml
100105
<Import Project=“$(VCTargetsPath)\Microsoft.Cpp.targets“ />
101106
```
102-
Defines (directly or via imports) VC++ targets such as build, clean, etc.
107+
Defines (directly or via imports) Visual C++ targets such as build, clean, etc.
103108

104109
```xaml
105110
<ImportGroup Label=“ExtensionTargets“ />
106111
```
107112
This group contains imports for the Build Customization target files.
108113

109-
The above ordering ensures that editing the project file via that IDE gives expected results. For example, when you define a property value in the property pages, the IDE will generally place the property definition in the property group with the empty label. This ensures that default values brought in the system property sheets are overridden by user defined values. Similarly, the target files are imported at the end since they consume the properties defined above and since they generally do not define properties themselves. Likewise, user property sheets are imported after the system property sheets (included via Microsoft.Cpp.props). This ensures that the user can override any defaults brought in by the system property sheets.
114+
## Impact of incorrect ordering
115+
The Visual Studio IDE depends on the project file having the ordering described above. For example, when you define a property value in the property pages, the IDE will generally place the property definition in the property group with the empty label. This ensures that default values brought in the system property sheets are overridden by user defined values. Similarly, the target files are imported at the end since they consume the properties defined above and since they generally do not define properties themselves. Likewise, user property sheets are imported after the system property sheets (included via Microsoft.Cpp.props). This ensures that the user can override any defaults brought in by the system property sheets.
110116

111-
If a .vcxproj file does not follow this layout, the build results may not be like you expected. For example, properties that are defined by the user using property pages may not be used during the build since they could have been overridden by the system property sheets in this different layout.
117+
If a .vcxproj file does not follow this layout, the build results may not be what you expect. For example, if you mistakenly import a system property sheet after the property sheets defined by the user, the user settings will be overridden by the system property sheets.
112118

113-
Even the IDE design time experience may suffer, although VS does its best to work with any .vcxproj file. If your .vcxproj file does not have, say, the PropertySheets import group, then you will not see any user property sheets in the Property Manager view (you might still see the system property sheets though). However, when you add a property sheet from the Property Manager view, then VS will create one such labeled import group for you at the right place in the .vcxproj file and add the import for the new property sheet. If however, your .vcxproj has a layout very different from the one described above, VS may not know what the right place is so it may end up creating it at an arbitrary location. In general, the heuristic used by VS IDE should work well for minor to moderate inconsistencies in the .vcxproj file layout.
119+
Even the IDE design time experience depends to some extent on correct ordering of elements. For example, if your .vcxproj file does not have the PropertySheets import group, the IDE might not be able to determine where to place a new property sheet that the user has created in Property Manager. This could result in a user sheet being overriden by a system sheet. Although the heuristic used by IDE can tolerate minor inconsistencies in the .vcxproj file layout, it is strongly recommended not to deviate from the structure shown earlier in this article.
120+
121+
## How the IDE uses element labels
114122

115123
You may want to know how VS magically knows where to write a particular property. For example, when you set UseOfAtl property in the general property page, it gets written to Configuration property group whereas the TargetName property in the same general property page gets written to the label-less property group. That is told to VS by the property itself. Well actually by the property schema in the property page xml file. Recall that property page xml defines the static information about a Rule and all its properties. One such piece of information is the preferred position of a Rule property in the destination file (the file where its value will be written). The preferred position is defined by taking advantage of the existence of Labels. Labels are used to distinguish the various top-level elements of the same type (such as two property groups). Thus, a property can declare in the property page xml file, which of the property groups it would like to be housed in when the time comes for it to be defined in the project file.
124+
125+
126+
## Property Sheet layout
116127

117128
Finally, here is the skeletal MSBuild file that will illustrate the file layout of a property sheet (.props) file in VS2010. The functionality of the layout elements can be inferred based on the discussion above.
118129

0 commit comments

Comments
 (0)