2009-09-03 59 views
11

如何让一个构建目标中定义的值保持在其他targert中?如果PropertyGroup不是我在此使用的写入MsBuild实体,那么是什么? RELEASEDIR被印在“包”目标确定,但在“DoPackage”空将属性组的值从一个MsBuild任务传递到另一个

<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> 

回答

21

有一个well known issue与性能和CallTarget任务。您应该使用DependsOnTargets。

<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 actual packaging --> 
<Target Name="DoPackage" DependsOnTargets="Package"> 
    <Message Text="Creating package in '$(ReleasesDir)'"/> 
    <Error Condition="'$(ReleasesDir)' == ''" Text="No ReleaseDir defined"/> 
    <MakeDir Directories="$(ReleasesDir)"/> 
</Target> 
+0

我想只有在ReleaseDir存在的情况下才运行DoPackage(我在CallTarget中使用Condition来实现此目的)。我可以使用DependsOnTarget来实现吗? – ripper234 2009-09-03 15:02:31

+0

现在我已经阅读了您发布的链接,解决方案很简单 - 我编写了一个名为“DefineProperties”的单独任务,完成后属性被...定义。谢谢。 – ripper234 2009-09-03 15:15:20

+0

是的,这是解决方案,我已经更新了示例。 – 2009-09-03 15:19:56

1

如果想传递一个属性设置为一个目标时,MSBuild任务可能是有用的。这是使用不同属性值多次调用目标的唯一方法,但不允许传递项目或项目组。在Julien链接的主题中查看comment

... [C]所有的MSBuild目标在它上面,这次传入所需的属性。这会绕过增量构建...,但有很多限制,即无法传递项目,并且必须指定需要传递哪些属性。

这里是您的代码段会是什么样使用MSBuild任务:

<Target Name="Package"> 
    <PropertyGroup> 
    <ReleasesDir>c:\tmp</ReleasesDir> 
    </PropertyGroup> 
    <Message Text="$(ReleaseDir)"/> 
    <MSBuild Projects="$(MSBuildProjectFile)" Targets="DoPackage" Properties="ReleaseDir=$(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> 

,如果你想使用的目标作为一个子程序,您可以用不同的呼叫多次,这种技术是非常有用的参数值。例如,为多个产品配置调用构建过程。

1

它可能不是解决这个问题的最干净的方式,但如果有一个人希望继续使用CallTarget在构建文件,他/她必须在另一目标定义的PropertyGroup,以下是解决这一奇怪的问题。

<Target Name="DebugBuild" DependsOnTargets="DebugBuildProp"> 
    <CallTarget Targets="CompileSolution"/> 
</Target> 
<Target Name="DebugBuildProp"> 
    <PropertyGroup> 
    <Configuration>Debug</Configuration> 
    </PropertyGroup> 
</Target> 
<Target Name="CompileSolution"> 
    <Message Text="$(Configuration)" /> 
</Target> 
+0

如果' CompileSolution'仍然不会使用新的值。 – makhdumi 2015-10-29 23:53:54

+0

@ Al-Muhandis实际上,我不知道为什么,但是如果你在依赖目标上定义属性,那么你使用CallTarget调用的所有其他目标都将具有该值。亲自尝试一下 – 2015-10-30 06:00:59

相关问题