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?
source to share
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 determineMyCustomProperty
when it is completed. Not now. - You define
ItemGroup
and therefore evaluate the condition. It returnsfalse
because itMyCustomProperty
is not yet defined. - You define the goal
BeforeBuild
. - You are launching an initial target i.e.
CommonSettingsTarget
... Now it is determinedMyCustomProperty
. - You are launching a default target that depends on
BeforeBuild
and thus launchesBeforeBuild
. There you rateMyCustomProperty
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"
.
source to share