views:

1380

answers:

3

I can't seem to find any useful documentation from Microsoft about how one would use the Delimiter and InheritsFromParent attributes in the UserMacro element when defining user Macros in .vsprops property sheet files for Visual Studio.

Here's sample usage:

<UserMacro Name="INCLUDEPATH" Value="$(VCROOT)\Inc"
    InheritsFromParent="TRUE" Delimiter=";"/>

From the above example, I'm guessing that "inherit" really means "a) if definition is non-empty then append delimiter, and b) append new definition" where as the non-inherit behavior would be to simply replace any current macro definition. Does anyone know for sure? Even better, does anyone have any suggested source of alternative documentation for Visual Studio .vsprops files and macros?

NOTE: this is not the same as the InheritedPropertySheets attribute of the VisualStudioPropertySheet element, for example:

<VisualStudioPropertySheet ... InheritedPropertySheets=".\my.vsprops">

In this case "inherit" basically means "include".

A: 

There's documentation on the UI version of this here. A lot of the XML files seem somewhat undocumented, often just giving a schema file. Your guess as to how they function is pretty much right.

Eclipse
A: 

In this specific instance it means that if you had a UserMacro setting on a parent of the current object, say your Project has one UserMacro setting and File X had a second setting, that the child object would by default inherit the setting of the parent. You can see this functionality in the IDE when you choose a project property value of or . The delimiter merely says how multiple values stored in the UserMacro setting are to be delimited. In your case they are delimited with a semicolon.

From Add User Macro Dialog Box:

Macro inherits from parent property sheets

Enables the custom macro to inherit from parent property sheets.

Delimiter

Specifies the character that represents the delimiter that separates values for your custom macro. This option is only available when Macro inherits from parent property sheets is selected.

sixlettervariables
Thanks for your answer, but I'm not sure I follow. I think you may be describing InheritedPropertySheets or $(Inherit) rather than InheritsFromParent. MS has too many definitions for 'inherit', huh?
jwfearn
I'm fairly certain that InheritsFromParent implies what I meant. Added a link to show this.
sixlettervariables
Thanks for the edits, I understand what you mean now.
jwfearn
@jwfearn: does that answer your question? I can't really find anything else on the topic.
sixlettervariables
Not exactly, InheritsFromParent is not necessary to use inherited user macros, rather it defines a prepend behavior within a specific user macro. see my answer. Gotta love MS useless recursive docs: "X means X, Y means Y", huh?
jwfearn
+4  A: 

[Answering my own question]

InheritsFromParent means prepend. To verify this, I did an experiment that reveals how User Macros work in Visual Studio 2008. Here's the setup:

  • Project p.vcproj includes the property sheet file d.vsprops ('d' for derived) using the InheritedPropertySheets tag.
  • d.vsprops includes the property sheet file b.vsprops ('b' for base.)
  • p.vcproj also defines a Pre-Build Event which dumps the environment.
  • Both .vsprops files contain User Macro definitions.

b.vsprops

...
<UserMacro Name="NOENV" Value="B"/>
<UserMacro Name="OVERRIDE" Value="B" PerformEnvironmentSet="true"/>
<UserMacro Name="PREPEND" Value="B" PerformEnvironmentSet="true"/>
...

d.vsprops

...
<VisualStudioPropertySheet ... InheritedPropertySheets=".\b.vsprops">
<UserMacro Name="ENV" Value="$(NOENV)" PerformEnvironmentSet="true"/>
<UserMacro Name="OVERRIDE" Value="D" PerformEnvironmentSet="true"/>
<UserMacro Name="PREPEND" Value="D" InheritsFromParent="true"
    Delimiter="+" PerformEnvironmentSet="true"/>
...

p.vcproj

...
<Configuration ... InheritedPropertySheets=".\d.vsprops">
<Tool Name="VCPreBuildEventTool" CommandLine="set | sort"/>
...

build output

...
ENV=B
OVERRIDE=D
PREPEND=D+B
...

From these results we can conclude the following:

  1. PerformEnvironmentSet="true" is necessary for User Macros to be defined in the environment used for build events. Proof: NOENV not shown in build output.
  2. User Macros are always inherited from included property sheets regardless of PerformEnvironmentSet or InheritsFromParent. Proof: in b.vsprops, NOENV is not set in the environment and in d.vsprops it is used without need of InheritsFromParent.
  3. Simple redefinition of a User Macro overrides any previous definition. Proof: OVERRIDE is set to D although it was earlier defined as B.
  4. Redefinition of a User Macro with InheritsFromParent="true" prepends the new definition to any previous definition, separated by a specified Delimiter. Proof: PREPEND is set to D+B (not D or B+D.)

Here are some additional resources I found for explanation of Visual Studio .vsprops files and related topics, it's from a few years back but it is still helpful:

understanding the VC project system part I: files and tools

understanding the VC project system part II: configurations and the project property pages dialog

understanding the VC project system part III: macros, environment variables and sharing

understanding the VC project system part IV: properties and property inheritance

understanding the VC project system part V: building, tools and dependencies

understanding the VC project system part VI: custom build steps and build events

understanding the VC project system part VII: "makefile" projects and (re-)using environments

jwfearn