msbuildmsbuild-propertygroup

MSBuild: how to create a global property?


When running MSBuild, anything passed in on the command line using /p:MyProp=value is accessible from every MSBuild script invoked (via the MSBuild task) from the main script. How can I define a property that is similarly accessible from every script, in a task?

For example:

Script1.proj:
[...]
<Target Name="Test">
  <MSBuild Projects="Script2.proj"/>
  <Message Text="Script1, GlobalProp1=$(GlobalProp1)"/>
  <Message Text="Script1, GlobalProp2=$(GlobalProp2)"/>
</Target>

Script2.proj:
[...]
<Target Name="Test">
  <!-- ??? Set GlobalProp2 = VALUE2 ??? -->
  <Message Text="Script2, GlobalProp1=$(GlobalProp1)"/>
  <Message Text="Script2, GlobalProp2=$(GlobalProp2)"/>
</Target>

If run like this: msbuild Script1.proj /p:GlobalProp1=VALUE1 the above scripts produce the following output:

Script2, GlobalProp1=VALUE1
Script2, GlobalProp2=
Script1, GlobalProp1=VALUE1
Script1, GlobalProp2=

I'd like Script2.proj to set GlobalProp2 somehow to produce the following output:

Script2, GlobalProp1=VALUE1
Script2, GlobalProp2=VALUE2
Script1, GlobalProp1=VALUE1
Script1, GlobalProp2=VALUE2

Is this possible, and if so, how?

I've seen suggestions to use environment variables, but it seems that the only situation in which that helps is when the variable is set in the parent script, and the child script is invoked using the Exec task (otherwise the env.variable change has no effect).


Solution

  • Since you are using the MSBuild task you have to pass the desired properties into the call using the Properties attribute so you should change you example to.

    <Target Name="Test">  
        <MSBuild Projects="Script2.proj" 
            Properties="GlobalProp1=$(GlobalProp1);GlobalProp2=$(GlobalProp2)"
        />  
        <Message Text="Script1, GlobalProp1=$(GlobalProp1)"/>  
        <Message Text="Script1, GlobalProp2=$(GlobalProp2)"/>
    </Target>
    

    The properties must be explicitly passed, this is by design.

    If you want a tighter integration then instead of using the MSBuild task you should just import the file(s) which will create 1 logical script.