MSBuild conditions based on imported properties

I have a solution that has multiple projects and I would like all of them to have access to a set of common properties that have been defined once in a common file at the solution level.

This basically works using the code below and I can use the imported properties in the target BeforeBuild environment, however the problem I am facing is that I cannot use the imported properties in the conditions.

So I have the following in my CommonSettings.targets file in my solution folder:

<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
    <Target Name="CommonSettingsTarget">
        <PropertyGroup>
            <MyCustomProperty>Sample</MyCustomProperty>
        </PropertyGroup>
    </Target>
</Project>

      

In my project file I have:

<Project ToolsVersion="14.0" DefaultTargets="Build" InitialTargets="CommonSettingsTarget" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <Import Project="$(SolutionDir)CommonSettings.targets" />

  <ItemGroup>
    <EmbeddedResource Include="EmbeddedDocument.txt" Condition=" '$(MyCustomProperty)' == 'Sample' " />
  </ItemGroup>

  <Target Name="BeforeBuild">
    <Message Text="MyCustomProperty='$(MyCustomProperty)'" Importance="high" />
  </Target>
</Project>

      

In the example above, I can see that my imported property appears in the output window as "MyCustomProperty =" Sample "", which is great, however, when used as part of a condition (optionally including an embedded resource), the condition is never met.

Is there a way to make imported properties work with conditions?

+3


source to share


1 answer


Since yours is ItemGroup

not part of the target, but PropertyGroup

is, CommonSettingsTarget

has not yet been met, when your condition is being evaluated and thus MyCustomProperty

not yet defined.

A task Message

is called from a target BeforeBuild

that depends on CommonSettingsTarget

and was thus MyCustomProperty

defined when the message was created.


Think of it Import

as copying an imported project to a project file. The result will be something like this:

<Project ToolsVersion="14.0" DefaultTargets="Build" InitialTargets="CommonSettingsTarget" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
   <Target Name="CommonSettingsTarget">
     <PropertyGroup>
       <MyCustomProperty>Sample</MyCustomProperty>
     </PropertyGroup>
   </Target>

  <ItemGroup>
    <EmbeddedResource Include="EmbeddedDocument.txt" Condition=" '$(MyCustomProperty)' == 'Sample' " />
  </ItemGroup>

  <Target Name="BeforeBuild">
    <Message Text="MyCustomProperty='$(MyCustomProperty)'" Importance="high" />
  </Target>
</Project>

      

Here's what's going on:



  • You define a goal CommonSettingsTarget

    that will determine MyCustomProperty

    when it is completed. Not now.
  • You define ItemGroup

    and therefore evaluate the condition. It returns false

    because it MyCustomProperty

    is not yet defined.
  • You define the goal BeforeBuild

    .
  • You are launching an initial target i.e. CommonSettingsTarget

    ... Now it is determined MyCustomProperty

    .
  • You are launching a default target that depends on BeforeBuild

    and thus launches BeforeBuild

    . There you rate MyCustomProperty

    that was determined in step 4.

As a solution, remove the target CommonSettingsTarget

and define it PropertyGroup

as a child Project

in CommonSettings.targets instead of:

<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
    <PropertyGroup>
        <MyCustomProperty>Sample</MyCustomProperty>
    </PropertyGroup>
</Project>

      

In the project file, you need to remove InitialTargets="CommonSettingsTarget"

.

+3


source







All Articles