views:

671

answers:

1

How do I keep values defined in one build target alive in other targert? If PropertyGroup is not the write MsBuild entity I should use here, what is? ReleaseDir is printed ok in "Package" target, but is empty in "DoPackage"

<Target Name="Package">
  <PropertyGroup>
    <ReleasesDir>c:\tmp</ReleasesDirBase>
  </PropertyGroup>
  <Message Text="$(ReleaseDir)"/>
  <CallTarget Targets="DoPackage" Condition="!Exists('$(ReleaseDir)')"/>
</Target>

<!-- Do the acutal packaging -->
<Target Name="DoPackage">
  <Message Text="Creating package in '$(ReleaseDir)'"/>
  <Error Condition="'$(ReleaseDir)' == ''" Text="No ReleaseDir defined"/>
  <MakeDir Directories="$(ReleaseDir)"/>
  ...
</Target>
+3  A: 

There is a well known issue with property and calltarget task. You should use DependsOnTargets instead.

<Target Name="Package">
  <PropertyGroup>
    <ReleasesDir>c:\tmp</ReleasesDir>
  </PropertyGroup>
  <Message Text="$(ReleasesDir)"/>
</Target>

<Target Name="PrePackage" DependsOnTargets="Package">
  <CallTarget Targets="DoPackage" Condition="!Exists('$(ReleasesDir)')"/>
</Target>

<!-- Do the acutal packaging -->
<Target Name="DoPackage" DependsOnTargets="Package">
  <Message Text="Creating package in '$(ReleasesDir)'"/>
  <Error Condition="'$(ReleasesDir)' == ''" Text="No ReleaseDir defined"/>
  <MakeDir Directories="$(ReleasesDir)"/>
</Target>
madgnome
I would like DoPackage to run only if ReleaseDir exists (I used the Condition in CallTarget to achieve this). Can I achieve this using DependsOnTarget?
ripper234
Now that I actually read the link you posted, the solution is simple - I wrote a separate task called 'DefineProperties', and after it's finished the properties are ... defined. Thanks.
ripper234
Yep, that's the solution, I've updated the sample.
madgnome
I have a feeling the reason properties are not defined until a task has finished is because of parallel execution. MsBuild doesn't guarantee anything mid-target because this way it can execute the subtargets in parallel.
ripper234