Передача значения группы свойств из одной задачи MsBuild в другую

Как сохранить значения, определенные в одной цели сборки, в другом таргетинге? Если PropertyGroup не является объектом записи MsBuild, я должен использовать здесь, что это такое? ReleaseDir печатается нормально в целевом "Пакет", но пуст в "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>

Ответ 1

Существует известная проблема со свойствами и задачей 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>

Ответ 2

Если кто-то хочет передать свойство цели, задача MSBuild может быть полезна. Это единственный способ вызывать цель несколько раз с разными значениями свойств, но не позволяет передавать элементы или группы элементов. См. Этот комментарий в потоке, к которому относится Жюльен.

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

Этот метод полезен, если вы хотите использовать цель как подпрограмму, которую вы можете вызывать несколько раз с разными значениями параметров. Например, для вызова процесса сборки для нескольких конфигураций продукта.

Ответ 3

Это может быть не самый чистый способ решить эту проблему, но если кто-то еще хочет использовать CallTarget в файле сборки, он должен определить PropertyGroup в другом Target, следующее: решение этой странной проблемы.

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