12

如何使一个构建目标中定义的值在另一个目标中保持有效?如果 PropertyGroup 不是我应该在这里使用的写入 MsBuild 实体,那是什么?ReleaseDir 在“Package”目标中打印正常,但在“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>
4

3 回答 3

22

属性和 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>
于 2009-09-03T12:44:20.337 回答
1

如果想将属性传递给目标,MSBuild 任务会很有用。这是使用不同属性值多次调用目标的唯一方法,但它不允许传入项目或项目组。请参阅Julien 链接到的线程中的此 评论。

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

如果您想将目标用作子例程,则此技术很有用,您可以使用不同的参数值多次调用它。例如,为多个产品配置调用构建过程。

于 2015-04-27T03:51:53.123 回答
1

这可能不是解决这个问题的最干净的方法,但是如果有人仍然想在构建文件上使用CallTarget,他/她必须在另一个 Target 中定义 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>
于 2015-10-16T13:09:15.500 回答