Can you defer property evalation?

I have a catch-22. I have a property called "OutputPath" defined in my targets file. I also have an empty property called VcOtherFlags defined in a target in my targets path that allows folks to add in addtional compiler flags. Now here is the problem. If I do this:

<PropertyGroup>
<VcOtherFlags>-I$(OutputPath)</VcOtherFlags>
</PropertyGroup>
<Import Project="..\foo.targets"/>

Then in the target buried in foo.targets, VcOtherFlags evaluates to "-I" because the OutputPath is defined in foo.targets. If I switch the order like so:

<Import Project="..\foo.targets"/>
<PropertyGroup>
<VcOtherFlags>-I$(OutputPath)</VcOtherFlags>
</PropertyGroup>

Then VcOtherFlags is defined correctly in my current project but it doesn't propagate to the foo.targets file because the property is defined after the import. So what do I do? I would like a way to use the first scenario but indicate to MSBuild to defer the evaluation of the "$(VcOtherFlags)" property until it actually is used. By that time, $(OutputPath) will be defined. If MSBuild doesn't have this ability then let me put my vote in now - allow for deferred (or lazy) property evaluation.

[1238 byte] By [KeithHill] at [2008-2-4]
# 1

Yes, property references in other properties are evaluated before everything else, but property references in task inputs etc. are only evaluated after we finish evaluating all properties. This means that if you don't have to consume VcOtherFlags in another property but can pass it directly into a task, you can do something like this:

leaf.proj:
<Project xmlns="
http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="include.proj"/>
<PropertyGroup>
<CustomProperty>custom $(ConsumedProperty)</CustomProperty>
</PropertyGroup>
</Project>

include.proj:
<Project xmlns="
http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<TargetsProperty>targets</TargetsProperty>
<ConsumedProperty>consumed</ConsumedProperty>
<CustomProperty/>
</PropertyGroup>
<Target Name="x">
<Message Text="$(TargetsProperty) $(CustomProperty)"/>
</Target>
</Project>

Building leaf.proj will produce the following output:

Target x:
targets custom consumed

Alternatively, you could also use the CreateProperty task, which, being a task, will defer evaluating its arguments till after evaluating all regular properties.

Hope this helps,
Lukasz

LukaszGwozdz at 2007-9-8 > top of Msdn Tech,Visual Studio,Visual Studio MSBuild...
# 2
I moved the evaluation of the property into the task and that worked. Thanks. Sometime I'll have to play with the CreateProperty task and see how that works.
KeithHill at 2007-9-8 > top of Msdn Tech,Visual Studio,Visual Studio MSBuild...

Visual Studio

Site Classified